Teach a noob how to do things with SDK.

NotSoGood

Emperor
Joined
Jan 25, 2009
Messages
1,077
Location
Finland
At first I apologize my bad English. Some parts of this text might be difficult to read and grammar awful. But try to cope with it.

My previous programming knowledge is only merging. I was planning to change the City/Improvement bombing so it could destroy routes too. Unfortunately I'm not too familiar with sdk coding so I decided to ask help. I thought that it might be handled in CvUnit.cpp. The only problem was tha there was few different functions and I didn't know witch one to edit.
Spoiler :
Code:
bool CvUnit::canAirBomb(const CvPlot* pPlot) const
{
	if (getDomainType() != DOMAIN_AIR)
	{
		return false;
	}

	if (airBombBaseRate() == 0)
	{
		return false;
	}

	if (isMadeAttack())
	{
		return false;
	}

	return true;
}


bool CvUnit::canAirBombAt(const CvPlot* pPlot, int iX, int iY) const
{
	CvCity* pCity;
	CvPlot* pTargetPlot;

	if (!canAirBomb(pPlot))
	{
		return false;
	}

	pTargetPlot = GC.getMapINLINE().plotINLINE(iX, iY);

	if (plotDistance(pPlot->getX_INLINE(), pPlot->getY_INLINE(), pTargetPlot->getX_INLINE(), pTargetPlot->getY_INLINE()) > airRange())
	{
		return false;
	}

	if (pTargetPlot->isOwned())
	{
		if (!potentialWarAction(pTargetPlot))
		{
			return false;
		}
	}

	pCity = pTargetPlot->getPlotCity();

	if (pCity != NULL)
	{
		if (!(pCity->isBombardable(this)))
		{
			return false;
		}
	}
	else
	{
		if (pTargetPlot->getImprovementType() == NO_IMPROVEMENT)
		{
			return false;
		}

		if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).isPermanent())
		{
			return false;
		}

		if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).getAirBombDefense() == -1)
		{
			return false;
		}
	}

	return true;
}


