Civilization Tactical Combat Development Thread (Input/Suggestions Wanted)

Iirc it is set to ocean so it might cause weird behavior later if plot type is ocean but terrain type grassland.

It won't cause any problems because of this code in setTerrainType():

Code:
if (GC.getTerrainInfo(getTerrainType()).isWater() != isWater())
{
	setPlotType(((GC.getTerrainInfo(getTerrainType()).isWater()) ? PLOT_OCEAN : PLOT_LAND), bRecalculate, bRebuildGraphics);
}

Maybe a unit for which you destroyed the entity is still selected.
So best deselect all units and cities at the start of the function.
Looking at CvUnit::reloadEntity() there do not seem to be other functions to call.

I added this and am building it now. I'll let you know if it works.
 
It appears as if that problem is fixed as well, but somehow the game is still calling doTurn() on the units I switched to m_altUnits. Is there still something wrong with this function's logic?

Code:
void CvPlayer::swapUnitsAndCities()
{
	FFreeListTrashArray<CvCityAI> tempCities;
	FFreeListTrashArray<CvUnitAI> tempUnits;
	FFreeListTrashArray<CvSelectionGroupAI> tempGroups;
	FFreeListTrashArray<CvCityAI> blankCities;
	FFreeListTrashArray<CvUnitAI> blankUnits;
	FFreeListTrashArray<CvSelectionGroupAI> blankGroups;

	tempCities = m_cities;
	m_cities = m_altCities;
	m_altCities = tempCities;

	tempUnits = m_units;
	m_units = m_altUnits;
	m_altUnits = tempUnits;

	tempGroups = m_selectionGroups;
	m_selectionGroups = m_altSelectionGroups;
	m_altSelectionGroups = tempGroups;

	tempUnits = blankUnits;			// setting these to blank lists so that the destructor
	tempCities = blankCities;		// doesn't delete the units/cities in the alt lists
	tempGroups = blankGroups;
}
 
It appears as if that problem is fixed as well, but somehow the game is still calling doTurn() on the units I switched to m_altUnits. Is there still something wrong with this function's logic?
It looks right to me. doTurn() of units is only called by selection groups doTurn() which you also replaced.
So I am not sure how it still got to the old units if you properly called that function for all players.
 
You should definitely try to add the ACO modcomp (advanced combat odds) to this. This looks really good, and if it ends out great, could I use this in my mod? This would be good for the tactical modern day battles :D
 
You should definitely try to add the ACO modcomp (advanced combat odds) to this. This looks really good, and if it ends out great, could I use this in my mod? This would be good for the tactical modern day battles :D

Since the mod's based off of RevDCM, it already contains ACO and a lot of other amazing modcomps :). And yes, I'll definitely let anyone use this in other mods after I release it.
 
How is it going?


I mean, with all the techno-bubble that occupied the thread last page, I did not understand what you're actually doing.


For istance, are you still trying to create a tactical map or are you trying to use the main map itself?

Can you please translate a sum in human language?

Anyway, good work!
 
How is it going?


I mean, with all the techno-bubble that occupied the thread last page, I did not understand what you're actually doing.


For istance, are you still trying to create a tactical map or are you trying to use the main map itself?

Can you please translate a sum in human language?

Anyway, good work!

He's trying to create a tactical map :)
 
@4lexander
Yes, I'm still trying to create a tactical map, except this way there won't be any need for reading/writing to files or loading a new game for every battle (a major improvement imo).

