Global Warming mod

I actually never liked the way global warming is presented in civilization, so I planned to add this to my mod. But my question is how hard would it be to add a new terrain to this terrain warming cycle?
 
I actually never liked the way global warming is presented in civilization, so I planned to add this to my mod. But my question is how hard would it be to add a new terrain to this terrain warming cycle?

Are we talking about base terrain like grasslands and plains, or features like forests and jungles?
 
Are we talking about base terrain like grasslands and plains, or features like forests and jungles?

Just base terrain marsh. I took closer look on your code. Do I have to add it only in CvXMLLoadUtilitySet.cpp and CvGame.cpp? Like this:
Code:
		SetGlobalDefine("MARSH_TERRAIN", szVal);
		idx = FindInInfoClass(szVal);
		GC.getDefinesVarSystem()->SetValue("MARSH_TERRAIN", idx);
and this:
Code:
					else if (pPlot->getTerrainType() == eMarshTerrain)
					{
						pPlot->setTerrainType(eTemperateTerrain);
						bChanged = true;
					}
And ofcourse define that MARSH_TERRAIN in GlobalDefinesAlt.
And I almost forgot, near the beginning of void CvGame::doGlobalWarming().
Code:
	TerrainTypes eWarmingTerrain = ((TerrainTypes)(GC.getDefineINT("GLOBAL_WARMING_TERRAIN")));
	TerrainTypes eFrozenTerrain = ((TerrainTypes)(GC.getDefineINT("FROZEN_TERRAIN")));
	TerrainTypes eColdTerrain = ((TerrainTypes)(GC.getDefineINT("COLD_TERRAIN")));
	[COLOR="Red"]TerrainTypes eMarshTerrain = ((TerrainTypes)(GC.getDefineINT("MARSH_TERRAIN")));[/COLOR]
	TerrainTypes eTemperateTerrain = ((TerrainTypes)(GC.getDefineINT("TEMPERATE_TERRAIN")));
	TerrainTypes eDryTerrain = ((TerrainTypes)(GC.getDefineINT("DRY_TERRAIN")));
	TerrainTypes eBarrenTerrain = ((TerrainTypes)(GC.getDefineINT("BARREN_TERRAIN")));
	TerrainTypes eShallowsTerrain = ((TerrainTypes)(GC.getDefineINT("SHALLOW_WATER_TERRAIN")));

	FeatureTypes eColdFeature = ((FeatureTypes)(GC.getDefineINT("COLD_FEATURE")));
	FeatureTypes eTemperateFeature = ((FeatureTypes)(GC.getDefineINT("TEMPERATE_FEATURE")));
	FeatureTypes eWarmFeature = ((FeatureTypes)(GC.getDefineINT("WARM_FEATURE")));
	FeatureTypes eFalloutFeature = ((FeatureTypes)(GC.getDefineINT("NUKE_FEATURE")));
Is there something more complicated than this?
 
Yes, that looks like it's all that's needed for a new terrain type. There is one other thing you could optionally add. With that set up, if there is a feature on a marsh tile then it will be removed with the first GW strike and leave the underlying terrain the same. Now if you would like a marsh tile with a forest or jungle on it to dry up the marsh into a grassland first and leave the that feature there, then there is something else too add.
Is that an effect you'd want?
 
