|
Post by wyliam on Jan 30, 2015 18:09:59 GMT
Can you control the rarity/randomness of a certain terrain definition (i.e. gold mines/hexes higher rarity).
Am I missing it or can I suggest this feature? Maybe an upper/lower limit for types?
|
|
|
Post by tango209 on Jan 31, 2015 1:47:15 GMT
I haven't seen anything like that in it, but you can script your own procedural generator:
1) In CameraController.cs at line 140 you would replace the World.GetInstance().Initialize(); line with the call to your generator. 2) Your generator would work something like this:
// Get the world engine and tell it we are preparing to generate World world = World.instance; world.status = HoneyFramework.World.Status.Preparation;
// Refresh terrain definitions TerrainDefinition.ReloadDefinitions();
// Clear out the old hex data world.hexes = new Dictionary<Vector3i, Hex>();
// Get the hexes we are going to populate List<Vector3i> rangeHexes = HexNeighbors.GetRange(new Vector3i(), world.hexRadius); int terrainCount = TerrainDefinition.definitions.Count; if (terrainCount < 1) { Debug.LogError("No terrain definitions to use!"); return; }
// Add the hex data Hex hex; MHTerrain td; foreach (Vector3i v in rangeHexes) { hex = new Hex(); hex.orderPosition = Random.Range(0f, 1f); hex.rotationAngle = Random.Range(0f, 360f);
// Just grab the first non-sea terrain type td = MHTerrain.list.First(t => t.seaType == false); hex.terrainType = TerrainDefinition.definitions.First(t => t.source.OID == td.OID);
hex.position = v; World.instance.ReadyToPolishHex(hex);
world.hexes.Add(v, hex); }
RiverFactory.CreateRivers(this, hexRadius);
// Force terrain redraw for (int x = -world.chunkRadius; x <= world.chunkRadius; x++) for (int y = -world.chunkRadius; y <= world.chunkRadius; y++) { world.PrepareChunkData(new Vector2i(x, y)); }
// Update the status to show the engine is generating the terrain world.status = HoneyFramework.World.Status.TerrainGeneration;
|
|
|
Post by wyliam on Jan 31, 2015 1:59:32 GMT
Nice-yeah. After digging around a bit, I can see how that could be updated to accommodate that. I've already been modifying TerrainDefinition to allow Lakes and such as well.
Thanks!
|
|
|
Post by khash on Jan 31, 2015 17:22:40 GMT
Note that if you want to have nice lakes maybe you dont want to have beach around them. You should then play with "SEA" tag. Its used by World Oven to extend sand from under water to nearby areas. You may want to add LAKE tag which would have benefit of the sea tag in most cases but will not get render way in oven .
|
|
|
Post by wyliam on Jan 31, 2015 20:47:23 GMT
My first pass was an inverted mountain [pic], which clearly isn't going to work as is. If it were tagged sea, would the rivers try to end in it as well? As you can see from the pic they ignore them as normal terrain. I guess I should dig into what the world oven does with sea tags.
|
|
|
Post by khash on Jan 31, 2015 21:25:41 GMT
look in RiverFactory for this line: if (!world.hexes.ContainsKey(v) || world.hexes[v].terrainType.source.typeList.Contains( GoogleFu.Tags.rowIds.TAG_SEA))
|
|
|
Post by wyliam on Feb 1, 2015 21:22:02 GMT
If anyone's interested, I got this working. I used Tango's snippet to create a new "InitializeWithWeight()" method. After adding the weight INT to the MHTerrain data and exposing it in the inspector, I run through the weights (below). I also added a new GUI button to use the weighted init method, so I could tweak the values to my liking. I intend to generate at run time. public void InitializeWithWeight()
{
// Get the world engine and tell it we are preparing to generate
World world = World.instance;
World.status = HoneyFramework.World.Status.Preparation;
// Refresh terrain definitions
TerrainDefinition.ReloadDefinitions();
// Clear out the old hex data
world.hexes = new Dictionary<Vector3i, Hex>();
// Get the hexes we are going to populate
List<Vector3i> rangeHexes = HexNeighbors.GetRange(new Vector3i(), world.hexRadius);
int terrainCount = TerrainDefinition.definitions.Count;
if (terrainCount < 1)
{
Debug.LogError("No terrain definitions to use!");
return;
}
// calculate the total weight of rarity
int totalWeight = MHTerrain.list.Sum(t => t.mode == MHTerrain.Mode.normal ? t.weight : 0);
int weight;
// Add the hex data
Hex hex;
MHTerrain td;
foreach (Vector3i v in rangeHexes)
{
hex = new Hex();
hex.orderPosition = UnityEngine.Random.Range(0f, 1f);
hex.rotationAngle = UnityEngine.Random.Range(0f, 360f);
// Just grab the first non-sea terrain type (but overwrite with rarity)
td = MHTerrain.list.First(t => t.isSeaType == false);
// value to look for
weight = Random.Range(0, totalWeight);
// updated weight value as we iterate through potential matches
int newWeight = 0;
// find the terrain whose range fits within that amount
foreach (MHTerrain terrain in MHTerrain.list)
{
if (terrain.mode != MHTerrain.Mode.normal) continue;
newWeight += terrain.weight;
if (weight <= newWeight)
{
td = terrain;
break;
}
}
hex.terrainType = TerrainDefinition.definitions.First(t => t.source.OID == td.OID);
hex.position = v;
HexWorld.instance.ReadyToPolishHex(hex);
world.hexes.Add(v, hex);
}
RiverFactory.CreateRivers(this, hexRadius);
// Force terrain redraw
for (int x = -world.chunkRadius; x <= world.chunkRadius; x++)
for (int y = -world.chunkRadius; y <= world.chunkRadius; y++)
{
world.PrepareChunkData(new Vector2i(x, y));
}
// Update the status to show the engine is generating the terrain
HexWorld.status = HoneyFramework.HexWorld.Status.TerrainGeneration;
} Haven't looked into getting the rivers to run into the lakes yet. Thanks guys!
|
|
|
Post by nichtdiemama on Apr 18, 2015 13:44:52 GMT
How did you manage to disable the borders of the hex. I cant find that line.
|
|