DLL coding thread

Looks like the problem is the source module, not the M:C one. Try to pull that one and then push it before dealing with M:C.

What is the source module? It doesn't show up when I look to fetch more branches.
 
What is the source module? It doesn't show up when I look to fetch more branches.
Remember that we have two submodules called source and python. If you click on sourceDLL in directories, you control the source module. You need to pull and push that one too, remember ;)
Also you may want to branch that one too.
 
Remember that we have two submodules called source and python. If you click on sourceDLL in directories, you control the source module. You need to pull and push that one too, remember ;)
Also you may want to branch that one too.

I can push sourceDLL just fine actually. I just repulled and pushed it again, but when I push Medieval_Conquest I get the same error. :mad:
 
Ok, I managed go back and create a new branch before I started making changes. Somehow, (still haven't figured it out) all my changes ended up in the new branch. I pushed and all went fine.

Edit: Hmm, I had created the LimitedYields branch and merged the changes from LimitedResources and tried to push but got the error. Then I reverted LimitedYields back before the merge, pulled and pushed, and then set about to add my changes but they where already there. :confused:

The new Branch is labled LimitedYields and the sourceDLL is LimitedResources. The LimitedResources for Medieval_Conquest is the one I could not push.

I just tested it for my attached saved game and the crash happens at the same place so maybe you can look at it now, the file is attached.

However, now I get the same popup message that talks about the schema changes and I need to run the scrips (move_to_source, etc.). I am afraid to run them now as they may have been the cause of why I could no longer push?
 
I have found the cause of the crash. On load each city can loop plots around it and update yield production. The problem in this case is that player 9 has stolen plots from player 3. When player 3 loops the plots around his cities, he will loop through plots owned by player 9. CvPlot::updateYield() will work on the plot owner, which mean it will read from the player 9 array.

The cause of the crash is that a player will not allocate the array until that player is read. This mean data for player 9 is not yet available when player 3 loops plots.

The solution would be to simply not call CvPlot::updateYield() because it is called for all plots after the last player has been read. I just need to figure out a good way to make a function bool isGameLoading().
 
Edit: Well, uhh urmm, I pulled first this time and then was able to push.
Medieval Conquets still gave me this..
Push
$ git.exe push --porcelain --progress --recurse-submodules=check origin refs/heads/LimitedYields:refs/heads/LimitedYields
'LimitedYields' pushed: 1e3d565..c3a31a7
error: refs/remotes/origin/Fullerene does not point to a valid object!
error: refs/remotes/origin/GameFont does not point to a valid object!
Delta compression using up to 4 threads.
Total 16 (delta 15), reused 0 (delta 0)
remote: <Repository /git/p/colonizationmodcollection/Medieval_Conquest.git> refresh queued.

Below is original post...

Well, ok.. right back to having Push errors again. When I try to push the sourceDLL I get

$ git.exe push --porcelain --progress --recurse-submodules=check origin refs/heads/LimitedResources:refs/heads/LimitedResources
'LimitedResources' rejected (non-fast-forward)
Delta compression using up to 4 threads.
Total 14 (delta 13), reused 0 (delta 0)
error: insufficient permission for adding an object to repository database ./objects
fatal: failed to write object
error: unpack failed: unpack-objects abnormal exit
error: failed to push some refs to 'ssh://kailric@git.code.sf.net/p/colonizationmodcollection/sourceDLL'

When I try to push the Medieval_Conquest I get that one error again...

Push: refs/remotes/origin/Fullerene does not point to a valid object! refs/remotes/origin/GameFont does not point to a valid object! Aborting.
$ git.exe push --porcelain --progress --recurse-submodules=check origin refs/heads/LimitedYields:refs/heads/LimitedYields
refs/remotes/origin/Fullerene does not point to a valid object!
refs/remotes/origin/GameFont does not point to a valid object!
sourceDLL
The following submodule paths contain changes that can
not be found on any remote:
Please try
git push --recurse-submodules=on-demand
or cd to the path and use
git push
to push them to a remote.
Aborting.

I've done nothing different this time. I have just been editing the DLL and XML and then tried to push. Never used the pearl scripts.
 
error: refs/remotes/origin/Fullerene does not point to a valid object!
error: refs/remotes/origin/GameFont does not point to a valid object!
Somehow it looks like you have local references to those two, which do not match the ones on SF. The only way I can imagine that happening would be if somebody commits, pushes, edit history and pushes again. However who should have done that? Fullerene doesn't have permission to do so and who else would have done it to that branch? Clearly the cause is something else. If you did something locally, then it should be fixable to making a new clone.

Looks like your computer is haunted and seriously misbehave. Maybe you should send for a witch hunter.
 
I discovered on contingency that we didn't prepare for in the PlotGroups and that is declaring war and peace. If I have a plotgroup connected to a foreign village and I declare war on them the plotgroup remains. This should not be so; plots that belong to the enemy should be removed from the Plotgroup.

I added the below code to the Declare war and similar to the make peace functions but I am not sure if it is the best approach, what do you think?
Code:
for (iI = 0; iI < MAX_PLAYERS; iI++)
{
	CvPlayer& kPlayer = GET_PLAYER((PlayerTypes)iI);
	if ((kPlayer.getTeam() == getID()) || (kPlayer.getTeam() == eTeam))
	{
		//TKs Here we check to see if there are trade net works established with other Players, if so update the Trade Net works
		for (int iPlotGroup = 0; iPlotGroup < kPlayer.getNumPlotgroups(); iPlotGroup++)
		{
			for (int iCity = 0; iCity < kPlayer.getNumCitiesInPlotgroup(iPlotGroup); iCity++)
			{
				CvCity* pCity = kPlayer.getCity(iPlotGroup, iCity);
				CvPlotGroup* pPlotGroup = pCity->plot()->getPlotGroup((PlayerTypes)iI);
				if (pPlotGroup != NULL)
				{
					//pPlotGroup->recalculatePlots();
					CLLNode<XYCoords>* pPlotNode;
					pPlotNode = pPlotGroup->headPlotsNode();
					CvPlot* pPlot;
					while (pPlotNode != NULL)
					{
						pPlot = GC.getMapINLINE().plotSorenINLINE(pPlotNode->m_data.iX, pPlotNode->m_data.iY);

						FAssertMsg(pPlot != NULL, "Plot is not assigned a valid value");

						pPlot->updatePlotGroup((PlayerTypes)iI, true);
						pPlotNode = pPlotGroup->nextPlotsNode(pPlotNode);
					}
				}
			}
		}
		kPlayer.validateMissions();
	}
}
 
I can't remember offhand how I made it, but what comes to mind would be to clear all plotgroup data from all plots and then loop all cities to make them spread again. We do something like that on game load/start and if we have a generic code to recalculate all plotgroups, all we have to do is to call it. Using only one function makes it easier to avoid bugs.
 
I can't remember offhand how I made it, but what comes to mind would be to clear all plotgroup data from all plots and then loop all cities to make them spread again. We do something like that on game load/start and if we have a generic code to recalculate all plotgroups, all we have to do is to call it. Using only one function makes it easier to avoid bugs.

I believe the pPlotGroup->recalculatePlots() that I commented out in the code above would do this then. I've added data to Plotgroups and some of it needs to be saved, but it will all need to be recalculated when Plotgroups are rebuilt. There is code for combing plots groups in CvMaps, but this isn't called as you would expect when using the recalculatePlots(). I was having issues with my data not being transferred correctly from one plot group to another when rebuilding, but I think I solved this by having it recalculated when a plot is added to the plotgroup. The variables are all based on cities in the plotgroup so when ever a plot is added I check for a city and then add variables as needed.

Edit: I just looked up how Civ4 done this and in their declare war function they have the below code. I'll add that and see how it goes...

Code:
for (iI = 0; iI < MAX_PLAYERS; iI++)
{
	if (GET_PLAYER((PlayerTypes)iI).isAlive())
       {
		if ((GET_PLAYER((PlayerTypes)iI).getTeam() == getID()) || (GET_PLAYER((PlayerTypes)iI).getTeam() == eTeam))
		{
			GET_PLAYER((PlayerTypes)iI).updatePlotGroups();
		}
       }
}
 
Here is a coding question. What would be the best way to code in the ability for AI traders to buy yields? We would need to save...

-What Yields to Buy
-How much Gold they have to Spend
-What other values?

The Delivery of Yields will be easier to handle as there is code already for this so it isn't really an issue.
 
I added more function overloads to JIT arrays. They now understand == and != in addition to =, += and -=. They all do precisely what you would expect. Take two JIT arrays of the same type (say two yield arrays, both ints) and then it will loop through both arrays and perform the chosen function on each element pair.

The new operators are a bit different through as they return a bool. == stops the moment a pair differs and != is calling == and inverts the output.

Example usage: (which I have added to the source)
Array B = A;
(so stuff to A)
if (A != B) // true if content of A has changed. Useful for marking dirty and similar
B is presumably local and will be released at the end of the function.



I have been looking CvPlot::calculateNatureYield(). This function looks rather broken. It works on teams and whenever it needs player specific settings, it uses the team leader. This mean if I have a civic, which enables yield X, then I can't use it unless my team leader also have that civic. I'm thinking of rewriting it to be player specific instead of team specific.

Another thing I noticed is that this function is CPU hungry. I think I measured it to 5% of all AI CPU time in RaR. I have known that for a while, but now I got the idea that presumably most calls comes from placing units in cities and similar. In other words it should be possible to install a cache, which keeps track of the results for the owner. I will look into this later.
 
Nice work on that above, I'll have to see it in action to fully understand.

One thing I wanted to point out is the Builds that Workers are allowed are not cached to the CvPlayer, so in the Function bool CvPlayer::canBuild, we are still having to cycle through all Civics to determine if the Build is allowed. And actually that functions checks Routes and Improvements, so I guess Routes and Improvements would need to be cached.

I was going to just use BuildTypes when I first coded it but Builds came after Civics in the xml load order so I couldn't easily do that, so I switch to Improvements. But, Improvements are better in that some Improvements upgrade to better improvements, so essentially you could have Techs that unlock Improvement Upgrades, like Cattle Pasture upgrades to Cattle Farm after some many turns. There are no Techs that unlock Improvement Upgrades in M:C yet, but it would be a cool feature. Perhaps Techs could unlock the Cattle Farm, which when you get the Tech and the Upgrade Time has already expired you get your Cattle Farm.

Also, noticed a few more Civic cycles for buildings and messages like // TODO get rid of building loop by caching which buildings are allowed with current inventions. Didn't you add buildings in m_ba_AllowedBuildings(JIT_ARRAY_BUILDING, true)?
 
One thing I wanted to point out is the Builds that Workers are allowed are not cached to the CvPlayer, so in the Function bool CvPlayer::canBuild, we are still having to cycle through all Civics to determine if the Build is allowed. And actually that functions checks Routes and Improvements, so I guess Routes and Improvements would need to be cached.
I see warning lights coming on here. Such a cache could be time consuming to keep up to date. In fact it might be slower to use the cache than to just calculate on the fly.

I was going to just use BuildTypes when I first coded it but Builds came after Civics in the xml load order so I couldn't easily do that
XML now loads twice, first to get types, the second to actually load everything. This mean civics can refer to builds even though builds are read later. I totally got fed up with the load order and decided on fixing it once and for all. Now it can even make loops, like A->B->C->A, which were simply not possible in vanilla, regardless of load order. It's also possible to refer to something further down the same file now.

There are no Techs that unlock Improvement Upgrades in M:C yet, but it would be a cool feature. Perhaps Techs could unlock the Cattle Farm, which when you get the Tech and the Upgrade Time has already expired you get your Cattle Farm.
I think it wouldn't be hard to do. Also I would like two versions of this.
1: an improvement can't be build unless there is a certain improvement already (mk 1-> mk 2 with +1 production or whatever)
2: timer upgrades. RaR has this and presumably it can be copy pasted and then add check for civics.

Also, noticed a few more Civic cycles for buildings and messages like // TODO get rid of building loop by caching which buildings are allowed with current inventions. Didn't you add buildings in m_ba_AllowedBuildings(JIT_ARRAY_BUILDING, true)?
There are two of those and they are not identical. Also they appear to do more than just checking if a civic is available. I skipped those as I have yet to figure out their full purpose.
 
I see warning lights coming on here. Such a cache could be time consuming to keep up to date. In fact it might be slower to use the cache than to just calculate on the fly.

You'll have to explain this one, because I can't see how this is different than any of the ones you added already. All Builds are available right from the start, until you throw in the Civics, and it only checks in one place if you can build?


XML now loads twice, first to get types, the second to actually load everything.

Yeah, one of you best addition for Col programmers:goodjob:

I think it wouldn't be hard to do. Also I would like two versions of this.
1: an improvement can't be build unless there is a certain improvement already (mk 1-> mk 2 with +1 production or whatever)
Yeah, good idea, we don't have this yet.
2: timer upgrades. RaR has this and presumably it can be copy pasted and then add check for civics.

This is actually in vanilla code if we are talking about the same thing.

There are two of those and they are not identical. Also they appear to do more than just checking if a civic is available. I skipped those as I have yet to figure out their full purpose.

Ok, since I wrote them I'll check it out.
 
Back
Top Bottom