Okay, this post got a little technical so here's the tl;dr version. I think I can make the whole worldmap generation thing a whole lot simpler, and way easier to add new locations to. Maybe I could even port it to a script file instead of people having to touch code to add dungeons. But the catch is that the New Attnam continent will average slightly bigger (4 to 10 cells instead of 2 to 4) and that it might not always be as close to the Attnam continent as before (the underwater tunnel could be improbably long). Is that acceptable?
Great tutorial, Warheck!
So, to clarify a little, the way things are working in the code there are that wterras.h contains a bunch of class definitions for classes that extend owterrain and gwterrain. owterrain is towns and dungeons and the like, gwterrain is forests and tundras and the like - I have no clue what the two names are supposed to mean, they're both overworld terrain. OWTERRAIN(namehere, owterrain) is a macro that does part of the class definition for you. What you are filling in at wterras.cpp are the actual methods of the class, which contain the class data. Nothing is actually being added to the game at this point though, just the code. Down in worldmap.cpp when you call ChangeOWTerrain(namehere::Spawn()) you are calling a method in the class namehere (which you unwittingly made with that OWTERRAIN macro) which creates an instance of that class and puts it into that square of the map.
This is actually rather inside-out. All the dungeons and towns could share a class, and different objects of that class would have their different name strings, graphics positions, etc. This would also be convenient because it'd allow you to make an actual list of places in the game, which then allows you to replace that whole mess at the start of worldmap::Generate() with something that looks like:
for(uint c = 1; c < Continent.size(); ++c)
{
if(Continent[c]->GetSize() > 25 && Continent[c]->GetSize() < 1000)
{
truth aPlaceForEveryone = true;
for(uint i = 0; i < ImportantPlaces.size(); i++)
{
if(Continent[c]->GetGTerrainAmount(ImportantPlaces[i]->GetLocalEnvironment())
{
aPlaceForEveryone = false;
break;
}
}
if(aPlaceForEveryone)
{
PerfectForAttnam.push_back(Continent[c]);
}
}
}
Which doesn't need to be changed when you add places, you just need to make sure ImportantPlaces gets your new location added to it at some point if it needs to be in the Attnam continent. And the AttnamPos, ElpuriCavePos stuff can be done easily with a list, as can the end spawning.
This can be extended to work for multiple continents pretty easily too. ImportantPlaces becomes a list of lists, things that need to go in the first continent go into the first list, next continent the second list, and so on. I can write code if that makes it more clear, but what I really want to get at is that there is a big messy hitch to all of this.
New Attnam is not actually on a continent. The game doesn't even look for a tiny island for it. Wherever the exit to the underwater tunnel goes, the game looks a certain radius outwards for some ocean and builds a tiny island on the spot, midway through the part where the other locations are looking for a place in the already-existing world. It's really hacky and I don't know how to generalize that.
So what I was thinking is maybe I make it so the game can check for different required sizes for the different continents (see above, it's looking for 25 to 1000 for the Attnam continent). Then the multi-continent thing above would let it put New Attnam on a small real continent, instead of a small continent it summoned out of the aether. The problem is that by default those continents wouldn't be anywhere near eachother. I could pretty easily add a generic thing that says two overworld locations try to be close to eachother (by repeatedly sampling possible locations and taking the best of N samples) which increases generation time slightly and improves the tunnel situation so far as at least making the two ends be as close as they can be on their continents (which is to say, if the continents are on opposite sides of the world, at least the tunnels are facing eachother). I could also put in a hard limit (discard the world if two locations are not within X of eachother), which fixes the problem entirely but that would probably increase generation time a fair deal, especially as people add more locations that use this requirement.
Anything that reduces special locations to objects instead of classes has another benefit. It's the prerequisite to being able to port that off to a script file. But learning how to make new script files is a big challenge in and of itself, I'd say this is something that should be done in two steps.
So... go for it, or use your tutorial as the official way to add new things to the world?