Custom features

Pococurante

Chieftain
Joined
Dec 22, 2005
Messages
40
Using Kael's guide I created a feature that mimics another completely, just different key/name and flavor text. I'm using the below syntax to get its ID so I can test for it, assign it, etc. But it always assigns the core Ice improvement. What am I doing wrong? TIA!

Code:
local FeatureType_FeatsDontFailMeNow = GameInfo.Features.FEATURE_MYFEAT.ID;
plot:SetFeatureType(FeatureType_FeatsDontFailMeNow);
 
Are you sure that your custom feature was properly added to the game? Ice is feature 0, which I imagine plot:SetFeatureType() defaults to when you pass an invalid option.
 
Hmm well I think so - i have seen it placed in the past, and using the above syntax I do get an id of 14. I don't see it in Live Tuner though, and am not really sure where to look. It is not in GameCore=>FeatureTypes but I didn't think it would.
 
Hmm well I think so - i have seen it placed in the past, and using the above syntax I do get an id of 14. I don't see it in Live Tuner though, and am not really sure where to look. It is not in GameCore=>FeatureTypes but I didn't think it would.
You've got me a bit confused now. You said you've seen it placed in the past, what does that mean?

As for Live Tuner, I have no idea how the code behind that works. It could use only the hard-coded values for Features for all I know.
 
Partially solved - turned out a bug was overwriting the earlier value. But even with that straightened out the Fallout animation doesn't display. It is mystifying because I've basically completely cloned Fallout to my new feature. Basically I searched through all XML / LUA in the core folders and mirrored what I found.

I'm starting to wonder if there is hard-coded behavior for Fallout. This is the XML just for the feature - the other changes are pedia text so I can't imagine it matters.

Code:
<Features>
	<Row>
		<Type>FEATURE_TILEEROSION</Type>
		<Description>TXT_KEY_FEATURE_TILEEROSION</Description>
		<Civilopedia>TXT_KEY_FEATURE_TILEEROSION_PEDIA</Civilopedia>
		<ArtDefineTag>ART_DEF_FEATURE_FALLOUT</ArtDefineTag>
		<Movement>2</Movement>
		<Defense>-33</Defense>
		<DisappearanceProbability>500</DisappearanceProbability>
		<NoImprovement>false</NoImprovement>
		<PortraitIndex>17</PortraitIndex>
		<IconAtlas>TERRAIN_ATLAS</IconAtlas>
	</Row>
</Features>
<Feature_YieldChanges>
	<Row>
		<FeatureType>FEATURE_TILEEROSION</FeatureType>
		<YieldType>YIELD_FOOD</YieldType>
		<Yield>-3</Yield>
	</Row>
	<Row>
		<FeatureType>FEATURE_TILEEROSION</FeatureType>
		<YieldType>YIELD_PRODUCTION</YieldType>
		<Yield>-3</Yield>
	</Row>
	<Row>
		<FeatureType>FEATURE_TILEEROSION</FeatureType>
		<YieldType>YIELD_GOLD</YieldType>
		<Yield>-3</Yield>
	</Row>
</Feature_YieldChanges>
I'm going to temporarily use another core feature as a basis and see if there is a difference.
 
Is there a performant way to tell the entire map to refresh itself? I'm using this syntax as I loop through each tile.

Code:
if featureType ~= GameInfo.Features.FEATURE_TILEEROSION.ID then
	print("Eroding tile");
	tile:SetFeatureType(GameInfo.Features.FEATURE_TILEEROSION.ID);