Would the function look like this, in red added by me
Code:
void CvGame::doGlobalWarming()
{//GWMod Start M.A.
	int iGlobalWarmingDefense = 0;
	int iTreeHuggerDefenseBonus = GC.getDefineINT("TREEHUGGER_DEFENSE_BONUS");
	bool abTreeHugger[MAX_PLAYERS];

	for (int iI = 0; iI < MAX_PLAYERS; iI++)//GWMod Loop to look for environmentalism witten by EmperorFool
	{
		abTreeHugger[iI] = false;
		if (GET_PLAYER((PlayerTypes)iI).isAlive())
		{
			for (int iJ = 0; iJ < GC.getNumCivicOptionInfos(); iJ++)
			{
				CivicTypes eCivic = GET_PLAYER((PlayerTypes)iI).getCivics((CivicOptionTypes)iJ);
				if (GC.getCivicInfo(eCivic).getExtraHealth() != 0)
				{
					abTreeHugger[iI] = true;
					break;
				}
			}
		}
	}

	for (int i = 0; i < GC.getMapINLINE().numPlotsINLINE(); ++i)
	{
		CvPlot* pPlot = GC.getMapINLINE().plotByIndexINLINE(i);
		if (pPlot->getFeatureType() != NO_FEATURE)
		{
			int iFeatureWarmingDefense = GC.getFeatureInfo(pPlot->getFeatureType()).getWarmingDefense();
			if (iFeatureWarmingDefense > 0)
			{
				PlayerTypes eCulturalOwner = pPlot->getOwner();
				if (eCulturalOwner != NO_PLAYER)
				{
					if (abTreeHugger[eCulturalOwner])
					{
						iGlobalWarmingDefense += (iFeatureWarmingDefense) * (iTreeHuggerDefenseBonus);
					}
					else
					{
						iGlobalWarmingDefense += iFeatureWarmingDefense;
					}
				}
				else
				{
					iGlobalWarmingDefense += iFeatureWarmingDefense;
				}
			}
		}
	}
	iGlobalWarmingDefense = iGlobalWarmingDefense * GC.getDefineINT("GLOBAL_WARMING_FOREST") / std::max(1, GC.getMapINLINE().getLandPlots());

	int iUnhealthWeight = GC.getDefineINT("GLOBAL_WARMING_UNHEALTH_WEIGHT");
	int iBonusWeight = GC.getDefineINT("GLOBAL_WARMING_BONUS_WEIGHT");
	int iPowerWeight = GC.getDefineINT("GLOBAL_WARMING_POWER_WEIGHT");
	int iGlobalWarmingValue = 0;
	for (int iPlayer = 0; iPlayer < MAX_PLAYERS; ++iPlayer)
	{
		CvPlayer& kPlayer = GET_PLAYER((PlayerTypes) iPlayer);
		if (kPlayer.isAlive())
		{
			int iLoop;
			for (CvCity* pCity = kPlayer.firstCity(&iLoop); pCity != NULL; pCity = kPlayer.nextCity(&iLoop))
			{
				iGlobalWarmingValue -= (pCity->totalBadBuildingHealth() * iUnhealthWeight) + (pCity->getBonusBadHealth() * iBonusWeight) + (pCity->getPowerBadHealth() * iPowerWeight); //GWMod Changed to be total building bad health and to include power and bonuses M.A.
			}
		}
	}
	iGlobalWarmingValue /= GC.getMapINLINE().numPlotsINLINE();

	TerrainTypes eWarmingTerrain = ((TerrainTypes)(GC.getDefineINT("GLOBAL_WARMING_TERRAIN")));
	TerrainTypes eFrozenTerrain = ((TerrainTypes)(GC.getDefineINT("FROZEN_TERRAIN")));
	TerrainTypes eColdTerrain = ((TerrainTypes)(GC.getDefineINT("COLD_TERRAIN")));
	[COLOR="Red"]TerrainTypes eMarshTerrain = ((TerrainTypes)(GC.getDefineINT("MARSH_TERRAIN")));[/COLOR][COLOR="Green"]//added by NotSoGood[/COLOR]
	TerrainTypes eTemperateTerrain = ((TerrainTypes)(GC.getDefineINT("TEMPERATE_TERRAIN")));
	TerrainTypes eDryTerrain = ((TerrainTypes)(GC.getDefineINT("DRY_TERRAIN")));
	TerrainTypes eBarrenTerrain = ((TerrainTypes)(GC.getDefineINT("BARREN_TERRAIN")));
	TerrainTypes eShallowsTerrain = ((TerrainTypes)(GC.getDefineINT("SHALLOW_WATER_TERRAIN")));

	FeatureTypes eColdFeature = ((FeatureTypes)(GC.getDefineINT("COLD_FEATURE")));
	FeatureTypes eTemperateFeature = ((FeatureTypes)(GC.getDefineINT("TEMPERATE_FEATURE")));
	FeatureTypes eWarmFeature = ((FeatureTypes)(GC.getDefineINT("WARM_FEATURE")));
	FeatureTypes eFalloutFeature = ((FeatureTypes)(GC.getDefineINT("NUKE_FEATURE")));

	//Global Warming
	for (int iI = 0; iI < iGlobalWarmingValue; iI++)
	{
		if (getSorenRandNum(100, "Global Warming") + iGlobalWarmingDefense < GC.getDefineINT("GLOBAL_WARMING_PROB"))
		{
			CvPlot* pPlot = GC.getMapINLINE().syncRandPlot(RANDPLOT_NOT_CITY); // GWMod removed check for water tile M.A.

			if (pPlot != NULL)
			{
				FeatureTypes eFeature = pPlot->getFeatureType();
				bool bChanged = false;
				if (pPlot->getFeatureType() != NO_FEATURE)
				{
					if (pPlot->getFeatureType() != GC.getDefineINT("NUKE_FEATURE"))
					{// GWMod won't remove features if underlaying terrain can melt
						if (pPlot->getFeatureType() != eColdFeature)
						{
							if ((pPlot->calculateBestNatureYield(YIELD_FOOD, NO_TEAM) > 1) && (pPlot->getFeatureType() == eTemperateFeature))
							{
								pPlot->setFeatureType(eWarmFeature);
								bChanged = true;
							}
							else if (pPlot->getTerrainType() == eColdTerrain)
							{
								pPlot->setTerrainType(eTemperateTerrain);
								bChanged = true;
							}
							[COLOR="Green"]//added by NotSoGood[/COLOR]
							[COLOR="red"]else if (pPlot->getTerrainType() == eMarshTerrain)
							{
								pPlot->setTerrainType(eTemperateTerrain);
								bChanged = true;
							}[/COLOR]
							else if (pPlot->getTerrainType() == eFrozenTerrain)
							{
								pPlot->setTerrainType(eColdTerrain);
								bChanged = true;
							}
							else
							{
								pPlot->setFeatureType(NO_FEATURE);
								bChanged = true;
							}
						}
						else
						{
							pPlot->setFeatureType(NO_FEATURE);
							bChanged = true;
						}
					}
				}
				else if (!pPlot->isWater())  // GWMod added check for water tile M.A.
				{// GWMod stepped terrain changes M.A.
					if (pPlot->getTerrainType() == eBarrenTerrain)
					{
						if (isOption(GAMEOPTION_RISING_SEAS))
						{
							if (pPlot->isCoastalLand())
							{
								if (!pPlot->isHills() && !pPlot->isPeak())
								{
									pPlot->setTerrainType(eShallowsTerrain);
									bChanged = true;
								}
							}
						}
					}
					else if (pPlot->getTerrainType() == eDryTerrain)
					{
						pPlot->setTerrainType(eBarrenTerrain);
						bChanged = true;
					}
					else if (pPlot->getTerrainType() == eTemperateTerrain)
					{
						pPlot->setTerrainType(eDryTerrain);
						bChanged = true;
					}
					else if (pPlot->getTerrainType() == eColdTerrain)
					{
						pPlot->setTerrainType(eTemperateTerrain);
						bChanged = true;
					}
					[COLOR="green"]//added by NotSoGood[/COLOR][COLOR="red"]
					else if (pPlot->getTerrainType() == eMarshTerrain)
					{
						pPlot->setTerrainType(eTemperateTerrain);
						bChanged = true;
					}[/COLOR]
					else if (pPlot->getTerrainType() == eFrozenTerrain)
					{
						pPlot->setTerrainType(eColdTerrain);
						bChanged = true;
					}
				}

				if (bChanged)
				{
					pPlot->setImprovementType(NO_IMPROVEMENT);

					CvCity* pCity = GC.getMapINLINE().findCity(pPlot->getX_INLINE(), pPlot->getY_INLINE());
					if (pCity != NULL)
					{
						if (pPlot->isVisible(pCity->getTeam(), false))
						{
							CvWString szBuffer = gDLL->getText("TXT_KEY_MISC_GLOBAL_WARMING_NEAR_CITY", pCity->getNameKey());
							gDLL->getInterfaceIFace()->addMessage(pCity->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_GLOBALWARMING", MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE(), true, true);
						}
					}
				}
			}
		}
	}
	//Nuclear Winter
	int iNuclearWinterValue = 0;
	iNuclearWinterValue += getNukesExploded() * GC.getDefineINT("GLOBAL_WARMING_NUKE_WEIGHT") / 100;

	for (int iI = 0; iI < iNuclearWinterValue; iI++)
	{
		if (getSorenRandNum(100, "Nuclear Fallout") + iGlobalWarmingDefense < GC.getDefineINT("NUCLEAR_WINTER_PROB"))
		{
			CvPlot* pPlot = GC.getMapINLINE().syncRandPlot(RANDPLOT_LAND | RANDPLOT_NOT_CITY);
			FeatureTypes eFeature = pPlot->getFeatureType();

			if (pPlot != NULL)
			{
				bool bChanged = false;
				if (pPlot->getFeatureType() != NO_FEATURE)
				{
					if (pPlot->getFeatureType() != GC.getDefineINT("NUKE_FEATURE"))
					{
						if (pPlot->getFeatureType() != eColdFeature)
						{
							pPlot->setFeatureType(NO_FEATURE);
							bChanged = true;
						}
					}
				}
				else
				{
					pPlot->setFeatureType(eFalloutFeature);
					bChanged = true;
				}
				if (getSorenRandNum(100, "Nuclear Winter") + iGlobalWarmingDefense < GC.getDefineINT("NUCLEAR_WINTER_PROB"))
				{
					if (pPlot->getTerrainType() == eColdTerrain)
					{
						pPlot->setTerrainType(eFrozenTerrain);
						bChanged = true;
					}
					if (pPlot->calculateTotalBestNatureYield(NO_TEAM) > 1)
					{
						pPlot->setTerrainType(eColdTerrain);
						bChanged = true;
					}
				}
				if (bChanged)
				{
					pPlot->setImprovementType(NO_IMPROVEMENT);

					CvCity* pCity = GC.getMapINLINE().findCity(pPlot->getX_INLINE(), pPlot->getY_INLINE());
					if (pCity != NULL)
					{
						if (pPlot->isVisible(pCity->getTeam(), false))
						{
							CvWString szBuffer = gDLL->getText("TXT_KEY_MISC_NUCLEAR_WINTER_NEAR_CITY", pCity->getNameKey());
							gDLL->getInterfaceIFace()->addMessage(pCity->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_GLOBALWARMING", MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE(), true, true);
						}
					}
				}
			}
		}
	}
}//GWMod end M.A.
Or is there more something else I didn't notice?
 
That looks like it should be it.
Remember that I missed the comment marker (GWmod) for "getWarmingDefense" in cvInfo.h so remember to grab that when merging.
 
Hi minor annoyance

I really like the idea behind your mod, but i've tested the mod (included in pig and unofficial expansion) and in my games anything happens, i've compared screen from 1700 to 2070 (much after the last tech was researched) and any singe tile, nothing changed...

well, maybe it's cause i play in small maps?
 
Hi minor annoyance

I really like the idea behind your mod, but i've tested the mod (included in pig and unofficial expansion) and in my games anything happens, i've compared screen from 1700 to 2070 (much after the last tech was researched) and any singe tile, nothing changed...

well, maybe it's cause i play in small maps?

Sorry to ask the obvious question, but you did turn it on in the custom game option menu, right? (For PIG)

If you did, to see if it works you should be able to fiddle with one of the XML settings to make GW much more likely, so you can check whether the mod is at least working.
 
Sorry to ask the obvious question, but you did turn it on in the custom game option menu, right? (For PIG)

If you did, to see if it works you should be able to fiddle with one of the XML settings to make GW much more likely, so you can check whether the mod is at least working.



If you mean the "rising seas" option, yes, i've enabled it, or maybe i've missed an option??
 
If you mean the "rising seas" option, yes, i've enabled it, or maybe i've missed an option??

No that's right. You didn't miss anything. I'll look into it. It's quite possible I missed something that is making the mod not work.

I suppose at worst, there is no global warming at all in the game. That probably doesn't bother some players. :lol:

Thanks for the report anyway! :goodjob:

EDIT ninja edit for small correction :)
 
No that's right. You didn't miss anything. I'll look into it. It's quite possible that when I produced the GWmod for 3.19 (in the thread for the mod) I missed something that is making the mod not work. If other people used the 3.19 code I released, it may be the reason it's not working in other mods. :blush:

I suppose at worst, there is no global warming at all in the game. That probably doesn't bother some players. :lol:

Thanks for the report anyway! :goodjob:


Nooo i like the global warming concept, in civ4 it's messed up, but with the minor annoyance changes would be interesting!

I like that the world changes in accoring to the players emissions :nuke::nuke:
 
Nooo i like the global warming concept, in civ4 it's messed up, but with the minor annoyance changes would be interesting!

I like that the world changes in accoring to the players emissions :nuke::nuke:

Well I agree with you. I do intend to fix it. I just don't know why it's not working yet.
 
Ok I can't get this to run as a stand alone mod even.

Attached is my attempt at making it compatible with 3.19. Can anyone figure out why it's not working?
 

Attachments

  • Global Warming 3.19.7z
    1.2 MB · Views: 149
When I merged it into BULL I noticed that there was a change (in CvEnum.h?) that wasn't marked with a MA comment, but IIRC it caused a compiler error so you must have found it too. To be honest, I have never tried to see if it works in BULL either. :blush:
 
To be honest, I have never tried to see if it works in BULL either. :blush:

I merged it with RevDCM way back in the summer, and even though I thought I merged it 100% correctly, I never could get it to work in game, the effects never appeared. I always thought I had screwed something up; maybe the actual code here is broken...
 
When I merged it into BULL I noticed that there was a change (in CvEnum.h?) that wasn't marked with a MA comment, but IIRC it caused a compiler error so you must have found it too. To be honest, I have never tried to see if it works in BULL either. :blush:

I think the uncommented change was in CvInfos.h or .cpp. I did notice it though.

Anyway, as it's not working for phungus and Afforess too, I suspect it is simply not working. Anyone have any ideas on what to do about fixing it?

The code I posted above is a stand-alone merge of GWmod so hopefully working on that should be easiest?
 
I haven't done a lot of testing in real games yet. Mostly just cranking :yuck: to extreme levels to check the code. My computer is so slow I just can't play the game. My last game (which did have my GW changes) too 100 hours to finish and it was on normal speed and medium sized map. I've heard people finish marathon games on huge maps in 15 hours. Right now this computer is struggling to keep up with my typing and I don't type very fast. So I'll be reformatting soon.

Anyway, I didn't see any global warming either, and I chose all leaders with high production flavor levels, and it did get into the modern era. So there is likely adjustments to be made. Things with randomness are hard to test because you can never be sure if something won't happen or if it just hasn't happened yet. By the way, this is the first time in almost a year that I've actually gotten feedback on how it works in actual practice, so thanks. Since the code does work it's just the numbers it uses that needs to be adjusted, all of which are in the XML.

So let's break down how it works:
iWarmingDefense is what each feature adds to global warming defence
TREEHUGGER_DEFENSE_BONUS is a multiplier applied if the feature is in a territory of a civ running environmentalism (or any civic with a :health: bonus)
GLOBAL_WARMING_FOREST is the multiplier for Warming Defense (I didn't change the name from the original)
That total is then divided by the number of land plots on the map. This is the final value for GW defence.
GLOBAL_WARMING_PROB is the base percentage change of global warming
When it rolls for global warming (number from 0 to 100) it adds the GW defence value. If the GW defence value is more than the GW probability then it will never occur. So if the GLOBAL_WARMING_PROB value is 20 (the default), then a final GW defence value of 20 makes it impossible.

That's one reason global warming might not be happening.

That was the defence, next is where it calculates the :yuck:, or the global warming "attack".

GLOBAL_WARMING_UNHEALTH_WEIGHT is the multiplier for the :yuck: from buildings
GLOBAL_WARMING_BONUS_WEIGHT is the multiplier for the :yuck: from bonuses (coal, oil etc.)
GLOBAL_WARMING_POWER_WEIGHT is the multiplier for the :yuck: from a city having power
All those are counted for every city and added together then divided by the maps total plots.
This is the final global warming value, which is the number of times the game will run a check for global warming. For each it rolls number from 0 to 100, adds the GW defence value and if it's less than the GLOBAL_WARMING_PROB then it picks a tile to hit.
Now when it divides by the number of map tiles the result might be less than 1, and it always rounds down. It's possible the if the multipliers for :yuck:are too low then there isn't enough :yuck:per city so there's no enough room on the map to have enough cities to have enough :yuck: to trigger GW.

That's the second reason it might not be happening.

Now for number crunching. Maybe later I'll use a spreadsheet to make it easier to fine tune if necessary. I'll start with a map of 4000 tiles which is a little smaller than the standard, and just assume it's all land, all features are forest, no environmentalism and all values are the defaults already used.

GLOBAL_WARMING_PROB x total tiles / GLOBAL_WARMING_FOREST / FeatureWarmingDefense = features needed to stop global warming

20x4000/25/2= 1600 features needed to stop global warming.
That's 40% of the land mass needing to have forest to totally prevent GW. That seems high to me and unlikely to occur often (unless I'm mistaken) so defence seems fine at the moment

Now "attack". Assuming all cities have recycling, and have clean power (2 :yuck:) and all :yuck: resource bonuses (totalling 6:yuck:).

1 x total map tiles / (GLOBAL_WARMING_BONUS_WEIGHT x city's power:yuck:) + (GLOBAL_WARMING_POWER_WEIGHT x city's bonus:yuck:) = number of developed cities needed to cause 1 check for GW a turn.

1 x 4000 / ((5x2) + (5x6)) = 100 developed cities needed to cause global warming.
That seems like a problem. Would you even see that many cities on a map that size? In the olden days when it was a building :yuck: weight of 20 and the city building's total :yuck: was 7 (does not include drydock or ironworks) it was 1 x 400 / 20 x 7 = 28.5 developed cities needed to cause global warming. That's much more likely.

So it seems the low weight of the :yuck: values are the problem. Those need to be higher.

Ok I can't get this to run as a stand alone mod even.

Attached is my attempt at making it compatible with 3.19. Can anyone figure out why it's not working?

I can't get civ4 to work at all recently. Some problem with barbarian in the force controls xml. I don't know what that is so I should reinstall. After reformatting.
 
I can't get civ4 to work at all recently. Some problem with barbarian in the force controls xml. I don't know what that is so I should reinstall. After reformatting.

This error occurs when you forget to put a Global Define in, and it must be there. Force Controls is the last XML file that loads, and if the game doesn't see the define by then, it gives you nasty errors. I've seen them before.
 
While crunching the numbers to see what settings generate what GW conditions on different maps I notice that a map with little land will have less chance of GW than one with a lot. This is because the city unhealthiness factors for GW (with it's multipliers) are divided by the map tiles. Less land means fewer cities and fewer GW factors, but the same sized map so sometimes there might never be enough cities to cause global warming. On the other hand, a map with all land will have more cities and thus will have more GW on the same size map. The easy solution is to divide the GW factors by the number of land tiles instead of total tiles. Land tiles plus shore tiles would be better because a map with lots of small islands could have the same number of cities as one will all land but with much increased change of GW due to the small divider, so including shores would even it out.

Also with regards to GW defence, since it's hard to get more features than what you start with the highest levels of GW defence are set when the map is created. If it's a rainforest map then the starting levels of GW defence might be over the amount needed to make GW impossible, while a map with far less might have such a small GWdefence value that it hardy makes a difference even if you keep all the features.

If I have the game count the total GW defence at the beginning of the game I could have it set that amount as the defence level required to totally prevent GW. Thus if you keep it all intact (unlikely, especially with the AI) you'll never have to worry. Then with the environmentalism modifier you could stand to lose some.

So GW factors that are adapted to the map will be the next plan. Also modifying the chance of GW based on map speed.
 
Top Bottom