bool CvUnit::airBomb(int iX, int iY)
{
	CvCity* pCity;
	CvPlot* pPlot;
	CvWString szBuffer;

	if (!canAirBombAt(plot(), iX, iY))
	{
		return false;
	}

	pPlot = GC.getMapINLINE().plotINLINE(iX, iY);

	if (!isEnemy(pPlot->getTeam()))
	{
		getGroup()->groupDeclareWar(pPlot, true);
	}

	if (!isEnemy(pPlot->getTeam()))
	{
		return false;
	}

	if (interceptTest(pPlot))
	{
		return true;
	}

	pCity = pPlot->getPlotCity();

	if (pCity != NULL)
	{
		pCity->changeDefenseModifier(-airBombCurrRate());

		szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_DEFENSES_REDUCED_TO", pCity->getNameKey(), pCity->getDefenseModifier(false), getNameKey());
		gDLL->getInterfaceIFace()->addMessage(pCity->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMBARDED", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pCity->getX_INLINE(), pCity->getY_INLINE(), true, true);

		szBuffer = gDLL->getText("TXT_KEY_MISC_ENEMY_DEFENSES_REDUCED_TO", getNameKey(), pCity->getNameKey(), pCity->getDefenseModifier(false));
		gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMBARD", MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pCity->getX_INLINE(), pCity->getY_INLINE());
	}
	else
	{
		if (pPlot->getImprovementType() != NO_IMPROVEMENT)
		{
			if (GC.getGameINLINE().getSorenRandNum(airBombCurrRate(), "Air Bomb - Offense") >=
					GC.getGameINLINE().getSorenRandNum(GC.getImprovementInfo(pPlot->getImprovementType()).getAirBombDefense(), "Air Bomb - Defense"))
			{
				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_DESTROYED_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGE", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pPlot->getX_INLINE(), pPlot->getY_INLINE());

				if (pPlot->isOwned())
				{
					szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_IMP_WAS_DESTROYED", GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide(), getNameKey(), getVisualCivAdjective(pPlot->getTeam()));
					gDLL->getInterfaceIFace()->addMessage(pPlot->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGED", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE(), true, true);
				}

				pPlot->setImprovementType((ImprovementTypes)(GC.getImprovementInfo(pPlot->getImprovementType()).getImprovementPillage()));
			}
			else
			{
				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_FAIL_DESTROY_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMB_FAILS", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE());
			}
		}
	}

	setReconPlot(pPlot);

	setMadeAttack(true);
	changeMoves(GC.getMOVE_DENOMINATOR());

	if (pPlot->isActiveVisible(false))
	{
		CvAirMissionDefinition kAirMission;
		kAirMission.setMissionType(MISSION_AIRBOMB);
		kAirMission.setUnit(BATTLE_UNIT_ATTACKER, this);
		kAirMission.setUnit(BATTLE_UNIT_DEFENDER, NULL);
		kAirMission.setDamage(BATTLE_UNIT_DEFENDER, 0);
		kAirMission.setDamage(BATTLE_UNIT_ATTACKER, 0);
		kAirMission.setPlot(pPlot);
		kAirMission.setMissionTime(GC.getMissionInfo((MissionTypes)MISSION_AIRBOMB).getTime() * gDLL->getSecsPerTurn());

		gDLL->getEntityIFace()->AddMission(&kAirMission);
	}

	if (isSuicide())
	{
		kill(true);
	}

	return true;
}
I thought the first function checks just if the unit can bomb and the second checks more if you can bomb and the third does all the work. Please correct me if I'm wrong.
I don't think I need to edit the first function at all. But should I check in the second fuction if the plot has route? This is just a ques but would it look something like this:
Spoiler :
Code:
bool CvUnit::canAirBombAt(const CvPlot* pPlot, int iX, int iY) const
{
	CvCity* pCity;
	CvPlot* pTargetPlot;

	if (!canAirBomb(pPlot))
	{
		return false;
	}

	pTargetPlot = GC.getMapINLINE().plotINLINE(iX, iY);

	if (plotDistance(pPlot->getX_INLINE(), pPlot->getY_INLINE(), pTargetPlot->getX_INLINE(), pTargetPlot->getY_INLINE()) > airRange())
	{
		return false;
	}

	if (pTargetPlot->isOwned())
	{
		if (!potentialWarAction(pTargetPlot))
		{
			return false;
		}
	}

	pCity = pTargetPlot->getPlotCity();

	if (pCity != NULL)
	{
		if (!(pCity->isBombardable(this)))
		{
			return false;
		}
	}
	else
	{
[COLOR="Red"]/*************************************************************************************************/
/**Can bombard routes                        5/12/09                                NotSoGood    */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
		if (pTargetPlot->getRouteType() == NO_ROUTE)
		{
			return false:
		}
/*************************************************************************************************/
/**Can bombard routes                        END                                                 */
/*************************************************************************************************/[/COLOR]
		if (pTargetPlot->getImprovementType() == NO_IMPROVEMENT)
		{
			return false;
		}

		if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).isPermanent())
		{
			return false;
		}

		if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).getAirBombDefense() == -1)
		{
			return false;
		}
	}

	return true;
}
But that's all I know I should do. I have no idea what I should add to the third function. So could anyone with some sdk knowledge teach me little more about it?
 
First checks if you can bomb at all, not sure why it requires a plot as it doesn't use it. Second checks if you can bomb a specific plot. And yes, third one does the bombing.

Your change in the second function would make it so you can only bomb a tile that does have a road AND an improvement. Instead you want something like this:

Code:
	else
	{
		if (pTargetPlot->getImprovementType() == NO_IMPROVEMENT)
		{
[COLOR="Red"]			if (pTargetPlot->getRouteType() == NO_ROUTE)
			{
[/COLOR]				return false:
[COLOR="Red"]			}
[/COLOR]		}

Now if it has either an improvement or a road you are allowed to hit it. You can make the same exception in the check for isPermanent if you want to allow someone to remove roads from under permanent improvements, but shouldn't make such an exception in the BombDefense, as the improvement ought to extend the defense to the road under it.

To actually remove the routes, in the third function do something like this:

Code:
	else
	{
		if (pPlot->getImprovementType() != NO_IMPROVEMENT)
		{
			if (GC.getGameINLINE().getSorenRandNum(airBombCurrRate(), "Air Bomb - Offense") >=
					GC.getGameINLINE().getSorenRandNum(GC.getImprovementInfo(pPlot->getImprovementType()).getAirBombDefense(), "Air Bomb - Defense"))
			{
				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_DESTROYED_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGE", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pPlot->getX_INLINE(), pPlot->getY_INLINE());

				if (pPlot->isOwned())
				{
					szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_IMP_WAS_DESTROYED", GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide(), getNameKey(), getVisualCivAdjective(pPlot->getTeam()));
					gDLL->getInterfaceIFace()->addMessage(pPlot->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGED", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE(), true, true);
				}

				pPlot->setImprovementType((ImprovementTypes)(GC.getImprovementInfo(pPlot->getImprovementType()).getImprovementPillage()));
			}
			else
			{
				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_FAIL_DESTROY_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMB_FAILS", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE());
			}
		}
[COLOR="Red"]		else
		{
			if (pTargetPlot->getRouteType() == NO_ROUTE)
			{
				pPlot->setRouteType(NO_ROUTE)));
			}		
		}
[/COLOR]	}

This way if there is no improvement, you automatically destroy the road. You could include a chance to destroy if you wanna.
 
:) I just noticed it myself when you pointed it out. I ques I still got much to learn.
What does that isPermanent mean? And how would it look like if I want it to destroy the road when it destroys the improvement? Should I add it like this:
Code:
	else
	{
		if (pPlot->getImprovementType() != NO_IMPROVEMENT)
		{
			if (GC.getGameINLINE().getSorenRandNum(airBombCurrRate(), "Air Bomb - Offense") >=
					GC.getGameINLINE().getSorenRandNum(GC.getImprovementInfo(pPlot->getImprovementType()).getAirBombDefense(), "Air Bomb - Defense"))
			{
[COLOR="Red"]				if (pTargetPlot->getRouteType() == NO_ROUTE)
				{
					pPlot->setRouteType(NO_ROUTE)));
				}[/COLOR]

				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_DESTROYED_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGE", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pPlot->getX_INLINE(), pPlot->getY_INLINE());

				if (pPlot->isOwned())
				{
					szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_IMP_WAS_DESTROYED", GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide(), getNameKey(), getVisualCivAdjective(pPlot->getTeam()));
					gDLL->getInterfaceIFace()->addMessage(pPlot->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGED", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE(), true, true);
				}

				pPlot->setImprovementType((ImprovementTypes)(GC.getImprovementInfo(pPlot->getImprovementType()).getImprovementPillage()));
			}
			else
			{
				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_FAIL_DESTROY_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMB_FAILS", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE());
			}
		}
		else
		{
			if (pTargetPlot->getRouteType() == NO_ROUTE)
			{
				pPlot->setRouteType(NO_ROUTE)));
			}		
		}
	}
 
Actually little fix, shouldn't this:
Code:
		else
		{
			if (pTargetPlot->getRouteType() == NO_ROUTE)
			{
				pPlot->setRouteType(NO_ROUTE)));
			}		
		}
be like this:
Code:
		else
		{
			[COLOR="Red"]if (pPlot->getRouteType() == NO_ROUTE)[/COLOR]
			{
				pPlot->setRouteType(NO_ROUTE)));
			}		
		}
It uses pPlot instead of pTargetPlot:
Code:
bool CvUnit::airBomb(int iX, int iY)
{
	CvCity* pCity;
	CvPlot* pPlot;
	CvWString szBuffer;

	if (!canAirBombAt(plot(), iX, iY))
	{
		return false;
	}

	pPlot = GC.getMapINLINE().plotINLINE(iX, iY);

	if (!isEnemy(pPlot->getTeam()))
	{
		getGroup()->groupDeclareWar(pPlot, true);
	}

EDIT: Wait a second!
Code:
 			if (pPlot->getRouteType() == NO_ROUTE)
			{
				pPlot->setRouteType(NO_ROUTE)));
			}
