How to completely swap art for a unit?

davidlallen

Deity
Joined
Apr 28, 2008
Messages
4,743
Location
California
In the Dune Wars mod, we have some awesome artwork for a Worm Rider. I want to have units which look one way when standing on land, and look completely different when standing on ocean.

I have tried to do this with unit swapping called by onUnitMove, but that did not work out. Please see this thread for more description and details, in particular point (2) in post #3. It generates a free unit whenever the routine executes.

One of the non-developers on the Dune Wars forum has said that this is a standard part of FFH. Of course FFH is a huge mod which contains huge changes to the sdk.

My question is, can anybody give me a high level view of how FFH handles unit art swapping? If there is a trick which I can easily re-implement, I will do it. If there is a big, but separable part of the FFH sdk mod which I can pull out, I will try to do it.

Any pointers?
 
I'm not sure FfH has the capability or not, but in FF there is a tag available for promotions, <UnitArtStyleType>.

You'd want to grab any DLL work relating to that tag, as well as the AutoAcquire work for promotions.... Then you can set a promotion to be autoacquired on certain terrain types, and set the art one way, then have another for the other terrains that sets the art another way.

The artstyle it refers to is in CIV4UnitArtStyleTypeInfos, so you need to make a new artstyle entirely for each unit, but that's not difficult to do.


Hopefully this helps a bit... I've never looked at the DLL side for those tags, they already existed when I started modding FF. :lol:
 
<UnitArtStyleType> is in normal FfH.

Actually, it might even be in normal BtS. I believe the capacity for promotion to control art was added in the BtS 3.17 patch, but I'm not sure if that means they added the tag or just exposed what had been in the graphics engine to the DLL for editing.
 
Doesn't change the fact that you'd need autoacquire promotions to make it work as he descrbed, however. ;)

I can add and remove promotions fine using onUnitMove without any FFH sdk. The art changing is what I am stuck on.

Is anybody familiar with the insides of the art swapping?
 
My question is, can anybody give me a high level view of how FFH handles unit art swapping? If there is a trick which I can easily re-implement, I will do it. If there is a big, but separable part of the FFH sdk mod which I can pull out, I will try to do it.
As far as I know to update graphics you need to call CvUnit::reloadEntity();

In FFH this is done in CvUnit::setHasPromotion and promotions are used to apply different artstyles.
 
Thanks, that may be a good starting point. I have downloaded the 0.41i sdk source files from the modder's guide thread.

I am not sure I understand the flow. I have units A, B, C which have their own individual art. Separately, I currently have unit D with art. I can trigger an event at the right time to swap for some unit which is an instance of A. I want it to display the art of D, and then at some other event it should switch back to showing its regular art. Same thing for B and C; each of them should swap to display the art of D. D by itself is kind of a placeholder unit, it never appears on its own. It is just a convenient place to store some art files.

What is the xml part of this? I am not too familiar with artstyles. Is there an example inside FFH where this happens, that I can get to with WB?
 
Thanks, that may be a good starting point. I have downloaded the 0.41i sdk source files from the modder's guide thread.

I am not sure I understand the flow. I have units A, B, C which have their own individual art. Separately, I currently have unit D with art. I can trigger an event at the right time to swap for some unit which is an instance of A. I want it to display the art of D, and then at some other event it should switch back to showing its regular art. Same thing for B and C; each of them should swap to display the art of D. D by itself is kind of a placeholder unit, it never appears on its own. It is just a convenient place to store some art files.

What is the xml part of this? I am not too familiar with artstyles. Is there an example inside FFH where this happens, that I can get to with WB?

I'm not sure of any in FfH, honestly.

I do know that in my mod (FFPlus) the Malakim have special mounted units... Can use normal horses, or camels. You can change the steed out at various Stables... Might be a good place to look.
 
One example. You have a human scout who explores a lair. You get a bad result and now the unit has a demon curse and looks a bit like a demon. This is done by giving the the unit a racial promotion via cvunit::setHasPromotion. The information is read from the XML promotion tag UnitArtStyleType.
I don't know how difficult this is to merge but I guess it isn't too difficult.

You can get an example by starting the game as Elohim civ and then give your warrior the demon promotion.
 
Deliverator made an excellent suggestion on another thread, to use the LateUnitArtStyle tags. Since we aren't using era-specific artwork, this offers an easy way to do the association, without much code.

In fact I have it working, and it required exactly seven lines of sdk code. I have Fremen scouts, who turn into worm riders when they move onto ocean, and it looks awesome!

