Blockade not working?

Joined
Jun 7, 2008
Messages
6,123
Location
Just wonder...
Hello guys, while playing A New Dawn recently someone reported that blockade isn't working. I've checked myself and I've seen it's true. Since I've imported most of the code in AND2 from C2C dll, I've checked C2C to see if that bug has been solved here. But a quick test has revealed that the problem exists here in C2C too. Hasn't anyone ever noticed it? A savegame is attached if you want to try; C2C ver33; I've use WB a bit to speed up the test and you can see some fusion destroyers surrounding a croatian city; while the tiles appear blockaded, trade is still being collected inside the city (visible via espionage) and resources still reach the city. Any idea?
 

Attachments

  • C2C-Corrado a. C. - 35380.CivBeyondSwordSave
    1.2 MB · Views: 310
Guys, I've seen 6 views to my savegame; can at least some of you who have tried my save tell me if it's just me or if it's really a bug? I know sometimes C2C and AND2 conflict with each other when both are installed and you switch playing from one mod to the other, so I'd like to know if the problem is there for other people as well or if it's just me. Thank you. ;)
 
I'm seeing it as well - all the fusion ships are blockading, and the AI is still getting fish and crab resources in his cities.


It's happening in my current game too.
I'm not at war with the Ethopian. I place some Privateers near their city on a two-tile large island, and run a blockade mission. All trade routes and external resources are cut off.

Now I declare war on him, and place some Iron Frigates there and have them blockade the city. The city is still getting off-shore trade routes and resources despite there being frigates blockading it.


So, could it be only Privateers have the ability to deny a city overseas trade routes and resources when blockading?
 
More on the subject: it looks like Privateers can blockade trade but not resources, and only during peace-time. When at war, they can't block anything. Other ships can't blockade at all, neither resources nor trade, not when at war, nor at peace. I'm going to test rev5881, before changes were made to blockade to solve the bug of ghost blockade caused by dead AI.

Rezca, are you sure your Privateers block resources too? I can't load your save, which rev are you using?
 
preV34, build 6702

I was mistaken when I said that it was blocking resources from entering too, sorry.
So they can't block during wartime either? Only during peacetime?

I wonder if this was intentional - like to prevent coastal cities from starving uncontrollably because of a lone galley or an island city from being rendered useless by being cut off from the mainland during a war... Leaving the naval harassment to privateers only...?
 
preV34, build 6702

I was mistaken when I said that it was blocking resources from entering too, sorry.
So they can't block during wartime either? Only during peacetime?

I wonder if this was intentional - like to prevent coastal cities from starving uncontrollably because of a lone galley or an island city from being rendered useless by being cut off from the mainland during a war... Leaving the naval harassment to privateers only...?

Well, a few more test and that's what I see:
- Every ship (privateers and others) prevents the blocked city to use its adjacent squares (which makes me think that no, it wasn't intentional to leave things to privateers only) Correction: privateers can prevent tiles adjacent to the blocked city from being used, always; other ships can do it but only at wartime (and that's ok, I'd say)
- Only Privateers can stop trading networks and only during peacetime (during wartime, trade networks still work)
- No ship, not Privateers nor other ships can stop resources by blockading a city.

Definetely something to look into, I'd say.
 
How odd... I wonder what caused this to happen?

I've tried with revision 5881, before latest blockade changes by Koshling (that change about dead players still blockading cities), and there's no difference, the bug is still there. I suspect it's there since a very long time because I remember trying a very old C2C revision and the problem was there already. The oldest revision I've installed now is rev3034 (July 2012), I'll try that one and see what happens.
 
The question is, is it a bug or was it done intentional this way back then.

If it was intentional it wasn't made in C2C, it was made back in the A New Dawn days. And I don't see why it should be intentional: why should privateers blockade only during peacetime and there would be no way to block a city during war time?
And in vanilla Civ you can block resources too, which looks quite normal to me, while in AND/C2C you can't block resources, ever.
 
This must be changed because all pirate ships sould always be able to blockade and the other ships just during war. Also ressources must be blocked too. I would do this change but right now i'am a bit busy in RL and i want to finish my current projects.
 
This must be changed because all pirate ships sould always be able to blockade and the other ships just during war. Also ressources must be blocked too. I would do this change but right now i'am a bit busy in RL and i want to finish my current projects.

I'm working on the dll code myself to see if I can fix it, but had no luck until now. If I succeed in fixing it, I'll let you know. If I can't make it, well, I guess I'll need help by C2C team (again). :)
 