Don't you check there if the route type is null and change it to null?

EDIT2: And why there are three )s after NO_ROUTE?
 
Ok, now I got strange error when trying to compile the DLL.
'CvPlot::setRouteType' : function does not take 1 arguments
It doesn't like this:
Code:
				if (pPlot->getRouteType() != NO_ROUTE)
				{
					[COLOR="Red"]pPlot->setRouteType(NO_ROUTE);[/COLOR]
				}
How should I put it then? Just in case here's my whole code:
Spoiler :
Code:
bool CvUnit::canAirBombAt(const CvPlot* pPlot, int iX, int iY) const
{
	CvCity* pCity;
	CvPlot* pTargetPlot;

	if (!canAirBomb(pPlot))
	{
		return false;
	}

	pTargetPlot = GC.getMapINLINE().plotINLINE(iX, iY);

	if (plotDistance(pPlot->getX_INLINE(), pPlot->getY_INLINE(), pTargetPlot->getX_INLINE(), pTargetPlot->getY_INLINE()) > airRange())
	{
		return false;
	}

	if (pTargetPlot->isOwned())
	{
		if (!potentialWarAction(pTargetPlot))
		{
			return false;
		}
	}

	pCity = pTargetPlot->getPlotCity();

	if (pCity != NULL)
	{
		if (!(pCity->isBombardable(this)))
		{
			return false;
		}
	}
	else
	{
		if (pTargetPlot->getImprovementType() == NO_IMPROVEMENT)
		{
/*************************************************************************************************/
/**Can bomb routes                        05/12/09                                NotSoGood      */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
			if (pTargetPlot->getRouteType() == NO_ROUTE)
			{
				return false;
			}
/*************************************************************************************************/
/**Can bomb routes                        END                                                    */
/*************************************************************************************************/
		}

		if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).isPermanent())
		{
/*************************************************************************************************/
/**Can bomb routes                        05/12/09                                NotSoGood      */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
			if (pTargetPlot->getRouteType() == NO_ROUTE)
			{
				return false;
			}
/*************************************************************************************************/
/**Can bomb routes                        END                                                    */
/*************************************************************************************************/
		}

		if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).getAirBombDefense() == -1)
		{
			return false;
		}
	}

	return true;
}