Unfortunately, I tried to update the other units to also work like this, and ran into the settler:
Code:
			<UnitMeshGroups>
				[...]
				<UnitMeshGroup>
					<iRequired>1</iRequired>
					<EarlyArtDefineTag>ART_DEF_UNIT_SETTLER_FEMALE</EarlyArtDefineTag>
				</UnitMeshGroup>
				<UnitMeshGroup>
					<iRequired>1</iRequired>
					<EarlyArtDefineTag>ART_DEF_UNIT_SETTLER_FEMALE</EarlyArtDefineTag>
				</UnitMeshGroup>
				<UnitMeshGroup>
					<iRequired>2</iRequired>
Nuts. The LateArtDefineTag goes inside the UnitMeshGroup. There is no way I can substitute *one* worm rider art for *several* UnitMeshes.

I didn't invent anything new; FFH shows how to change the local unit art style and then call CvUnit::reloadEntity, and Planetfall shows how to trigger a change in setXY(). Using them together, with the era art style, is a new variation.

After I get over my temporary elation => depression at this, I will try a larger code change to get *one* worm rider to replace *multiple* settler or other unit components. But the scout => worm rider change looks soooo cool.

EDIT: nuts nuts NUTS. Even the full up FFH code will not solve this. UnitArtStyleType cannot help with replacing multiple units by one unit. So I am totally stuck again. Can anybody suggest a different approach?
 
I think you can replace multiple units with one unit. In the artstyletypeinfos, just use one of the worm riders in there rather than three
 
I don't think so; in the schema for UnitInfo, a UnitMeshGroup has an iRequired field. But in the StyleUnit schema, a UnitMeshGroup does not have iRequired.

The easy case works: the unit has a single UnitMeshGroup which has iRequired = 1.

The medium case is: single UnitMeshGroup with iRequired > 1, for example, worker, or soldier, or most units.

The hard case is: multiple UnitMeshGroups, like settler.

The current technique cannot address the medium or hard cases. The goal is to replace all the meshs, regardless of how many meshgroups or irequired, with a single mesh. So, I would like to replace the settler graphic of one man, one woman and two children settlers, with one worm graphic. I don't think there are any existing examples of that, and I can't see any way to do it. Any suggestions?
 
Generally speaking, I don't think artstyles by themselves allow you to change meshgroup size; Vermicious Knid had some trouble with that for one of his projects.

However, there IS a tag that will help you... <iGroupSize>, in promotioninfos. Allows you to change the number of units shown. In FF, it's used for few special promotions... Adventurer, Hero, Godslayer, etc. This would still require you to add/remove a promotion, but at the least it WILL work.... And might be a good reason to merge Autoacquire and MustMaintain tags for promotions.

Those go by the tag 'AutoBots' in FF's DLL by the way... Xienwolf gets rather creative with his naming sometimes. :lol:
 
The medium case is: single UnitMeshGroup with iRequired > 1, for example, worker, or soldier, or most units.

Potential workaround: create two different art_defines, say Fedaykin1 and Fedaykin2 that are identical. Fedaykin1 is replaced by the Worm Rider on Promotion, Fedaykin2 is replaced by the empty NIF. The group of three Fedaykin is made up of one Fedaykin1 and two Fedaykin2s.

The hard case is: multiple UnitMeshGroups, like settler.

For settler, replace the woman and children with the empty NIF on promotion.

The main problem with this will probably be that the Worm Rider will not be properly centred in the tile, but it might be possible to fix that by having different Worm Rider NIFs for groups of 3 or 4.
 
Great idea! I will try it. For three, using the center one should avoid any alignment. For two, such as the worker, we may need an "offcenter" one. For settler, may I request a variant unit which has settler types on board instead of a Fedaykin?
 
Let's see if the basic idea works. If so, I can customize some NIFs.
 
It is working for settlers and soldiers now. As deliverator suggested, the trick is to change the xml like this (soldier example):
Code:
<UnitMeshGroup>
	<iRequired>1</iRequired>
	<EarlyArtDefineTag>ART_DEF_UNIT_SOLDIER</EarlyArtDefineTag>
	<LateArtDefineTag>ART_DEF_UNIT_FREMEN_WORM</LateArtDefineTag>
</UnitMeshGroup>
<UnitMeshGroup>
	<iRequired>2</iRequired>
	<EarlyArtDefineTag>ART_DEF_UNIT_SOLDIER</EarlyArtDefineTag>
	<LateArtDefineTag>ART_DEF_UNIT_EMPTY</LateArtDefineTag>
</UnitMeshGroup>

The first one appears to take the center position, so making him into the worm seems to produce a result which is on-center. It also works for the settler. However, the sdk change is not doing the right thing for workers quite yet, it is possible after I fix that, they will be off-center.
 
Top Bottom