add bonuses to civ?

davidlallen

Deity
Joined
Apr 28, 2008
Messages
4,743
Location
California
In Dune Wars, we are experimenting with offworld trade. If a civ builds a spaceport, it may obtain a "contract" for an offworld bonus. This bonus may represent a rare offworld mineral or luxury items. If the civ gets the contract, it would be represented by three copies of a bonus: one to use, and two to trade away. Some bonuses may only be contracted one time; some bonuses may be specific to a civ.

We can do part of this with buildings that provide free bonuses. But we want more control, particularly for strategic resources which are specific to a civ, when that civ is not played in a particular game.

Is there a way to add/subtract bonus access with python? I can "plant" one copy of the bonus under a city; but I was hoping to find a hook in the python API that would let me add or subtract bonuses available to a civ. I looked in the team, player and city APIs. Any leads?
 
You mention you can do part of it with buildings- can't you do all of it with buildings, plus random events?

You build a spaceport, and this is the prereq for a random event. This random event would be something like "We have won a contract with our homeworld for exporting iron*." Once that random event is triggered, you can have the city "build" a new building, "Iron Contract", via the event).

Code:
			<BuildingClass>BUILDINGCLASS_IRON_CONTRACT</BuildingClass>
			<iBuildingChange>1</iBuildingChange>

You might need a lot of buildings and events to make it work, though.

If you want to restrict civ access, you can make the event only triggerable for a specific civ via a python prereq for the event:

Code:
def canTriggerIronContract(self, argsList):
	kTriggeredData = argsList[0]
	pPlayer = gc.getPlayer(kTriggeredData.ePlayer)
	if not pPlayer.getCivilizationType() == gc.getInfoTypeForString('CIVILIZATION_IRON_EXPORTERS'):
		return false
	return true

Or something like that, anyway.

*Just a generic Civ 4 resource.
 
Suppose we have a strategic resource, Sapho Plant, which is required to build a medium power unit, Mentat. Normally this resource is only available to the House Ecaz civ. However, if Ecaz is not in the game, then any one civ can select it, the first one to complete a Space Port building and ask for it. If we use buildings, I need a way to make the Sapho Plant Contract building limited to Ecaz, unless Ecaz is not in the game. I could presumably do this with cannotConstruct; but the logic would be relatively complicated, and cannotConstruct is called very frequently by the AI.

I was hoping to find a hook, where I could directly provide N bonuses to a city/civ/team.
 
I have a cunning plan.

Can you make the resources be provided by a building that is a world wonder? Then only one civ could ever have the resources.

Give the world wonder to the appropriate civ as a free building, like the palace.

With any luck this would work fine as long as you don't end up with the same civ in a game two (or more) times, which can happen if you play a game with more players than civs.

The part (well, one of them) I'm not sure about is if the building requires a spaceport to be built, and the default civ doesn't start with a spaceport will the thing still provide the resources from the beginning or will it not start working until you build a spaceport in that city?
 
Alternate method. Give each nation a Tech of its own "*NationName* knowledge". Make said technology untradable (bTrade = 0) and unresearchable (iCost = -1).

This new technology is a prerequisite for the building that provides the resource.

Have the spaceport let you chose one of the technologies that are not already in use by an existing nation.
 
Another idea.

Instead of having the wonder be available to be built with the requirement of there being a spaceport building, you could have it as a cost -1 (unbuildable) wonder with no requirements. Have an event fire off when a spaceport is completed with the trigger such that it is always included in the game and will always fire on the completion of a starport but will only ever fire once.

It would probably need a little python (pointed at via the PythonCanDo tag, most likely) to make it not fire if the civ that gets it for free is in the game.
 
I agree that using buildings to provide the resources a la Broadway seems like the best route. I don't think you need events, but maybe they will help.

I would make the buildings have a -1 cost as God-Emperor said and display a button popup from buildingBuilt (or whatever the event is when a player builds a building) when it's a Space Port. Here you can see a) which civs are in the game to block resources and b) which resources have already been chosen by previous Space Port builders.

If you track which resource contracts were selected by each civ, you could even have those contracts follow the player rather than the particular Space Port. Say you build a SP, select Sapho Plant, get the free building, and then lose that city (along with the building). If you build a SP in another city, should you get the resources again, or does the conquering player take over the contract?