bool CvUnit::airBomb(int iX, int iY)
{
	CvCity* pCity;
	CvPlot* pPlot;
	CvWString szBuffer;

	if (!canAirBombAt(plot(), iX, iY))
	{
		return false;
	}

	pPlot = GC.getMapINLINE().plotINLINE(iX, iY);

	if (!isEnemy(pPlot->getTeam()))
	{
		getGroup()->groupDeclareWar(pPlot, true);
	}

	if (!isEnemy(pPlot->getTeam()))
	{
		return false;
	}

	if (interceptTest(pPlot))
	{
		return true;
	}

	pCity = pPlot->getPlotCity();

	if (pCity != NULL)
	{
		pCity->changeDefenseModifier(-airBombCurrRate());

		szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_DEFENSES_REDUCED_TO", pCity->getNameKey(), pCity->getDefenseModifier(false), getNameKey());
		gDLL->getInterfaceIFace()->addMessage(pCity->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMBARDED", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pCity->getX_INLINE(), pCity->getY_INLINE(), true, true);

		szBuffer = gDLL->getText("TXT_KEY_MISC_ENEMY_DEFENSES_REDUCED_TO", getNameKey(), pCity->getNameKey(), pCity->getDefenseModifier(false));
		gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMBARD", MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pCity->getX_INLINE(), pCity->getY_INLINE());
	}
	else
	{
		if (pPlot->getImprovementType() != NO_IMPROVEMENT)
		{
			if (GC.getGameINLINE().getSorenRandNum(airBombCurrRate(), "Air Bomb - Offense") >=
					GC.getGameINLINE().getSorenRandNum(GC.getImprovementInfo(pPlot->getImprovementType()).getAirBombDefense(), "Air Bomb - Defense"))
			{
/*************************************************************************************************/
/**Can bomb routes                        05/12/09                                NotSoGood      */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
				if (pPlot->getRouteType() != NO_ROUTE)
				{
					pPlot->setRouteType(NO_ROUTE);
				}
/*************************************************************************************************/
/**Can bomb routes                        END                                                    */
/*************************************************************************************************/
				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_DESTROYED_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGE", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pPlot->getX_INLINE(), pPlot->getY_INLINE());

				if (pPlot->isOwned())
				{
					szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_IMP_WAS_DESTROYED", GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide(), getNameKey(), getVisualCivAdjective(pPlot->getTeam()));
					gDLL->getInterfaceIFace()->addMessage(pPlot->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGED", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE(), true, true);
				}

				pPlot->setImprovementType((ImprovementTypes)(GC.getImprovementInfo(pPlot->getImprovementType()).getImprovementPillage()));
			}
			else
			{
				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_FAIL_DESTROY_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMB_FAILS", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE());
			}
		}
/*************************************************************************************************/
/**Can bomb routes                        05/12/09                                NotSoGood      */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
		else
		{
			if (pPlot->getRouteType() != NO_ROUTE)
			{
				pPlot->setRouteType(NO_ROUTE);
			}
		}
/*************************************************************************************************/
/**Can bomb routes                        END                                                    */
/*************************************************************************************************/
	}

	setReconPlot(pPlot);

	setMadeAttack(true);
	changeMoves(GC.getMOVE_DENOMINATOR());

	if (pPlot->isActiveVisible(false))
	{
		CvAirMissionDefinition kAirMission;
		kAirMission.setMissionType(MISSION_AIRBOMB);
		kAirMission.setUnit(BATTLE_UNIT_ATTACKER, this);
		kAirMission.setUnit(BATTLE_UNIT_DEFENDER, NULL);
		kAirMission.setDamage(BATTLE_UNIT_DEFENDER, 0);
		kAirMission.setDamage(BATTLE_UNIT_ATTACKER, 0);
		kAirMission.setPlot(pPlot);
		kAirMission.setMissionTime(GC.getMissionInfo((MissionTypes)MISSION_AIRBOMB).getTime() * gDLL->getSecsPerTurn());

		gDLL->getEntityIFace()->AddMission(&kAirMission);
	}

	if (isSuicide())
	{
		kill(true);
	}

	return true;
}
 
The reason is pretty much what it says: setRouteType takes 2 arguments, not 1. The second one is a boolean to tell it whether or not to recalculate plot groups. This seems to be "true" in most cases.
 
As a non programmer, that argument stuff is hard for me, and sometimes I can't figure it out either. But the way I usually get it is to look at an example of the function being used somewhere else, I can then often figure out how to add in the missing argument. So take a look at another example of setRouteType in the code, and see if you can't use the same format in your code.
 
Sorry for the errors, I should have posted in pseudocode since I was just cut/pasting with what was already in the thread at the time.

isPermanent is a tag in ImprovementInfos used to mark improvements which shouldn't be able to be pillaged or built over.

And as stated by the others, setRouteType(NO_ROUTE,true) ought to work for you.
 
As a non programmer, that argument stuff is hard for me, and sometimes I can't figure it out either. But the way I usually get it is to look at an example of the function being used somewhere else, I can then often figure out how to add in the missing argument. So take a look at another example of setRouteType in the code, and see if you can't use the same format in your code.

Yeah, I knew exactly what you meant. Before I took an intro to programming class, I really didn't understand arguments at all. But, once I was forced to write a few functions for myself, I quickly understood their significance. Let's see if I can explain it in simple of terms as possible.

Let's say you want to, for whatever reason, write a function compares two integers and returns the larger one. (So, if it compared 2 and 3, it would give 3 as the answer...aka the result)

It would be a "Int" function, because the datatype of the result is an integer. So, it might look like this:
Code:
int compareForMaxValue(int i, int j)
{
       if (i > j)
             return i;
return j;
}

The two "parameters" are integers, i and j. The names do not matter. Now, if I wanted to use this function and compare to see whether 3 or 5 was a larger value, I would need to give the function 3 and 5, so it could compare.

Code:
maxValue = compareForMaxValue(3,5);

In this case, maxValue would become 5.

Now, you might ask, what use is this function? Actually, this function is used 100's of time in civ, but you know it as a different name, std::max.

If you can understand some basic programming and begin to understand some parameters, it will help your civ modding immensely.
 
Sorry for the errors, I should have posted in pseudocode since I was just cut/pasting with what was already in the thread at the time.

isPermanent is a tag in ImprovementInfos used to mark improvements which shouldn't be able to be pillaged or built over.

And as stated by the others, setRouteType(NO_ROUTE,true) ought to work for you.

:) It doesn't matter. It's good that they were spotted.
Now I'm going to test the code. I hope it'll work...

EDIT: Hmm weird. The game crashes imediately when I try to bomb routes. :confused:
I'll try to debug it.

EDIT2: The route is destroyed when you bomb improvements. But when you try to bomb only route, it crashes. Why?
 
Isn't the problem in the second function. Because it crashes when I just move the pointer or something to a tile. No bombing, only testing if you can bomb. And it occurs only on tiles that have only route no improvement. Here's all changes I have made:
Code:
bool CvUnit::canAirBombAt(const CvPlot* pPlot, int iX, int iY) const
{
	CvCity* pCity;
	CvPlot* pTargetPlot;

	if (!canAirBomb(pPlot))
	{
		return false;
	}

	pTargetPlot = GC.getMapINLINE().plotINLINE(iX, iY);

	if (plotDistance(pPlot->getX_INLINE(), pPlot->getY_INLINE(), pTargetPlot->getX_INLINE(), pTargetPlot->getY_INLINE()) > airRange())
	{
		return false;
	}

	if (pTargetPlot->isOwned())
	{
		if (!potentialWarAction(pTargetPlot))
		{
			return false;
		}
	}

	pCity = pTargetPlot->getPlotCity();

	if (pCity != NULL)
	{
		if (!(pCity->isBombardable(this)))
		{
			return false;
		}
	}
	else
	{
		if (pTargetPlot->getImprovementType() == NO_IMPROVEMENT)
		{
[COLOR="Red"]/*************************************************************************************************/
/**Can bomb routes                        05/12/09                                NotSoGood      */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
			if (pTargetPlot->getRouteType() == NO_ROUTE)
			{
				return false;
			}
/*************************************************************************************************/
/**Can bomb routes                        END                                                    */
/*************************************************************************************************/[/COLOR]
		}

		if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).isPermanent())
		{
			return false;
		}

		if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).getAirBombDefense() == -1)
		{
			return false;
		}
	}

	return true;
}


