An All-terrain Unit

jeffrockson

Chieftain
Joined
Feb 8, 2010
Messages
40
Location
USA
I've searched a bunch, and I found no solution to this question. So I set out on my own to figure out how to make a unit move seamlessly from land to coast to ocean (without embarking). Yesterday I identified exactly the combination of XML to make the Helicopter Gunship allowed to move over the coast. But I'm still at a loss about how to get it to go over the ocean and stay there.

So, hopefully by posting this to the forums, we can work together to come up with a solution. I know there's some work on this in conjunction with the Alpha Centauri Mod. I doubt we're the only ones looking for this solution!

Spoiler :
I want this:
2z3qx41.jpg

Spoiler :
This is the entire mod to get the Helicopter to hover over Coast tiles.
Code:
<GameData>
[INDENT]<UnitPromotions>
[INDENT]<!-- Original entry
[INDENT]<Row>
<Type>PROMOTION_HOVERING_UNIT</Type>
<Description>TXT_KEY_PROMOTION_HOVERING_UNIT</Description>
<Help>TXT_KEY_PROMOTION_HOVERING_UNIT_HELP</Help>
<Sound>AS2D_IF_LEVELUP</Sound>
<CanMoveImpassable>true</CanMoveImpassable>
<PortraitIndex>58</PortraitIndex>
<IconAtlas>ABILITY_ATLAS</IconAtlas>
<PediaType>PEDIA_ATTRIBUTES</PediaType>
<PediaEntry>TXT_KEY_PEDIA_PROMOTION_HOVERING_UNIT</PediaEntry>
</Row> -->[/INDENT]
<Update>
[INDENT]<!-- This allows the helicopter's movement range (blue border) to
extend over the coast, but doesn't allow the heli to actually
move there. I'm pretty sure that it's useless, because
HoveringUnit does more. -->
<Where Type="PROMOTION_HOVERING_UNIT" />
<Set CanMoveAllTerrain="1" />[/INDENT]
</Update>
<Update>
[INDENT]<!--This allows the unit to hover over coastal tiles, but not
enter the ocean. -->
<Where Type="PROMOTION_HOVERING_UNIT" />
<Set HoveringUnit="1" />[/INDENT]
</Update>[/INDENT]
</UnitPromotions>[/INDENT]
</GameData>
Some things I know that don't work:
  • Setting the Domain to DOMAIN_AIR (and then modifying its movement to allow it to move regularly with :c5moves: Movement Points) causes the unit to be able to move an indefinite number of tiles and makes it to jump back to the closest city at the beginning of the player's next turn, which is not desirable.
  • Setting the Domain to the default NULL or any other invalid value causes exactly the behavior I would like to see, but again makes the unit jump back to the closest city at the beginning of the player's next turn. So close! But at least I got a screenshot out of it. Can I get someone else to verify this?
  • The promotion combination of CanMoveImpassable, CanMoveAllTerrain, and HoveringUnit do not make Ocean tiles passable by a unit. (CanMoveAllTerrain appears to be a broken promotion option.)

So, let's work together to solve this. It's likely we can't solve this with just XML, but that's fine. It'll be worth it! Please post your attempts and findings in this thread!


Thanks for reading,
JeffRockson
 
I've spent a disturbing amount of time on this so far, as you know since we've been talking about this in PMs. And no, there's no simple XML fix for this, although from what I can tell it'd be trivial for the devs to add one if they wanted to.

Also, this is in the wrong forum. It should be in the base C&C forum, these subforums are only for mods with actual files involved.