else
	if terrainType == TerrainTypes.TERRAIN_TUNDRA then
		print("Collapsing tundra");
		tile:SetTerrainType(TerrainTypes.TERRAIN_PLAINS, true, true);
	elseif terrainType == TerrainTypes.TERRAIN_GRASS then
		print("Collapsing grassland");
		tile:SetTerrainType(TerrainTypes.TERRAIN_PLAINS, true, true);
	elseif terrainType == TerrainTypes.TERRAIN_PLAINS then
		print("Collapsing plains");
		tile:SetTerrainType(TerrainTypes.TERRAIN_DESERT, true, true);
	elseif terrainType == TerrainTypes.TERRAIN_DESERT then
		print("Tile collapsed, consoling player");
		tile:SetFeatureType(-1);
		tile:SetImprovementType(GameInfo.Improvements.IMPROVEMENT_GOODY_HUT.ID);
	else
		print("Erosion detected - AjustState invoked but no matching criteria was found")
	end
end
 
Sorry to resurrect this thread but I am having a similar problem. Pococurante, did you ever find out what was wrong? I am trying to create a feature on top of every desert tile which is not already covered by flood plains or an oasis.

I have added my new feature in CIV5Features.xml and FeatureGenerator.lua but it isn't appearing. Not only that but now Ice seems to be appearing on every coast tile!! How do I link FeatureGenerator.lua to CIV5Features.xml so it uses my new feature, or does it do that automatically?

EDIT:
In terms of coding, my CIV5Features.xml is this:

Code:
<GameData>
	<Features>
		<Row>
			<Type>FEATURE_SAND</Type>
			<Description>TXT_KEY_FEATURE_SAND</Description>
			<Civilopedia>TXT_KEY_CIV5_FEATURE_SAND_TEXT</Civilopedia>
			<ArtDefineTag>ART_DEF_FEATURE_FALLOUT</ArtDefineTag>
			<Movement>2</Movement>
			<InfluenceCost>-1</InfluenceCost>
			<AppearanceProbability>10000</AppearanceProbability>
			<PortraitIndex>17</PortraitIndex>
			<IconAtlas>TERRAIN_ATLAS</IconAtlas>
		</Row>
	</Features>
	<Feature_TerrainBooleans>
		<Row>
			<FeatureType>FEATURE_SAND</FeatureType>
			<TerrainType>TERRAIN_DESERT</TerrainType>
		</Row>
	</Feature_TerrainBooleans>
	<BuildFeatures>
		<Row>
			<BuildType>BUILD_FARM</BuildType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<BuildType>BUILD_MINE</BuildType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<BuildType>BUILD_TRADING_POST</BuildType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<BuildType>BUILD_PASTURE</BuildType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<BuildType>BUILD_PLANTATION</BuildType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<BuildType>BUILD_QUARRY</BuildType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<BuildType>BUILD_FORT</BuildType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<BuildType>BUILD_CUSTOMS_HOUSE</BuildType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<BuildType>BUILD_MANUFACTORY</BuildType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<BuildType>BUILD_CITADEL</BuildType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
	</BuildFeatures>
	<Resource_FeatureBooleans>
		<Row>
			<ResourceType>RESOURCE_IRON</ResourceType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_OIL</ResourceType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_ALUMINIUM</ResourceType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_URANIUM</ResourceType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_SHEEP</ResourceType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_GOLD</ResourceType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_SILVER</ResourceType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_GEMS</ResourceType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_MARBLE</ResourceType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_COTTON</ResourceType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_INCENSE</ResourceType>
			<FeatureType>FEATURE_SAND</FeatureType>
		</Row>
	</Resource_FeatureBooleans>
	<Resource_FeatureTerrainBooleans>
		<Row>
			<ResourceType>RESOURCE_IRON</ResourceType>
			<FeatureType>TERRAIN_DESERT</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_OIL</ResourceType>
			<FeatureType>TERRAIN_DESERT</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_ALUMINIUM</ResourceType>
			<FeatureType>TERRAIN_DESERT</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_URANIUM</ResourceType>
			<FeatureType>TERRAIN_DESERT</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_SHEEP</ResourceType>
			<FeatureType>TERRAIN_DESERT</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_GOLD</ResourceType>
			<FeatureType>TERRAIN_DESERT</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_SILVER</ResourceType>
			<FeatureType>TERRAIN_DESERT</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_GEMS</ResourceType>
			<FeatureType>TERRAIN_DESERT</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_MARBLE</ResourceType>
			<FeatureType>TERRAIN_DESERT</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_COTTON</ResourceType>
			<FeatureType>TERRAIN_DESERT</FeatureType>
		</Row>
		<Row>
			<ResourceType>RESOURCE_INCENSE</ResourceType>
			<FeatureType>TERRAIN_DESERT</FeatureType>
		</Row>
	</Resource_FeatureTerrainBooleans>