bool CvUnit::airBomb(int iX, int iY)
{
	CvCity* pCity;
	CvPlot* pPlot;
	CvWString szBuffer;

	if (!canAirBombAt(plot(), iX, iY))
	{
		return false;
	}

	pPlot = GC.getMapINLINE().plotINLINE(iX, iY);

	if (!isEnemy(pPlot->getTeam()))
	{
		getGroup()->groupDeclareWar(pPlot, true);
	}

	if (!isEnemy(pPlot->getTeam()))
	{
		return false;
	}

	if (interceptTest(pPlot))
	{
		return true;
	}

	pCity = pPlot->getPlotCity();

	if (pCity != NULL)
	{
		pCity->changeDefenseModifier(-airBombCurrRate());

		szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_DEFENSES_REDUCED_TO", pCity->getNameKey(), pCity->getDefenseModifier(false), getNameKey());
		gDLL->getInterfaceIFace()->addMessage(pCity->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMBARDED", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pCity->getX_INLINE(), pCity->getY_INLINE(), true, true);

		szBuffer = gDLL->getText("TXT_KEY_MISC_ENEMY_DEFENSES_REDUCED_TO", getNameKey(), pCity->getNameKey(), pCity->getDefenseModifier(false));
		gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMBARD", MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pCity->getX_INLINE(), pCity->getY_INLINE());
	}
	else
	{
		if (pPlot->getImprovementType() != NO_IMPROVEMENT)
		{
			if (GC.getGameINLINE().getSorenRandNum(airBombCurrRate(), "Air Bomb - Offense") >=
					GC.getGameINLINE().getSorenRandNum(GC.getImprovementInfo(pPlot->getImprovementType()).getAirBombDefense(), "Air Bomb - Defense"))
			{
[COLOR="red"]/*************************************************************************************************/
/**Can bomb routes                        05/12/09                                NotSoGood      */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
				if (pPlot->getRouteType() != NO_ROUTE)
				{
					pPlot->setRouteType(NO_ROUTE,true);
				}
/*************************************************************************************************/
/**Can bomb routes                        END                                                    */
/*************************************************************************************************/[/COLOR]
				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_DESTROYED_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGE", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pPlot->getX_INLINE(), pPlot->getY_INLINE());

				if (pPlot->isOwned())
				{
					szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_IMP_WAS_DESTROYED", GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide(), getNameKey(), getVisualCivAdjective(pPlot->getTeam()));
					gDLL->getInterfaceIFace()->addMessage(pPlot->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGED", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE(), true, true);
				}

				pPlot->setImprovementType((ImprovementTypes)(GC.getImprovementInfo(pPlot->getImprovementType()).getImprovementPillage()));
			}
			else
			{
				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_FAIL_DESTROY_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMB_FAILS", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE());
			}
		}
[COLOR="red"]/*************************************************************************************************/
/**Can bomb routes                        05/12/09                                NotSoGood      */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
		else
		{
			if (pPlot->getRouteType() != NO_ROUTE)
			{
				pPlot->setRouteType(NO_ROUTE,true);
			}
		}
/*************************************************************************************************/
/**Can bomb routes                        END                                                    */
/*************************************************************************************************/[/COLOR]
	}

	setReconPlot(pPlot);

	setMadeAttack(true);
	changeMoves(GC.getMOVE_DENOMINATOR());

	if (pPlot->isActiveVisible(false))
	{
		CvAirMissionDefinition kAirMission;
		kAirMission.setMissionType(MISSION_AIRBOMB);
		kAirMission.setUnit(BATTLE_UNIT_ATTACKER, this);
		kAirMission.setUnit(BATTLE_UNIT_DEFENDER, NULL);
		kAirMission.setDamage(BATTLE_UNIT_DEFENDER, 0);
		kAirMission.setDamage(BATTLE_UNIT_ATTACKER, 0);
		kAirMission.setPlot(pPlot);
		kAirMission.setMissionTime(GC.getMissionInfo((MissionTypes)MISSION_AIRBOMB).getTime() * gDLL->getSecsPerTurn());

		gDLL->getEntityIFace()->AddMission(&kAirMission);
	}

	if (isSuicide())
	{
		kill(true);
	}

	return true;
}
 
Try to maintain the original code commented out so you can easily undo your changes to test things like this. I don't see directly how this set of changes is crashing. so the quick approach is to undo them one at a time to see if that fixes it.
 
Code:
		if (pTargetPlot->getImprovementType() != NO_IMPROVEMENT)
		{
			if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).isPermanent())
			{
				return false;
			}

			if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).getAirBombDefense() == -1)
			{
				return false;
			}
		}
		//there is no improvement, but is there a road?
		else
		{
			if (pTargetPlot->getRouteType() == NO_ROUTE)
			{
				return false;
			}
		}