I'm running into a lot of problems with it, though. I haven't had much time to debug it the last couple days, but hopefully I can get it working here soon (that is if it's even possible, which is definitely not guaranteed).
 
OK, thank you all for information and btw for your invaluable work.

Hope to see this coming out soon.

Good work!
 
My most recent debugging shows that a city switched to an alt list is somehow switching back to the original list, causing it to reference it's plot, which no longer exists. Here's the full code for swapMaps()

Spoiler Code :
Code:
void CvGlobals::swapMaps()
{
	int i, iLoop;
	CvUnit* pLoopUnit;
	CvCity* pLoopCity;
	CvPlayerAI& kPlayer = GET_PLAYER((PlayerTypes)0);		// just because I have to initialize it...

	GC.setMapSwapping(true);

	for (i = 0; i < MAX_PLAYERS; i++)
	{
		kPlayer = GET_PLAYER((PlayerTypes)i);
		
		if (kPlayer.isAlive())
		{
			for (pLoopCity = kPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kPlayer.nextCity(&iLoop))
			{
				pLoopCity->removeEntity();
				pLoopCity->destroyEntity();
			}
			
			for (pLoopUnit = kPlayer.firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = kPlayer.nextUnit(&iLoop))
			{
				if (gDLL->getEntityIFace()->IsSelected(pLoopUnit->getEntity()))
				{
					gDLL->getInterfaceIFace()->selectUnit(pLoopUnit, true, true);
				}
				
				if (GC.IsGraphicsInitialized())
				{
					gDLL->getEntityIFace()->RemoveUnitFromBattle(pLoopUnit);
					pLoopUnit->removeEntity();
				}
				pLoopUnit->destroyEntity();
			}
			
			kPlayer.swapInfo();

			for (pLoopCity = kPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kPlayer.nextCity(&iLoop))
			{
				pLoopCity->removeEntity();
				pLoopCity->destroyEntity();
			}
			
			for (pLoopUnit = kPlayer.firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = kPlayer.nextUnit(&iLoop))
			{
				if (GC.IsGraphicsInitialized())
				{
					gDLL->getEntityIFace()->RemoveUnitFromBattle(pLoopUnit);
					pLoopUnit->removeEntity();
				}
				pLoopUnit->destroyEntity();
			}
		}
	}

	for (i = 0; i < GC.getMap().numPlots(); i++)
	{
		GC.getMap().plotByIndex(i)->destroyGraphics();
	}

	CvMap* tempMap = m_map;
	m_map = m_altMap;
	m_altMap = tempMap;

	GC.getMapINLINE().init();
	for (i = 0; i < GC.getMapINLINE().numPlots(); i++)
	{
		GC.getMapINLINE().plotByIndex(i)->setTerrainType((TerrainTypes)GC.getInfoTypeForString("TERRAIN_GRASS"), false, false);
	}
	gDLL->getEngineIFace()->RebuildAllPlots();
	GC.getMapINLINE().setupGraphical();

	for (i = 0; i < MAX_PLAYERS; i++)
	{
		kPlayer = GET_PLAYER((PlayerTypes)i);

		if (kPlayer.isAlive())
		{
			[COLOR="DimGray"]for (pLoopCity = kPlayer.firstCity(&iLoop); pLoopCity != NULL; pLoopCity = kPlayer.nextCity(&iLoop))
			{
				gDLL->getEntityIFace()->createCityEntity(pLoopCity);
				pLoopCity->setupGraphical();
			}[/COLOR]
			
			for (pLoopUnit = kPlayer.firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = kPlayer.nextUnit(&iLoop))
			{
				gDLL->getEntityIFace()->createUnitEntity(pLoopUnit);
				pLoopUnit->setupGraphical();
			}
		}
	}
}

CvPlayer::swapInfo() (which now swaps units, cities, selection groups, plot groups, and cycle selection groups) is working fine, but somehow by the time it gets to the highlighted loop, the player has the city again in m_cities. I've ran it a couple times trying to figure out what's causing this, and it always happens to PlayerTypes 1 (and possibly subsequent players, since it crashes before it gets to them). Any ideas?
 
After the swapInfo you go through the alt list and destroy entities. Is there a reason for that?

About the problem:
Was there any modifying access to any of the lists after the swap?
 
After the swapInfo you go through the alt list and destroy entities. Is there a reason for that?

Actually, no. I had it there to destroy the entities of all units/cities that may have originally been in the alt lists, but now that you mention it their entities would have already been destroyed.

I discovered the whole problem with the swapMaps() function was that I was looping through the players and changing the value of kPlayer (a CvPlayerAI reference). I actually didn't know until earlier today that you couldn't change what a reference pointed to. Now that I fixed that problem, it actually works! :woohoo:

By 'it actually works', I mean that it doesn't crash. The map displayed, however, is a haphazard combination of the new and the old, which obviously isn't what I want. I looked again at CvGame::regenerateMap() and the only pertaining functions I saw called that I'm not already calling are these:

Code:
for (iI = 0; iI < MAX_TEAMS; iI++)
{
	GC.getMapINLINE().setRevealedPlots(((TeamTypes)iI), false);
}

gDLL->getEngineIFace()->clearSigns();

I'll try these asap and see if this fixes things.
 
Calling those functions didn't seem to change anything--the old map is still graphically there, so I'm not sure what I need to do here. One thing that I'm not really sure about is functions like gDLL->getEngineIFace()->setDirty(). Probably a stupid question, but what exactly does it mean by 'set dirty'? Is it relevant for what I'm trying to do?

Do you have any idea what function might actually graphically destroy the map, and not just the features, symbols, etc.?
 
I believe (but am not sure) that "setDirty" is used for "update this" in regards to graphics, which are handled by the .exe.
Yes, that is the case. And not only for graphics. Also for other stuff that needs updating after changes to the game state like selection buttons or the city screen.
The advantage compared to just calling an updating method right away is that it delays the action and you can cheaply set the dirty bit a lot of times but the action will only be done once.
 
I believe (but am not sure) that "setDirty" is used for "update this" in regards to graphics, which are handled by the .exe.

Yes, that is the case. And not only for graphics. Also for other stuff that needs updating after changes to the game state like selection buttons or the city screen.
The advantage compared to just calling an updating method right away is that it delays the action and you can cheaply set the dirty bit a lot of times but the action will only be done once.

Okay, so it's nothing I'm really interested in right now. I wasn't sure, but thought I'd ask anyway.

I tried calling CvMap::rebuild() instead of init() and using an actual world size (instead of manually defining the grid width and height), but it didn't make a difference. At this point I'm beginning to think it's not even possible to make a different sized map, and represent it graphically, without access to the .exe. I'm assuming that a map of the same size will work fine, but I haven't actually tried it yet.

So: if this is the only possibility open, I thought perhaps I could make the actual 30x30 map (the battle plot and the surrounding 8 tiles) take up the middle plots of the map, and make the other plots be the surrounding strategic map, but inaccessible from the tactical map. This way the map would be the same size, but you would still only have access to the relevant plots.
 
Okay, so it's nothing I'm really interested in right now. I wasn't sure, but thought I'd ask anyway.
Actually it might help you if it causes the recalculations you need. An attempt to set all the engine dirty bits is worth it

Other functions to try would be InitGraphics, some of the interface dirty bits or marking the plot textures as dirty (if that is not already done by one of the functions you call).
 
Just to confirm, I tried it with the same sized map and it seems to work perfectly.

Since you think setting the dirty bits might work (I'm sure you know far more about this than I do), I'll try that and setting the plot textures, when I get a chance, to see if I can get a different-sized map working as well. I've tried calling InitGraphics() already, but it crashed the game.
 
This will be the best mod I have ever seen when its done.
When do you hope it will be out? A year, 6 months?
No rush, just curious!
 
Top Bottom