How are Units Prevented from Entering Ocean Tiles Until Cartography?

ReggieB

Chieftain
Joined
Mar 28, 2018
Messages
36
Hi all, I'm working on a mod that will allow some, but not all, units to move onto mountain tiles. So I thought a good approach would be to mimic the way units are prevented from entering ocean tiles until certain conditions are met. Allowing all units to move onto mountains is easy enough, simply by changing the "impassable" tag to false. And fortunately, the game modifier "MODIFIER_PLAYER_UNITS_ADJUST_VALID_TERRAIN" can allow some units to move on certain terrain only if the requirements are met, just like ocean tiles.

However, I'm struggling to find the game element that actually prevents units from moving onto ocean tiles in the first place. As far as I can tell, ocean tiles are passable, and there is no modifier preventing units from entering them. So how does the base game actually prevent ocean navigation, and how would I mimic that effect for mountain tiles? I'd appreciate any suggestions, thanks!
 
So, you must run your modifier at the start game. A suggestion is to develop a dummy start tech, associate MODIFIER_PLAYER_UNITS_ADJUST_VALID_TERRAIN to that start tech, and give the tech 100%, discovering it at start game.

Tech name suggestion: Ancient Technology opposing to future technology.

To add 100% to tech (discovering it) check out this mod: https://forums.civfanatics.com/threads/really-advanced-setup-lite.610454/page-4 . I Can't live without it anymore, I integrated it into my Portugal mod, I pop out starting units with it, @LeeS is the man :)
 
Sorry, maybe my explanation of the issue wasn't clear enough. I understand well enough how to create a modifier that will ALLOW units to enter mountains. What I don't understand is now to PREVENT units for entering mountains until certain conditions are met. Clearly that type of thing is possible, since units are prevented from entering ocean tiles by default, even though ocean tiles aren't technically "impassable". My question is, how does the game prevent units from entering ocean tiles by default, and how would I copy that system for mountains?
 
I've never specifically been able to find where in the database (if it is exposed to the database) TERRAIN_OCEAN and TERRAIN_COAST are made "impassable" by default at the beginning of the game. I suspect but cannot be sure it is inherent in the game's DLL code where the assumption is made that Oceans cannot be navigated at the start of the game by sea units, and land units cannot embark onto Coastal or Lake-ish tiles until the needed "unlock" is researched.

Embarkation-types "unlocking" for land units is handled as direct columns within tables Technologies and Civics although columns "EmbarkAll" and "EmbarkUnitType" in table "Civics" are never used anywhere in the Vanilla game or the expansions for the "normal" game.

I suspect (again, "suspect" but cannot prove) that the "Water" column in table Terrains is the signal used by the game's DLL to disable movement unless the player gets the tech which modifies that player's valid set of terrains so far as "water" movement is concerned. You'll note that TERRAIN_COAST has both "Water" and "ShallowWater" set to true, which I suspect (yet again with "suspect") is how the game's DLL differentiates between how it should handle the two types of "Water" terrains for purposes of movement and for determining whether lake as opposed to sea coast should be applied to an individual tile (although we do know that lake determination is also affected by the number of tiles in the water-body as specified in GlobalParameter LAKE_MAX_AREA_SIZE).
 
I think you might be right. I tried setting mountains as "Water" but not "ShallowWater" and that does prevent units from entering them defaultly. Unfortunately there are too many issues with that to be the solution I'm looking for. For one, units do embark if mountains are set to water, and naval units can enter them as well. Interestingly, units are only prevented from entering isolated mountain "lakes", but can still enter "coastal" mountains once shipbuilding is unlocked.

After some more experimenting though, I found a solution with potential. The modifier "MODIFIER_PLAYER_UNITS_ADJUST_VALID_TERRAIN" can have an argument of either 1 or 0. If the argument is set to 0, then the modifier actually does prevent units from entering the specified terrain type. So I can make mountains passable by default, but use the modifier to prevent entry into mountains under certain requirements.

The only issue I've found with this approach so far is that if a unit is prevented from entering a mountain tile, it cannot use a mountain tunnel that has been built on that mountain. I could try granting mountain tunnels a modifier that lets adjacent units enter mountains. But I expect that long range pathing like traders won't understand that they can actually go through mountain tunnels if they don't start adjacent to one. One potential solution to this problem might be with some clever manipulation of the "MODIFIER_MOUNTAIN_PORTAL" to apply to tiles adjacent to the mountain tunnel as well. However I don't understand anything about how that modifier works. I'd appreciate any advice for a workaround to allow units to use mountain tunnels even if they can't enter mountains normally, thanks!
 
The modifier "MODIFIER_PLAYER_UNITS_ADJUST_VALID_TERRAIN" can have an argument of either 1 or 0. If the argument is set to 0, then the modifier actually does prevent units from entering the specified terrain type.
Can you post the code?
 
Sure, what I have so far looks like this:

Code:
UPDATE Terrains SET Impassable='0'                    WHERE TerrainType LIKE 'TERRAIN_%_MOUNTAIN';
INSERT INTO Types (Type, Kind) VALUES
    ('MODIFIER_ALL_UNITS_ADJUST_VALID_TERRAIN', 'KIND_MODIFIER');