1> There are three Lua events that matter here:
SerialEventUnitCreated triggers when a unit is created, embarks, or disembarks. There's no easy way to tell which of these three called the function. I've gotten around that by adding a "Rookie" promotion in my mod, which all units get at creation and is removed as soon as the unit is in a fight. So through a combination of checking the turn number the unit was created on and checking the presence of this promotion, you can tell whether the unit was just created. (If you simply never remove the promotion, then there's no need for the turn check.)
One upshot of this event is that you can remove the free Embarkation promotions easily when a unit is created, to ensure that it hovers over shallow water.

UnitEmbark triggers when a unit embarks or disembarks. Three arguments: player ID, unit ID, and true/false (true when it embarks, false when it disembarks). Unfortunately, if you try using the Units:Embark() command inside here while the unit still has its embarkation promotion, you'll get stuck in an infinite loop.

There are several Lua events that trigger when a unit moves; most have the player ID and unit ID and nothing else, but a couple also pass the X and Y values (although you could get those from the unit's database just as easily). The best of these is the UnitSetXY GameEvent.

However, all but one of these events will only trigger if the destination hex is valid, which doesn't help here as what you really need to know is when the unit WOULD move into the impassable deep ocean while hovering. The only one that does trigger for an invalid move (StartUnitMoveToHexes, I think) has no arguments at all, not even unit ID.

Now, you could still get around this through the SaveData structures, and I'm working on just that. Basically storing whether that last event triggers without the other ones, to know whether an invalid move was ordered. Unfortunately, there's no way to know what hex the unit was moved to order to, without also trapping the mouse position or something, and that's not going to work for anyone other than the human player.

What we need is a modified UnitSetXY that reports when an invalid move is ordered as well, with full positional information. But this wouldn't help in the long term, since the AI would simply never give those invalid orders.

2> For XML, you'd have to go about things a bit differently. It IS possible to make a true all-terrain promotion, by doing the following:
> Go into the database and change Ocean and Coast tiles to be land instead of sea
> Make all naval units be land units with the "Naval Unit" promotion, making everything other than coast and ocean impassable.
> Make all land units start with the "Land Unit" promotion, making coast and oceans impassable.
> For the all-terrain units, just don't give them either of those promotions. (Although the CanMoveImpassable might override them anyway.)
As you can tell, this'd be tremendously messy, as it would basically render the Domain system useless. You'd have to rewrite all of those "Naval Penalty" type promotions to key off of combat classes instead of domains, and the Barracks and such would now add XP to naval units. On the bright side, the AI would know how to handle this.

3> There's a possibility I've also been looking into: cheating. Basically, let's say I made a "Gravtank" unit that is intended to work this way. So I create a "Gravtank2" unit; exact same stats in every way (including the Armor combat class), except that it's DOMAIN_SEA instead of DOMAIN_LAND. Neither has Embarkation.
So when the Gravtank moves over water not adjacent to shore, the game spawns a Gravtank2 on the same hex, gives it every promotion that the original had, sets its movement to whatever the original had remaining, and kills the original.
In reverse, as soon as the Gravtank2 moves to a hex adjacent to land, it switches back to a hovering land unit through a similar process.

(This could be done even easier if the game provided a Units:ChangeDomain() function, but it doesn't.)

The problems:
A> The naval combat penalty. Naval units have much weaker stats than land units, which is why so many things have the naval penalty. Gravtank2 could have a lower combat rating to compensate, like half as much, but it'd now be far more vulnerable to artillery.
B> 1-hex-wide continental shelves.
The above method only works if the shelf is 2 hexes wide, or else you can get situations where the unit just doesn't trigger the transformation.

and the big one:
C> The AI would have no clue how to do this.
It would think the ocean is impassable, and so not try to move to that continent on the far side. It's possible that the unit might hover too far from land, transform, move across the ocean, accidentally come up next to the shore and transform back. But it's horribly unlikely, which means this'd be a very unbalanced system.

This last one is the major drawback of nearly any system you can come up with; doing something the game already knows to be invalid just prevents the AI from using it, so they're not good long-term solutions.

So until the devs release the DLL, I'm not going to go much further. Right now, I'm focusing on making a poor man's version of this by giving all units with this promotion two things: the defensive embarkation of the Songhai, and a triggered Lua event where whenever a unit embarks or disembarks it refunds the movement points that were lost in the process, allowing the unit to keep moving through the water. It's not as good as what I'd wanted, but it at least is something the AI should have no issues using.
Also, I added airlifting in my mod (through a custom paradrop promotion that only appears when you start your turn in the city with that building), so having these units be unable to embark isn't crippling.
 
Thanks for all of the input! I knew you had some awesome stuff to try to solve this obnoxious problem. I actually put this in the correct forum when I started writing it, because I got halfway through writing it (talking about a NULL Domain) before I realized that the unit returned to the closest city at the next turn. I went back to change the message text, but forgot it should be in a different forum. Hopefully a moderator can move it for me.

I wish the devs would make the CanMoveAllTerrain promotion item work. :( That'd just be fantastic!

Thank you for your notes! I hope others contribute too!
~JeffRockson
 
I got halfway through writing it (talking about a NULL Domain) before I realized that the unit returned to the closest city at the next turn.

That behavior is actually useful in its own right; I've used a similar setup for the Geosynchronous Survey Pod unit in my own mod, although there it's handled as DOMAIN_AIR but with the <Immobile> flag turned off, so you can at least do a few air unit-type things with it and it seems to be a bit more stable. Since it's not a combat unit, it's not unbalanced, and since it's cheap it's replaceable if something goes wrong.

And it'll do that for any invalid value. I tried seeing if I could hack the Domain variable to count the unit as both a Land and a Sea unit, and at first it looked like it was working, but then it did the usual reset bit, because it just saw an invalid domain value.
There IS one other limitation to the invalid Domain method, though; if two combat units reset to the same city this way, there's a chance that one of them will be destroyed in the process. So watch out for using this for anything beyond disposable scout units. (This is also why I made sure to stick with the Air domain for the geosynchs: air units have no stacking limit, so it's less flaky.)
 
GOT IT!

I think.

Here's the thing. We've determined that the CanMoveImpassable promotions can't override the inability of land units to move through deep water. However, the reverse apparently isn't true; if you give a SEA unit all of the hovering, canmoveimpassable, etc. promotions, it can move across land. And obviously, it can already move across sea, so you're done! All you have to do is change any units like this to DOMAIN_SEA and give them a promotion that gives those other abilities.

I'm testing it now, but it seems to work. The only quirk I've found is that as Sea units, things like the Barracks, Forge, etc. don't help. But that's a minor thing.

Testing now, but you might want to try something similar in your own mods...
 
GOT IT!

I think.

Hey, excellent! Sounds great. One thing I thought of is that it means you can only build the unit in coastal cities. Until further progress is made, though, that is an absolutely fine concession! :goodjob:

I'm excited to get back to working on my mod now! :D

~JeffRockson
 
One thing I thought of is that it means you can only build the unit in coastal cities.

I hadn't even thought of that, but I just double-checked and yes, that's exactly what happens. Only coastal cities can build these. Which isn't really so bad in my mod, given the unit types I happen to have given this ability to.

I'm still hoping that at some point the devs will just fix this so that we can do this through those promotions, but until then it's a limitation I can live with.
 
I hate to necro this thread, but it was incredibly useful to me, and if anyone drops by to look at it, the coastal-only problem might be solved by making a building that allows the unit to be built and allowing that building to be constructed in any city. If not, then you'll need to whip up some Lua. :hammer2:
Whoward made a mod that allows naval units to enter coastal and landlocked forts though, so it can't be too far off.
 
EDIT:
I actually went and tried this and changing the Domain to Sea and giving it CanMoveImpassable and HoveringUnit promotions doesnt work for me. At first I thought it was my syntax but it isn't. Anyone else tested this?
 
Look at the SteamPunk Airships in the G&K scenario - these do exactly what was being asked for in the first post
 
Look at the SteamPunk Airships in the G&K scenario - these do exactly what was being asked for in the first post

Yeah, I was trying to copy the Airships for my unit at first but I went wrong somewhere in the process. Anyway, it was resolved here. Sorry for asking the same question in two threads, but thanks! :D
 
Back
Top Bottom