More on this issue; AND was working up to AND1.76beta5, so I'm testing intermediate revisions to pinpoint where blockade troubles started, I'll let you know if I find something. It looks like the error was made in C2C early stages and imported in AND back in 2011. Hopefully I'll pinpoint the part of the code causing troubles and I'll post a solution here as well if I can fix it.
 
OK, I've been able to discover that troubles with blockades started in AND rev567 (rev566 is working); code was imported there from C2C rev1531, Koshling's log reads

[*]Reworked the plot group system (trade networks) to use less memory. Also reduces the size of save games somewhat and (in most circumstances) runs a bit faster

Involved files should be cvplotgroup.cpp, cvplotgroup.h cvmap.cpp, and a single line in cvplayer.cpp (I'm making more test to narrow research field).
I'll see what I can do if I'm able to fix it (that is, if the error isn't already plain to Koshling who wrote that code).

Edit: mmm, it looks like when Afforess worked on AND he's made some partial update, so problem could be in rev567 or 568 in AND, which could mean C2C rev up to rev1577. No, it should definetely be rev1531. More will follow.
 
I'm sure Koshling would be able to offer you some advice, but he's on holidays for another month or something.
 
I can take a look at it - what's the file and function it's in? Give me whatever you've been able to figure out about it and I can take a look. My own files are in the midst of a huge project so I can't easily directly debug anything at the moment (aside from my own project - ulf)
 
I can take a look at it - what's the file and function it's in? Give me whatever you've been able to figure out about it and I can take a look. My own files are in the midst of a huge project so I can't easily directly debug anything at the moment (aside from my own project - ulf)

Rev1531 had some big changes, so I guess there's not a single function as Koshling rewrote trade network code in that revision; involed files are cvplotgroup.cpp, cvplotgroup.h cvmap.cpp, and a single line in cvplayer.cpp. Here's what I've found:

This was cvplotgroup.h before changes

Code:
#pragma once

// plotGroup.h

#ifndef CIV4_PLOT_GROUP_H
#define CIV4_PLOT_GROUP_H

//#include "CvStructs.h"
#include "LinkedList.h"

typedef struct
{
	int resourceNodesHash;
	int allNodesHash;
} plotGroupHashInfo;

typedef struct
{
	plotGroupHashInfo	hashInfo;
	int					groupGenerationNumber;
} plotGroupCheckInfo;

class CvPlot;
class CvPlotGroup
{
friend class CvPlot;

public:

	CvPlotGroup();
	virtual ~CvPlotGroup();

	void init(int iID, PlayerTypes eOwner, CvPlot* pPlot, bool bRecalculateBonuses = true);
	void uninit();
	void reset(int iID = 0, PlayerTypes eOwner = NO_PLAYER, bool bConstructorCall=false);

	void addPlot(CvPlot* pPlot, bool bRecalculateBonuses);
	void removePlot(CvPlot* pPlot, bool bRecalculateBonuses = true);
	void recalculatePlots();														

	int getID() const;
	void setID(int iID);

	PlayerTypes getOwner() const;
//#ifdef _USRDLL
	inline PlayerTypes getOwnerINLINE() const
	{
		return m_eOwner;
	}
//#endif
	int getNumBonuses(BonusTypes eBonus) const;
	int getNumFreeTradeRegionBuildings(BuildingTypes eBuilding) const;
	bool hasBonus(BonusTypes eBonus);										
	void changeNumBonuses(BonusTypes eBonus, int iChange);
	void changeNumFreeTradeRegionBuildings(BuildingTypes eBuilding, int iChange);

	void insertAtEndPlots(XYCoords xy);			
	CLLNode<XYCoords>* deletePlotsNode(CLLNode<XYCoords>* pNode);
	CLLNode<XYCoords>* nextPlotsNode(CLLNode<XYCoords>* pNode);
	int getLengthPlots();
	int getNumCities(void);
	CLLNode<XYCoords>* headPlotsNode();

	// for serialization
	void read(FDataStreamBase* pStream);
	void write(FDataStreamBase* pStream);
	//	Calculate the hashes after a fresh game load
	void RecalculateHashes();
	void Validate(void);

private:
	int m_sessionAllocSeq;
	static int m_allocationSeqForSession;

protected:

	int m_iID;

	PlayerTypes m_eOwner;

	int* m_paiNumBonuses;
	int* m_paiNumFreeTradeRegionBuildings;
	mutable int m_numCities;

	plotGroupHashInfo m_zobristHashes;
						//	XOR of the zobrist contributions from all
						//	constituent plots 

	CLinkList<XYCoords> m_plots;
};

#endif


and this is after Koshling changed it

Code:
#pragma once

// plotGroup.h

#ifndef CIV4_PLOT_GROUP_H
#define CIV4_PLOT_GROUP_H

//#include "CvStructs.h"
#include "LinkedList.h"

typedef struct
{
	int resourceNodesHash;
	int allNodesHash;
} plotGroupHashInfo;

typedef struct
{
	plotGroupHashInfo	hashInfo;
	int					groupGenerationNumber;
} plotGroupCheckInfo;

class CvPlot;
class CvPlotGroup
{
friend class CvPlot;

public:

	CvPlotGroup();
	virtual ~CvPlotGroup();

	void init(int iID, PlayerTypes eOwner, CvPlot* pPlot, bool bRecalculateBonuses = true);
	void uninit();
	void reset(int iID = 0, PlayerTypes eOwner = NO_PLAYER, bool bConstructorCall=false);

	void addPlot(CvPlot* pPlot, bool bRecalculateBonuses);
	void removePlot(CvPlot* pPlot, bool bRecalculateBonuses = true);
	void recalculatePlots();														

	int getID() const;
	void setID(int iID);

	PlayerTypes getOwner() const;
//#ifdef _USRDLL
	inline PlayerTypes getOwnerINLINE() const
	{
		return m_eOwner;
	}
//#endif
	int getNumBonuses(BonusTypes eBonus) const;
	int getNumFreeTradeRegionBuildings(BuildingTypes eBuilding) const;
	bool hasBonus(BonusTypes eBonus);										
	void changeNumBonuses(BonusTypes eBonus, int iChange);
	void changeNumFreeTradeRegionBuildings(BuildingTypes eBuilding, int iChange);

	int getNumCities(void);

	// for serialization
	void read(FDataStreamBase* pStream);
	void write(FDataStreamBase* pStream);
	//	Calculate the hashes after a fresh game load
	void RecalculateHashes();
	void Validate(void);

	inline int getLengthPlots() { return m_numPlots; }

	void mergeIn(CvPlotGroup* from, bool bRecalculateBonuses);
	static void colorRegion(CvPlot* pStartPlot, PlayerTypes eOwner);

private:
	CvPlot* getRepresentativePlot(void) const;
	void plotEnumerator(bool (*pfFunc)(CvPlotGroup* onBehalfOf, CvPlot*, void*), void* param);
	static CvPlotGroup* colorRegionInternal(CvPlot* pPlot, PlayerTypes eOwner, CvPlotGroup* pPlotGroup);

	int m_sessionAllocSeq;
	static int m_allocationSeqForSession;

protected:

	int m_iID;

	PlayerTypes m_eOwner;

	int* m_paiNumBonuses;
	int* m_paiNumFreeTradeRegionBuildings;
	mutable int m_seedPlotX;
	mutable int m_seedPlotY;

	plotGroupHashInfo m_zobristHashes;
						//	XOR of the zobrist contributions from all
						//	constituent plots 
public:
	int m_numPlots;
	mutable int m_numCities;
	//CLinkList<XYCoords> m_plots;
};

#endif

As you can see there are changes after changeNumFreeTradeRegionBuildings; of course these changes are reflected in cvplotgroup.cpp

cvmap.cpp was changed from

Code:
void CvMap::combinePlotGroups(PlayerTypes ePlayer, CvPlotGroup* pPlotGroup1, CvPlotGroup* pPlotGroup2, bool bRecalculateBonuses)
{
	CLLNode<XYCoords>* pPlotNode;
	CvPlotGroup* pNewPlotGroup;
	CvPlotGroup* pOldPlotGroup;
	CvPlot* pPlot;

	FAssertMsg(pPlotGroup1 != NULL, "pPlotGroup is not assigned to a valid value");
	FAssertMsg(pPlotGroup2 != NULL, "pPlotGroup is not assigned to a valid value");

	if (pPlotGroup1 == pPlotGroup2)
	{
		return;
	}

	if (pPlotGroup1->getLengthPlots() > pPlotGroup2->getLengthPlots())
	{
		pNewPlotGroup = pPlotGroup1;
		pOldPlotGroup = pPlotGroup2;
	}
	else
	{
		pNewPlotGroup = pPlotGroup2;
		pOldPlotGroup = pPlotGroup1;
	}

	pPlotNode = pOldPlotGroup->headPlotsNode();
	while (pPlotNode != NULL)
	{
		pPlot = plotSorenINLINE(pPlotNode->m_data.iX, pPlotNode->m_data.iY);
		pNewPlotGroup->addPlot(pPlot, bRecalculateBonuses);
		pPlotNode = pOldPlotGroup->deletePlotsNode(pPlotNode);
	}
}

to

Code:
void CvMap::combinePlotGroups(PlayerTypes ePlayer, CvPlotGroup* pPlotGroup1, CvPlotGroup* pPlotGroup2, bool bRecalculateBonuses)
{
	CvPlotGroup* pNewPlotGroup;
	CvPlotGroup* pOldPlotGroup;

	FAssertMsg(pPlotGroup1 != NULL, "pPlotGroup is not assigned to a valid value");
	FAssertMsg(pPlotGroup2 != NULL, "pPlotGroup is not assigned to a valid value");

	if (pPlotGroup1 == pPlotGroup2)
	{
		return;
	}

	if (pPlotGroup1->getLengthPlots() > pPlotGroup2->getLengthPlots())
	{
		pNewPlotGroup = pPlotGroup1;
		pOldPlotGroup = pPlotGroup2;
	}
	else
	{
		pNewPlotGroup = pPlotGroup2;
		pOldPlotGroup = pPlotGroup1;
	}

	pNewPlotGroup->mergeIn(pOldPlotGroup, bRecalculateBonuses);
}

and there's a line changed in cvplayer.cpp inside void CvPlayer::updatePlotGroups

from

Code:
			pLoopPlot->updatePlotGroup(getID(), false);

to

Code:
			if ( pLoopPlot->getPlotGroup(getID()) == NULL )
			{
				CvPlotGroup::colorRegion(pLoopPlot, getID());
			}
			//pLoopPlot->updatePlotGroup(getID(), false);

I'm going to test these changes adding new code bit by bit to the last working code to see if I can pinpoint what's exactly causing troubles, but if you have any idea where to look, that could help a lot.
 
Top Bottom