</GameData>

And I have only added the following to my FeatureGenerator.lua:

Code:
function FeatureGenerator:__initFeatureTypes()

	self.featureFloodPlains = FeatureTypes.FEATURE_FLOOD_PLAINS;
	self.featureIce = FeatureTypes.FEATURE_ICE;
	self.featureJungle = FeatureTypes.FEATURE_JUNGLE;
	self.featureForest = FeatureTypes.FEATURE_FOREST;
	self.featureOasis = FeatureTypes.FEATURE_OASIS;
	self.featureSand = FeatureTypes.FEATURE_SAND;
	self.featureMarsh = FeatureTypes.FEATURE_MARSH;
	
	self.terrainIce = TerrainTypes.TERRAIN_SNOW;
	self.terrainTundra = TerrainTypes.TERRAIN_TUNDRA;
	self.terrainPlains = TerrainTypes.TERRAIN_PLAINS;
end

and

Code:
function FeatureGenerator:AddFeaturesAtPlot(iX, iY)
	-- adds any appropriate features at the plot (iX, iY) where (0,0) is in the SW
	local lat = self:GetLatitudeAtPlot(iX, iY);
	local plot = Map.GetPlot(iX, iY);

	if plot:CanHaveFeature(self.featureFloodPlains) then
		-- All desert plots along river are set to flood plains.
		plot:SetFeatureType(self.featureFloodPlains, -1)
	end
	
	if (plot:GetFeatureType() == FeatureTypes.NO_FEATURE) then
		self:AddOasisAtPlot(plot, iX, iY, lat);
	end

	if (plot:GetFeatureType() == FeatureTypes.NO_FEATURE) then
		if plot:CanHaveFeature(self.featureSand) then
			plot:SetFeatureType(self.featureSand, -1);
		end
	end

	if (plot:GetFeatureType() == FeatureTypes.NO_FEATURE) then
		self:AddIceAtPlot(plot, iX, iY, lat);
	end

	if (plot:GetFeatureType() == FeatureTypes.NO_FEATURE) then
		self:AddMarshAtPlot(plot, iX, iY, lat);
	end
		
	if (plot:GetFeatureType() == FeatureTypes.NO_FEATURE) then
		self:AddJunglesAtPlot(plot, iX, iY, lat);
	end
	
	if (plot:GetFeatureType() == FeatureTypes.NO_FEATURE) then
		self:AddForestsAtPlot(plot, iX, iY, lat);
	end
		
end

Is any of this right?! :blush: Thanks
 
Yellowdartfrog, I'm currently trying to do something similar... and I've just asked a question in the main modding forum. Did you ever figure it out, or is this problem still going on for you?
 
But even with that straightened out the Fallout animation doesn't display.

That's because the game's art defines for terrain, improvements, features, etc. are not adjustable in mods. It doesn't matter which art define you try to mimic, it just won't always work, because certain parts of the process are being hard-coded internally.

You also see this when creating new units. As long as the new units have one of the existing combat classes (Mounted, Gunpowder, Armor, etc.) AND the art you're using as a placeholder is for a unit in the same combat class, you'll have the unit animation. But try to create a new combat class and suddenly the combat animations will stop working, because somewhere inside the engine is logic that explicitly checks for combat class when deciding which animation to trigger.
 
Back
Top Bottom