How do AI's handle items like Orthus' Axe?

I was able to get this working, partly, but there are still some problems. The beacon approach seems fine. I haven't coded all of it but units will pick up nearby items, and if they can't use them they will drop them in the nearest city.

I have traced out bCommunalProperty, and all it seems to do is hide the flag when the unit is displayed. That is working. I have traced out bNeverHostile, which goes a number of places.

1. In CvUnit::canJoinGroup, there is a test to return false if bNeverHostile. When I include this check, and a NeverHostile unit is created, a python exception is thrown, unidentifiable C++ exception at CvMainInterface.py line 1487 in updateSelectionButtons. I have not modded this file or anything related to selection buttons. When I remove the NeverHostile test in canJoinGroup, everything "appears" to be fine, but I am sure that test must be there for a reason. Any thoughts on what may cause this problem?

2. It seems that when a bNeverHostile unit is dropped in territory which is owned by any player, the unit is deleted at the end of the turn. It does not matter if there are any other units there or not. The dropped unit will persist fine on un-owned territory. I am not sure what could be doing this; any thoughts?

3. At a higher level, I am concerned about archipelago maps and my beacons. It may be that a unit is nearby, but on another island, and cannot reach. I am checking if the two plot().getArea()s match, and this is probably OK, but is there another way to tell in python if one unit can reach a certain plot? I have tried calling CyUnit.generatePath, but I cannot figure out what python to write for an "int *" argument.

4. Either to answer a beacon or to drop off an unusable item, a land unit may be required to travel by ocean. (This mod is not Dune Wars, no all-terrain units here.) Is there a way that a unit can request pickup by a transport? I guess that land units may get "stranded" for any reason, and they would need pickup. Once the transport arrives, I can probably figure out how to push its mission to go to the nearest useful drop-off point on the right island; but any help on how to *call* for transport would be appreciated.
 
Is there a way that a unit can request pickup by a transport? I guess that land units may get "stranded" for any reason, and they would need pickup. Once the transport arrives, I can probably figure out how to push its mission to go to the nearest useful drop-off point on the right island; but any help on how to *call* for transport would be appreciated.

Check out jdog's Better AI code. He has some stuff in there for picking up units with boats. I don't completely understand how it works, but I do see it being used successfully by the AI.
 
Possibly related info for point #2 above. My items have a combat strength of 0. I do not see why that should mean that they get destroyed if lying around in an owned plot. But, I see different behavior with the same code, changing the item to a combat strength of 1. The good news is, with strength 1 the item can now "survive" being dropped in an owned plot. I can pick it up, leave it there, come back later, and pick it up fine. So having a strength of 1 is an improvement from that standpoint.

However, now when the item drops, the unit which discovered it is ejected out of the plot. That is not fatal, but there is no good reason for it. If a unit is exploring a lair and finds an item, it should not get kicked out of the plot. The unit can move back into the plot with the item fine, so that part of NeverHostile is working.

Does this help any? I would like to have both, "survive in owned plot" and "does not eject discovering unit from plot". I am not sure which of the small changes for NeverHostile might be missing, or wrong; any suggestions?
 
Sorry, bCommunalProperty does most of the work it actually does in python as I recall. It is just a flag to look for on a unit which doesn't belong to you, and then you personally authorize actions which typically require ownership of the unit where you need them. So in this particular case, it is more of an idea for a tag than the precise function you require I suppose. The only thing it does in FF is allow a unit to cast spells which require a certain promotion on the tile (without the tag, the promotion must be on a unit which you own. I modified it so that you can use it on a tile where the promotion is on a unit you own, OR a communal unit).

1. CvUnit::canJoinGroup -- The test should only prevent grouping with other units who lack the same tag. I don't think it checks the unit to be allowed to group with itself, but maybe it does so during a conversion process or something. That may be the source of your issue there.

2. That'd be a bug, I think I recall people reporting it a while ago, apparently never cleared it up.

3. getArea is about the best approach you can use for that really. As I recall if a line of mountains splits a landmass it will assign a separate area to each side, so it should cover you for all cases.


Your second note on point 2 would be do to CvUnit::canCoexist or something along those lines I believe. It is forcing potential enemies away from one another. There ought to be a check against bNeverHostile which prevents a unit from ever being considered a potential enemy though which would help prevent the unit ejection issues. But as you stated, the unit can move back onto the tile without considering it an attack, so something may simply be checking who the owner of a unit is (though there should at least be a isVisible check to point out the right location to modify in setXY)
 
davidlallen said:
2. It seems that when a bNeverHostile unit is dropped in territory which is owned by any player, the unit is deleted at the end of the turn. It does not matter if there are any other units there or not. The dropped unit will persist fine on un-owned territory. I am not sure what could be doing this; any thoughts?
2. That'd be a bug, I think I recall people reporting it a while ago, apparently never cleared it up.
I have fixed this particular issue. If this is a bug in FF, you may want to make the fix also. It seems that at the end of every turn, CvPlot::verifyUnitValidPlot() is called to make sure units are in valid plots, and jump them if they are not. A non-combat unit (say, a worker), in an enemy owned plot, stacked with an enemy unit, is not valid according to this function. If the unit has a <Capture> it is captured, otherwise it is killed.

I made the following change in red.
Code:
if (pLoopUnit->atPlot(this))
{
	if (!(pLoopUnit->isCargo()))
	{
		[COLOR="Red"]// davidlallen item next line: prevent vanish on owned plot[/COLOR]
		if ((!(pLoopUnit->isCombat())) [COLOR="red"]&& (!(pLoopUnit->getUnitInfo().isItem()))[/COLOR])
		{
			if (!isValidDomainForLocation(*pLoopUnit) || !(pLoopUnit->canEnterArea(getTeam(), area())))
			{
				if (!pLoopUnit->jumpToNearestValidPlot())
				{
					bErased = true;
				}
			}
		}
	}
}
For a reason I do not understand, there are two identical copies of this loop in this function; add the new test to both copies. I originally thought that the inner jumpToNearestValidPlot would not be called because canEnterArea should return true. However, items are also DOMAIN_IMMOBILE, and canMoveInto returns false for this domain. I suppose that makes sense, if a unit is immobile it should not be able to move into a plot. Adding the new test after isCombat seems the best place to make this change.

For me, this fixed the problem, and dropped items now persist even in owned territory.
 
I don't know, but in my latest game Faeryl left the Black Mirror sitting in my territory after I took care of the Assassin hero (whatshisface), despite having non-spellcasting units left over to pick up the mirror. Was hilarious to use it for myself, and making illusory Great People XD.
 
Top Bottom