this should work.

your code crashes because when you use if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).isPermanent()) you need to make sure that getImprovementType isn't NO_IMPROVEMENT.
 
To expand a little on Sephi's answer, the original code probably looked like this:

Code:
if there is no improvement
    [B][COLOR="Red"]return false[/COLOR][/B]
if improvement is permanent
    ...

The second if test above assumes that there is an improvement, and because the if test immediately above it exits the function if there isn't one, the assumption is safe. By changing the red line to exit the function only if there is no route, you invalidate the assumption below it, causing a crash by calling the isPermanent() function on a NULL object.

You can use Sephi's fix, or you can use the following:

Code:
if (pTargetPlot->getImprovementType() == NO_IMPROVEMENT)
{
	// can bomb non-improved tiles only if there is a route
	[B][COLOR="Red"]return pTargetPlot->getRouteType() != NO_ROUTE;[/COLOR][/B]
}

if (GC.getImprovementInfo(pTargetPlot->getImprovementType()).isPermanent())
{
	return false;
}

The red line returns true if there is a route or false if not. Since we know at this point that there is no improvement, there is nothing left to check. The advantage to this solution is that it changes less of the original code.
 
Thanks for help. That was pretty bad mistake. I should have looked it more precisely. I'll try to compile it again.

EDIT: Jay, it works! :woohoo: Thanks.