All this logic could be handled from the buildingBuilt event pretty easily. Just store the contracts chosen using sdToolkit.
 
You should be able to check, in a canDo function, if a certain civ is in the game or not, no?

Then, if they aren't, enable the event to run.

If we use buildings, I need a way to make the Sapho Plant Contract building limited to Ecaz, unless Ecaz is not in the game. I could presumably do this with cannotConstruct; but the logic would be relatively complicated, and cannotConstruct is called very frequently by the AI.

You don't have to mess with that. You can make an event that when triggered gives a city the Sapho Plant Contract Building. In the python prereq, you can check if House Ecaz is in the game. If they are, then only Ecaz can get the event. If they aren't, then any civ can trigger the event.
 
I am liking the event method increasingly as I think about it.

You can have building a starport trip an event trigger that has a list of events, one per resource that it is possible to have. This can be triggered every time a starport is built. Each of the individual events can have it's own canDo function, so each individual type of resource can have different conditions for availability. This presents you with a list of resrouces you can get from the starport, and you can pick only one. You could even have it triggered again from some other sources to allow an additional resource to be selected. Each time you get one, it puts another building in the city.

For example, you might want to import fish to Dune, so you pick the "Import Fish" option on the list, then the event adds the "Fish Market" (or whatever) building to the city which provides the 3 (or whatever) fish resources.

There could also be events wich cancel an existing "contract" which result in the building being removed from the city.
 
I have not used the game random events before. I will trace through; but I like the ideas that each can have its own canDo (so I can reference my own global data) and the picklist of available outcomes is automatically built for me.

The only drawback to this approach is that for 20 resources, 20 buildings are required. But since they do not need separate graphics and they never appear in anybody's city build picklist, it is only the file size of the xml, and maybe that does not matter. If there had been a python hook to just make resources appear and disappear, that would be a little more elegant; but I'll try the random event approach and see what I get.
 
Well, the random event approach does not quite appear to work for this application. I have added the event, which is guaranteed to trigger when a space port building is built. However, there does not appear to be any way to force the event to occur in the city which built it. I set up a test in WB with two cities. When the first city built the space port, the event triggered in that city. However, when the second city built the space port, the event also triggered in the *first* city, not the one which built the building. I have attached my triggerinfo file; don't worry that it calls EVENT_FOREST_FIRE for now, I have only written the trigger part so far.

Is there a way to force the event to trigger in the city that built the building? None of the XML flags seem to match this. I need to change the building in *that* city to the new contract building, not some other random city.

EDIT: retract! I will try PythonCanDoCity. Assuming that the space port building is already added to this city, then picking any city which has a space port will work. In case two cities finish a building in the same turn, it does not matter which order we trigger the events.
 
Thanks for pointing me to events, this is working. There is a generic building, "Contract" which you can build when you receive space ports technology. When you complete this building, it triggers an event which checks to see which contracts are available and gives you the event popup. Whichever one you select, you get the appropriate building. If you want you can immediately build another contract building, and get another contract in the same city when it completes.

The python has complete control over how many contracts are available and can allocate civ-specific contracts to any civ, if the owning civ is not in the game.

We will see how well players like it, but I have achieved the goal of this thread. Thanks again!
 
That is exactly what I started out looking for. Thanks! However, the advantage of the random event system is that it automatically builds the graphics of the picklist for me. I have never built civ graphic items myself, maybe it is not hard, but this way I do not have to learn.
 
I'm pretty sure that the pCity.changeFreeBonus does not act like the bonus(es) from a building. I think you'll find that bonuses from that only apply to that one city and you can also never end up with any to trade. The first could be overcome by applying them to every city a player has, but the second is aparently insurmountable.

This is presumably the same way some corporations add bonuses to the city they are in, which have those "only in this city" and "not tradeable no matter how many you get" characteristics.
 
You wouldn't need to create your own Python screen in this case. You could use a simple popup that had graphics for each resource and/or text. It would look exactly like a "What do you want to build in this city?" popup. The differences between that solution (using the buildingBUilt event) and the guaranteed random event are pretty trivial, and you have it working. :goodjob:
 
Top Bottom