Property Tutorial
This tutorial will give you some information about how to deal with the extended property system and use it to model interesting behaviors.
As first example we will try to change the crime property. Instead of the current system that calculates a constant crime rating depending on the buildings in a city we will instead use the buildings as a constant crime source that then moves to plots resulting in a crime value in all plots and cities.
First step is to change the property from the current behavior towards a property that has sources and drains. Open Assets/XML/GameInfo/CIV4PropertyInfos.xml where the properties are defined. Change <bDrainSource>1</bDrainSource> to the crime property.
Now we need to change the buildings so they don't just add a value on construction and remove a value when they are destroyed but instead act as a source each turn.
Open the CIV4BuildingInfos.xml that contains the building you want to change. If the building currently influences crime, it has XML code like this:
Remove that.
Instead we now add a source. A source is a property manipulator. Everything that allows you to add sources also allows you to add the other types of manipulators (interactions, propagators). This includes buildings, unit types, promotions, terrain types, ...
You add them in these tags:
So now lets add 20 crime each turn. The source type that does that is PROPERTYSOURCE_CONSTANT and takes iAmountPerTurn as a parameter.
Now our buildings produce crime per turn which gets added to the cities the buildings are in (depending on what you tag your manipulator to the value will be added to different game objects, e.g. terrain type sources will be added to the plot with that terrain).
Since we don't want the crime to just accumulate in our cities, we now need to add propagators. That behavior should be global instead of just on specific features, so we add it to the property itself.
In CIV4PropertyInfos.xml add PropertyManipulators tags (in a property, due to some loading issues that I will fix later you are actually better off to add them to the flammability property) and in there we add a PropertyPropagator.
Currently implemented are PROPERTYPROPAGATOR_SPREAD, which spreads the property without decreasing it on the source object and PROPERTYPROPAGATOR_GATHER, which collects properties from other objects and moves it to the object with the propagator. Here we actually want the soon to be implemented PROPERTYPROPAGATOR_DIFFUSE which moves a property from a source object to target objects with a rate depending on the difference between them. The parameter is iPercent representing by how much you want the difference reduced per turn. First lets diffuse from the city to all plots in a distance of 1.
So this means diffuse crime from cities to nearby plots in a distance of max 1 with 2%.
But it will not spread it any further so we need more propagators.
Lets assume routes spread crime.
So open CIV4RouteInfos.xml and add a diffuse propagator to each route type:
Now crime on routes will be diffused to nearby plots which should slowly move crime along the roads.
Crime likes a place to hide. Forests are good for hiding. So lets add a gather propagator to forests so crime concentrates there if any gets nearby. Open CIV4FeatureInfos.xml and add this to the forest type:
Finally a percentage decay should be added to all objects so our crime does not reach ever higher numbers. That is actually a source (to be added): PROPERTYSOURCE_DECAY and uses iPercent as parameter.
This tutorial will give you some information about how to deal with the extended property system and use it to model interesting behaviors.
As first example we will try to change the crime property. Instead of the current system that calculates a constant crime rating depending on the buildings in a city we will instead use the buildings as a constant crime source that then moves to plots resulting in a crime value in all plots and cities.
First step is to change the property from the current behavior towards a property that has sources and drains. Open Assets/XML/GameInfo/CIV4PropertyInfos.xml where the properties are defined. Change <bDrainSource>1</bDrainSource> to the crime property.
Now we need to change the buildings so they don't just add a value on construction and remove a value when they are destroyed but instead act as a source each turn.
Open the CIV4BuildingInfos.xml that contains the building you want to change. If the building currently influences crime, it has XML code like this:
Code:
<Properties>
<Property>
<PropertyType>PROPERTY_CRIME</PropertyType>
<iPropertyValue>20</iPropertyValue>
</Property>
</Properties>
Instead we now add a source. A source is a property manipulator. Everything that allows you to add sources also allows you to add the other types of manipulators (interactions, propagators). This includes buildings, unit types, promotions, terrain types, ...
You add them in these tags:
Code:
<PropertyManipulators>
Add your sources, interactions, propagators here. Order does not matter.
</PropertyManipulators>
Code:
<PropertyManipulators>
<PropertySource>
<PropertySourceType>PROPERTYSOURCE_CONSTANT</PropertySourceType>
<PropertyType>PROPERTY_CRIME</PropertyType>
<iAmountPerTurn>20</iAmountPerTurn>
</PropertySource>
</PropertyManipulators>
Now our buildings produce crime per turn which gets added to the cities the buildings are in (depending on what you tag your manipulator to the value will be added to different game objects, e.g. terrain type sources will be added to the plot with that terrain).
Since we don't want the crime to just accumulate in our cities, we now need to add propagators. That behavior should be global instead of just on specific features, so we add it to the property itself.
In CIV4PropertyInfos.xml add PropertyManipulators tags (in a property, due to some loading issues that I will fix later you are actually better off to add them to the flammability property) and in there we add a PropertyPropagator.
Currently implemented are PROPERTYPROPAGATOR_SPREAD, which spreads the property without decreasing it on the source object and PROPERTYPROPAGATOR_GATHER, which collects properties from other objects and moves it to the object with the propagator. Here we actually want the soon to be implemented PROPERTYPROPAGATOR_DIFFUSE which moves a property from a source object to target objects with a rate depending on the difference between them. The parameter is iPercent representing by how much you want the difference reduced per turn. First lets diffuse from the city to all plots in a distance of 1.
Code:
<PropertyManipulators>
<PropertyPropagator>
<PropertyPropagatorType>PROPERTYPROPAGATOR_DIFFUSE</PropertyPropagatorType>
<PropertyType>PROPERTY_CRIME</PropertyType>
<GameObjectType>GAMEOBJECT_CITY</GameObjectType>
<TargetObjectType>GAMEOBJECT_PLOT</TargetObjectType>
<RelationType>RELATION_NEAR</RelationType>
<iDistance>1</iDistance>
<iPercent>2</iPercent>
</PropertyPropagator>
</PropertyManipulators>
But it will not spread it any further so we need more propagators.
Lets assume routes spread crime.
So open CIV4RouteInfos.xml and add a diffuse propagator to each route type:
Code:
<PropertyManipulators>
<PropertyPropagator>
<PropertyPropagatorType>PROPERTYPROPAGATOR_DIFFUSE</PropertyPropagatorType>
<PropertyType>PROPERTY_CRIME</PropertyType>
<TargetObjectType>GAMEOBJECT_PLOT</TargetObjectType>
<RelationType>RELATION_NEAR</RelationType>
<iDistance>1</iDistance>
<iPercent>2</iPercent>
</PropertyPropagator>
</PropertyManipulators>
Crime likes a place to hide. Forests are good for hiding. So lets add a gather propagator to forests so crime concentrates there if any gets nearby. Open CIV4FeatureInfos.xml and add this to the forest type:
Code:
<PropertyManipulators>
<PropertyPropagator>
<PropertyPropagatorType>PROPERTYPROPAGATOR_GATHER</PropertyPropagatorType>
<PropertyType>PROPERTY_CRIME</PropertyType>
<TargetObjectType>GAMEOBJECT_PLOT</TargetObjectType>
<RelationType>RELATION_NEAR</RelationType>
<iDistance>1</iDistance>
<iAmountPerTurn>1</iAmountPerTurn>
</PropertyPropagator>
</PropertyManipulators>
Finally a percentage decay should be added to all objects so our crime does not reach ever higher numbers. That is actually a source (to be added): PROPERTYSOURCE_DECAY and uses iPercent as parameter.