Naval Healing mod?

shaglio

The Prince of Dorkness
Joined
Jun 15, 2001
Messages
3,721
Location
Lawrence, MA, USA
I play with a mod called “Naval Healing” by Barathor (I’m pretty sure he has since moved on from Civ 5 and into the realms of Civ BERT). This mod allows naval units to heal outside friendly territory and changes the Supply promotion to “heal on every turn regardless of whether it has performed an action” thus making naval units akin to land units. I recently implored him to update his mod for the Portuguese Nau UU, which he graciously did. I don’t know much about reading code, but this led me to believe his mod makes the change for every naval unit individually.

Several modded civ have naval UU replacements, and mods such as Enlightenment Era add many ships to bridge the gaps in Vanilla civ. Unfortunately, these aren’t affected by the Naval Healing mod (unless I implore Barathor to update it further for all these additional ships, which would be crazy).

My question is: would it be possible to make a mod that makes these changes to the “Naval Unit Class” rather than each individual unit (to account for future UUs and mods)? If so, would some kind soul be willing to do it for me? (I'm not sure about the modiquette and whether Barathor needs to be asked for permission or whatnot).
 
  • He added the promotion on a unit-by-unit basis because he really does not have much of a choice with XML-only modding.
  • Unfortunately there is no game-table in the UnitPromotions schema of the XML that allows specification of UnitClass as the determiner for whether a unit is to receive a promotion for free upon creation.
  • <UnitPromotions_UnitClasses> is used to specify which class of unit a promotion gives better or worse combat power against.
  • <UnitPromotions_UnitCombats> tells the game that a promotion is valid for a specified combat-type but does not actually give the promotion to these units.

Methods that would work:
  1. At the very least an SQL file would have to be added as a mod to the mod, and the SQL file would have to contain a trigger to give out the promotion to any units that 'ought' to get them.
  2. An lua script would have to be added to the mod as a modmod, and the Lua script would gather all units of unitclass x, y, and z into an lua-table and add the promotion to those units as they are created.
 
  • He added the promotion on a unit-by-unit basis because he really does not have much of a choice with XML-only modding.
  • Unfortunately there is no game-table in the UnitPromotions schema of the XML that allows specification of UnitClass as the determiner for whether a unit is to receive a promotion for free upon creation.
  • <UnitPromotions_UnitClasses> is used to specify which class of unit a promotion gives better or worse combat power against.
  • <UnitPromotions_UnitCombats> tells the game that a promotion is valid for a specified combat-type but does not actually give the promotion to these units.

That's what I was afraid of. I previously changed the XML file to upgrade Scouts to Musketmen. I was told something similar when I wanted to make a mod that would have the Scouting Class upgrade to Musketmen to accommodate for UU Scout replacements (like the Shoshone Pathfinder and the Garamantes Plumed Nomad).

Methods that would work:
  1. At the very least an SQL file would have to be added as a mod to the mod, and the SQL file would have to contain a trigger to give out the promotion to any units that 'ought' to get them.
  2. An lua script would have to be added to the mod as a modmod, and the Lua script would gather all units of unitclass x, y, and z into an lua-table and add the promotion to those units as they are created.

But, this makes it sound like it is indeed possible? :confused:
 
The SQL approach

Code:
-- This replaces the <Unit_FreePromotions> ... </Unit_FreePromotions> xml
-- and gives the free PROMOTION_OCEAN_PASSABLE promotion to all existing units of the given classes
INSERT INTO Unit_FreePromotions(UnitType, PromotionType)
    SELECT Type, 'PROMOTION_OCEAN_PASSABLE' FROM Units
        WHERE Class IN (
            'UNITCLASS_CARAVEL', 'UNITCLASS_FRIGATE', 'UNITCLASS_PRIVATEER',
            'UNITCLASS_IRONCLAD', 'UNITCLASS_DESTROYER', 'UNITCLASS_BATTLESHIP',
            'UNITCLASS_MISSILE_CRUISER',
            'UNITCLASS_CARRIER',
            'UNITCLASS_SUBMARINE', 'UNITCLASS_NUCLEAR_SUBMARINE'
        );

-- This ensures that any newly added unit,
-- where the default unit of the class has the PROMOTION_OCEAN_PASSABLE promotion,
-- also gets the free PROMOTION_OCEAN_PASSABLE promotion
CREATE TRIGGER OceanPassablePromotion
AFTER INSERT ON Units
WHEN EXISTS (SELECT 1 FROM UnitClasses uc, Unit_FreePromotions fp WHERE uc.Type = NEW.Class AND uc.DefaultUnit = fp.UnitType AND fp.PromotionType = 'PROMOTION_OCEAN_PASSABLE')
BEGIN
    INSERT INTO Unit_FreePromotions(UnitType, PromotionType)
    VALUES(NEW.Type, 'PROMOTION_OCEAN_PASSABLE');
END;

The slightly convoluted approach in the trigger is to avoid duplicating the UnitClass list, which makes maintenance easier.

There is still the problem that a completely new class of ships will need manual editing of the list in the first statement, buts there's nothing that can be done about that.
 
The SQL approach

Spoiler :
Code:
-- This replaces the <Unit_FreePromotions> ... </Unit_FreePromotions> xml
-- and gives the free PROMOTION_OCEAN_PASSABLE promotion to all existing units of the given classes
INSERT INTO Unit_FreePromotions(UnitType, PromotionType)
    SELECT Type, 'PROMOTION_OCEAN_PASSABLE' FROM Units
        WHERE Class IN (
            'UNITCLASS_CARAVEL', 'UNITCLASS_FRIGATE', 'UNITCLASS_PRIVATEER',
            'UNITCLASS_IRONCLAD', 'UNITCLASS_DESTROYER', 'UNITCLASS_BATTLESHIP',
            'UNITCLASS_MISSILE_CRUISER',
            'UNITCLASS_CARRIER',
            'UNITCLASS_SUBMARINE', 'UNITCLASS_NUCLEAR_SUBMARINE'
        );

-- This ensures that any newly added unit,
-- where the default unit of the class has the PROMOTION_OCEAN_PASSABLE promotion,
-- also gets the free PROMOTION_OCEAN_PASSABLE promotion
CREATE TRIGGER OceanPassablePromotion
AFTER INSERT ON Units
WHEN EXISTS (SELECT 1 FROM UnitClasses uc, Unit_FreePromotions fp WHERE uc.Type = NEW.Class AND uc.DefaultUnit = fp.UnitType AND fp.PromotionType = 'PROMOTION_OCEAN_PASSABLE')
BEGIN
    INSERT INTO Unit_FreePromotions(UnitType, PromotionType)
    VALUES(NEW.Type, 'PROMOTION_OCEAN_PASSABLE');
END;

The slightly convoluted approach in the trigger is to avoid duplicating the UnitClass list, which makes maintenance easier.

There is still the problem that a completely new class of ships will need manual editing of the list in the first statement, buts there's nothing that can be done about that.

Awesome! Now if only I knew SQL :( If I were to ask a modder to make this mod for me, would it be a monumental task or a quick, easy side project?

In hindsight, I suppose I should have asked this in the "Requested mods" thread rather than starting a new thread of my own, since I'm not a modder. But then it would have gotten washed out in the midst of all the other requests and responses.
 
Just use whoward's "My Changes" mod (there is a link in his sig) and drop the SQL code into the pre-provided SQL file in "My Changes". Then copy this from Barathor's mod:
Code:
<GameData>

	<UnitPromotions>
		<Update>
			<Where Type="PROMOTION_OCEAN_IMPASSABLE_UNTIL_ASTRONOMY"/>
			<Set IconAtlas="PROMOTION_ATLAS" PortraitIndex="5" HealOutsideFriendly="true"/>
		</Update>
		<Update>
			<Where Type="PROMOTION_OCEAN_IMPASSABLE"/>
			<Set IconAtlas="PROMOTION_ATLAS" PortraitIndex="5" HealOutsideFriendly="true"/>
		</Update>
		<Row>
			<Type>PROMOTION_OCEAN_PASSABLE</Type>
			<Description>TXT_KEY_PROMOTION_OCEAN_PASSABLE</Description>
			<Help>TXT_KEY_PROMOTION_OCEAN_PASSABLE</Help>
			<CannotBeChosen>true</CannotBeChosen>
			<Sound>AS2D_IF_LEVELUP</Sound>
			<LostWithUpgrade>true</LostWithUpgrade>
			<HealOutsideFriendly>true</HealOutsideFriendly>
			<PortraitIndex>5</PortraitIndex>
			<IconAtlas>PROMOTION_ATLAS</IconAtlas>
			<PediaType>PEDIA_ATTRIBUTES</PediaType>
			<PediaEntry>TXT_KEY_PEDIA_PROMOTION_OCEAN_PASSABLE</PediaEntry>
		</Row>
		<Update>
			<Where Type="PROMOTION_GREAT_ADMIRAL"/>
			<Set HealOutsideFriendly="true"/>
		</Update>
		<Update>
			<Where Type="PROMOTION_SUPPLY"/>
			<Set EnemyHealChange="0" NeutralHealChange="0" HealOutsideFriendly="0" AlwaysHeal="true"/>
		</Update>
	</UnitPromotions>

	<Language_en_US>
		<Row Tag="TXT_KEY_PEDIA_PROMOTION_OCEAN_PASSABLE">
			<Text>Can Enter Deep Ocean</Text>
		</Row>
		<Row Tag="TXT_KEY_PROMOTION_OCEAN_PASSABLE">
			<Text>Can Enter Deep Ocean</Text>
		</Row>
		<Update>
			<Where Tag="TXT_KEY_PROMOTION_SUPPLY_HELP"/>
			<Set Text="Unit will [COLOR_POSITIVE_TEXT]Heal Every Turn[ENDCOLOR], even if it performs an action."/>
		</Update>
	</Language_en_US>
	
</GameData>
into the XML file pre-provided in "My Changes". You should be good to go, then, to enable the "My Changes" mod, but you should disable the Naval Healing mod because otherwise it would tend to cause clashing.
 
I'll give it a shot when I get home from work. Thanks for the help guys :)
 
Just use whoward's "My Changes" mod (there is a link in his sig) and drop the SQL code into the pre-provided SQL file in "My Changes". Then copy this from Barathor's mod:

into the XML file pre-provided in "My Changes". You should be good to go, then, to enable the "My Changes" mod, but you should disable the Naval Healing mod because otherwise it would tend to cause clashing.

Clearly I'm not cut out for modding :( I opened WHoward's "My Changes Mod" zip, opened the SQL file in Notepad, copied and pasted his SQL code, and saved it as "ShaglioNavalHealingSQL.sql" Then I opened the XML file in Notepad, copied and pasted your XML code, and saved it as "ShaglioNavalHealingXML.xml" Then I put both of those files in a folder named "ShaglioNavalHealing" in my MODS folder, but when I go into the Mods Menu in-game it doesn't show up.

Clearly I'm doing something wrong, but with no modding experience beyond tweaking numbers in existing code, I have no idea what else I'm supposed to do. Admittedly, I did get confused by all the different files and folders in the "My Changes Mod" There's probably something in there that I needed to include because it was integral to tying all the files together.
 
Do NOT rename the files - there are references in the .modinfo file to them.
Do NOT rename the mod - there is a connection between the name of the directory and the name of the .modinfo file

Just copy/unzip the "My - Changes" empty mod in the MODS sub-directory and then add the changes directly to the files already in the mod and save them.

Then start Civ and enable the "My - Changes" mod.

When/If you have it all working, that's when you can start slowly renaming things if you must (but there is no need)
 
Thanks again! I'll give it another go tonight.
 
Back
Top Bottom