Here's another question: How hard would it be to add a text message to tell you that you destroyed a route? I think those szBuffer lines add the texts but how do they work?
 
I got the text message work myself. It wasn't so hard after all. I attached a screenshot of it. Here's also my code:
Spoiler :
Code:
	else
	{
		if (pPlot->getImprovementType() != NO_IMPROVEMENT)
		{
			if (GC.getGameINLINE().getSorenRandNum(airBombCurrRate(), "Air Bomb - Offense") >=
					GC.getGameINLINE().getSorenRandNum(GC.getImprovementInfo(pPlot->getImprovementType()).getAirBombDefense(), "Air Bomb - Defense"))
			{
/*************************************************************************************************/
/**Can bomb routes                        05/12/09                                NotSoGood      */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
				if (pPlot->getRouteType() != NO_ROUTE)
				{
					pPlot->setRouteType(NO_ROUTE,true);
				}
/*************************************************************************************************/
/**Can bomb routes                        END                                                    */
/*************************************************************************************************/
				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_DESTROYED_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGE", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pPlot->getX_INLINE(), pPlot->getY_INLINE());

				if (pPlot->isOwned())
				{
					szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_IMP_WAS_DESTROYED", GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide(), getNameKey(), getVisualCivAdjective(pPlot->getTeam()));
					gDLL->getInterfaceIFace()->addMessage(pPlot->getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGED", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE(), true, true);
				}

				pPlot->setImprovementType((ImprovementTypes)(GC.getImprovementInfo(pPlot->getImprovementType()).getImprovementPillage()));
			}
			else
			{
				szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_FAIL_DESTROY_IMP", getNameKey(), GC.getImprovementInfo(pPlot->getImprovementType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_BOMB_FAILS", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pPlot->getX_INLINE(), pPlot->getY_INLINE());
			}
		}
/*************************************************************************************************/
/**Can bomb routes                        07/12/09                                NotSoGood      */
/**                                                                                              */
/**                                                                                              */
/*************************************************************************************************/
		else
		{
			if (pPlot->getRouteType() != NO_ROUTE)
			{
				[COLOR="Red"]szBuffer = gDLL->getText("TXT_KEY_MISC_YOU_UNIT_DESTROYED_ROUTE", getNameKey(), GC.getRouteInfo(pPlot->getRouteType()).getTextKeyWide());
				gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_PILLAGE", MESSAGE_TYPE_INFO, getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pPlot->getX_INLINE(), pPlot->getY_INLINE());[/COLOR]

				pPlot->setRouteType(NO_ROUTE,true);
			}
		}
/*************************************************************************************************/
/**Can bomb routes                        END                                                    */
/*************************************************************************************************/
	}
 
I like the idea of this modcomp. Does anyone know if the AI would automatically "understand" the change with it's current bombing logic?
 
I don't see how it could. There must be a function--something like CvPlot::AI_bombValue()--that calculates a number measuring how valuable a single plot is as a bombing target. Since Firaxis chose to make routes immune to bombing, I doubt they included the plot's route in the calculation.
 
I don't see how it could. There must be a function--something like CvPlot::AI_bombValue()--that calculates a number measuring how valuable a single plot is as a bombing target. Since Firaxis chose to make routes immune to bombing, I doubt they included the plot's route in the calculation.

Ugh, that sounds calculation intense, especially if you wanted to make a route that was the only path to a particular city more valuable than others, then add in routes connecting bonues, and routes near borders, and... I'm sure theirs more. :(
 
Top Bottom