INSERT INTO DynamicModifiers (ModifierType, CollectionType, EffectType) VALUES
    ('MODIFIER_ALL_UNITS_ADJUST_VALID_TERRAIN', 'COLLECTION_ALL_UNITS', 'EFFECT_ADJUST_UNIT_VALID_TERRAIN');
INSERT INTO GameModifiers (ModifierId) VALUES
    ('MODIFIER_DENY_MOUNTAIN_GRASS_MOVEMENT'),
    ('MODIFIER_DENY_MOUNTAIN_PLAINS_MOVEMENT'),
    ('MODIFIER_DENY_MOUNTAIN_DESERT_MOVEMENT'),
    ('MODIFIER_DENY_MOUNTAIN_TUNDRA_MOVEMENT'),
    ('MODIFIER_DENY_MOUNTAIN_SNOW_MOVEMENT');
INSERT INTO Modifiers (ModifierId, ModifierType, SubjectRequirementSetId) VALUES
    ('MODIFIER_DENY_MOUNTAIN_GRASS_MOVEMENT', 'MODIFIER_ALL_UNITS_ADJUST_VALID_TERRAIN', 'REQUIRES_UNIT_CANT_ENTER_MOUNTAINS'),
    ('MODIFIER_DENY_MOUNTAIN_PLAINS_MOVEMENT', 'MODIFIER_ALL_UNITS_ADJUST_VALID_TERRAIN', 'REQUIRES_UNIT_CANT_ENTER_MOUNTAINS'),
    ('MODIFIER_DENY_MOUNTAIN_DESERT_MOVEMENT', 'MODIFIER_ALL_UNITS_ADJUST_VALID_TERRAIN', 'REQUIRES_UNIT_CANT_ENTER_MOUNTAINS'),
    ('MODIFIER_DENY_MOUNTAIN_TUNDRA_MOVEMENT', 'MODIFIER_ALL_UNITS_ADJUST_VALID_TERRAIN', 'REQUIRES_UNIT_CANT_ENTER_MOUNTAINS'),
    ('MODIFIER_DENY_MOUNTAIN_SNOW_MOVEMENT', 'MODIFIER_ALL_UNITS_ADJUST_VALID_TERRAIN', 'REQUIRES_UNIT_CANT_ENTER_MOUNTAINS');
INSERT INTO ModifierArguments (ModifierId, Name, Value) VALUES
    ('MODIFIER_DENY_MOUNTAIN_GRASS_MOVEMENT', 'Valid', '0'),
    ('MODIFIER_DENY_MOUNTAIN_GRASS_MOVEMENT', 'TerrainType', 'TERRAIN_GRASS_MOUNTAIN'),
    ('MODIFIER_DENY_MOUNTAIN_PLAINS_MOVEMENT', 'Valid', '0'),
    ('MODIFIER_DENY_MOUNTAIN_PLAINS_MOVEMENT', 'TerrainType', 'TERRAIN_PLAINS_MOUNTAIN'),
    ('MODIFIER_DENY_MOUNTAIN_DESERT_MOVEMENT', 'Valid', '0'),
    ('MODIFIER_DENY_MOUNTAIN_DESERT_MOVEMENT', 'TerrainType', 'TERRAIN_DESERT_MOUNTAIN'),
    ('MODIFIER_DENY_MOUNTAIN_TUNDRA_MOVEMENT', 'Valid', '0'),
    ('MODIFIER_DENY_MOUNTAIN_TUNDRA_MOVEMENT', 'TerrainType', 'TERRAIN_TUNDRA_MOUNTAIN'),
    ('MODIFIER_DENY_MOUNTAIN_SNOW_MOVEMENT', 'Valid', '0'),
    ('MODIFIER_DENY_MOUNTAIN_SNOW_MOVEMENT', 'TerrainType', 'TERRAIN_SNOW_MOUNTAIN');
INSERT INTO RequirementSets (RequirementSetId, RequirementSetType) VALUES
    ('REQUIRES_UNIT_CANT_ENTER_MOUNTAINS', 'REQUIREMENTSET_TEST_ALL');
INSERT INTO RequirementSetRequirements (RequirementSetId, RequirementId) VALUES
    ('REQUIRES_UNIT_CANT_ENTER_MOUNTAINS', 'UNIT_CANT_ENTER_MOUNTAINS');
INSERT INTO Requirements (RequirementId, RequirementType, Inverse) VALUES
    ('UNIT_CANT_ENTER_MOUNTAINS', 'REQUIREMENT_UNIT_HAS_ABILITY', 1);
INSERT INTO RequirementArguments (RequirementId, Name, Value) VALUES
    ('UNIT_CANT_ENTER_MOUNTAINS', 'UnitAbilityType', 'ABILITY_IGNORE_TERRAIN_COST');

This will allow helicopters (technically, units with the ability 'ABILITY_IGNORE_TERRAIN_COST') to move onto mountains, and prevent other units from moving onto mountains. However, like I said, it will also prevent all units except helicopters from using mountain tunnels, since technically, a unit must move onto a tunnel to use it. I'm still looking for a good way to solve that issue, and I'd appreciate any suggestions.
 
it will also prevent all units except helicopters from using mountain tunnels, since technically, a unit must move onto a tunnel to use it. I'm still looking for a good way to solve that issue, and I'd appreciate any suggestions.
Use code similar to this to allow helicopters to enter mountains.
 
Back
Top Bottom