Lua help

The theory behind implementing a bonus like this is relatively simple: get the amount of Horse resources the player owns using something of this structure (use "available" or "total" depending on if you only want to count Horse resources that aren't being used or just how many you own period):
Code:
Player:GetNumResourceTotal(eType, bIncludeImport)
Player:GetNumResourceAvailable(eType, bIncludeImport)
...where eType is the type of resource (in this case, RESOURCE_HORSE) and bIncludeImport is set to true if you want to include any resources you're receiving from trades with other Civs/City-States. After that, you iterate through all of the Civ's military units and give them a promotion based on how many Horses they had.

The problem lies with the fact it will require you to make 35 different promotions (+1% Strength, +2% Strength, +3% Strength etc) and add a bunch of checks to make sure you're giving the units the right one. Long story short: it's gonna be a lot of coding, but the idea is relatively simple. I can give a crack at it if I find some free time, but hopefully another kind soul can provide you the skeleton of what you need.
 
The problem lies with the fact it will require you to make 35 different promotions (+1% Strength, +2% Strength, +3% Strength etc) and add a bunch of checks to make sure you're giving the units the right one. Long story short: it's gonna be a lot of coding, but the idea is relatively simple.

Alternatively, you could just do +1%, +2%, +4%, +8%, +16%, and +32%, and have more than one active at once.
 
Alternatively, you could just do +1%, +2%, +4%, +8%, +16%, and +32%, and have more than one active at once.

That's definitely a possibility, and one I considered but discarded because I personally couldn't stomach having multiple promotions display for the same bonus :p If NiaoMeow can accept that, though, it would definitely cut down on the amount of promotions he'd need.
 
I think both would work... but I asked JFD and he said that there was some way to only have one promotion as long as it had a cap... but I might be delusional.

I was referring to Cyphose's proposition, in the sense that you would only have 1 promotion on the unit at any given time, so long as there was a cap.
 
There's also unit:SetBaseCombatStrength(iCombat). Use it in conjunction with unit:GetBaseCombatStrength() plus your modifier for number or horses.

Code:
BaseCombat = unit:GetBaseCombatStrength()
ModifiedCombat = math.floor((BaseCombat * (100 + NumberOfHorses)) / 100)
unit:SetBaseCombatStrength(ModifiedCombat)

All of this goes in a PlayerDoTurn event, with a loop through the player's units.
 
There's also unit:SetBaseCombatStrength(iCombat). Use it in conjunction with unit:GetBaseCombatStrength() plus your modifier for number or horses.

Code:
BaseCombat = unit:GetBaseCombatStrength()
ModifiedCombat = math.floor((BaseCombat * (100 + NumberOfHorses)) / 100)
unit:SetBaseCombatStrength(ModifiedCombat)

All of this goes in a PlayerDoTurn event, with a loop through the player's units.

And it should run only if number of horses that player has changes.

Are you sure this would work? Say a horseman unit has 16 combat strength, gains +10%, becomes 18, then the amount of horses change, if you fire it again, it'll take the 18 as the base, therefore becoming cumulative. You'd need something to 'reset' it to the original value, though that's a bit of an unreliable method, I presume. I tried using this method for Yugoslavia, ending up with using an absolute value as the base value, not unit:GetBaseCombatStrength(), because it would add more per turn. Or one could make a table of all combat units with the type and original combat strength. Though I think a bunch of promotions might work better in that case.

Or am I missing something here?
If so, ignore me. :)
 
GetBaseCombatStrength() retrieves the value of SetBaseCombatStrength(). But you can retrieve the GameInfo.Units[unitID].Combat instead.

Yeah, that seems like the best course of action. Forgot about that method :p

Code:
unitID = unit:GetID()
BaseCombat = GameInfo.Units[unitID].Combat
ModifiedCombat = math.floor((BaseCombat * (100 + NumberOfHorses)) / 100)
unit:SetBaseCombatStrength(ModifiedCombat)
 
Code:
unitID = unit:[COLOR="Blue"]GetUnitType()[/COLOR]
BaseCombat = GameInfo.Units[unitID].Combat
Also:
  • you are going to look up the same info from the game database multiple times per turn, every turn.
  • what about ranged units?
 
Several other issues with using SetBaseCombatStrength

1) you'll conflict with any other mod using this API method, unless you take quite complex steps to use get/set combinations to simulate a change method AND record/remember the number of horses last time around so you can change by a delta.

2) you'll need to test for combat being 0 and not make the change - or you'll change all civilian, ranged and air units into melee units

3) you'll be subject to integer maths - assuming a combat value of 15 and 6 horses, 15 * 1.06 = 15.9 which is still 15

4) other promotions will be multiplied by the change, not additive - assuming a combat value of 15 and 14 horses and the unit having shock 2 (+20%) the final combat value will be int(int(15 * 1.14) * 1.3) = 22 and not int(15 * 1.44) = 21, or going back to the 6 horse scenario int(int(15 * 1.06) * 1.3) = 19 and not int(15 * 1.36) = 20
 
What would happen if they got +1 Combat Strength instead of +1%?

Unit with base combat of 10 (warrior-ish), +1 is 10% bonus, unit with a base combat of 50 (infantry-ish), +1 is a 2% bonus

OK, if you want an early era bias.

Bite the bullet and use compound (+1, +2, +4) promotions - it's not as if there isn't a mod out there that deals with the multiple promotions issue ;)
 
Unit with base combat of 10 (warrior-ish), +1 is 10% bonus, unit with a base combat of 50 (infantry-ish), +1 is a 2% bonus

OK, if you want an early era bias.

Bite the bullet and use compound (+1, +2, +4) promotions - it's not as if there isn't a mod out there that deals with the multiple promotions issue ;)

I'd be fine doing that... I just don't understand how to make each promotion.


Code:
unitID = unit:[COLOR="Blue"]GetUnitType()[/COLOR]
BaseCombat = GameInfo.Units[unitID].Combat
Also:
  • you are going to look up the same info from the game database multiple times per turn, every turn.
  • what about ranged units?


Good point... what do I need to have to just have melee units gain the promotions?
 
I'd be fine doing that... I just don't understand how to make each promotion.
Making the promotions is the easy part, you do it through XML/SQL :p
Code:
<GameData>
	<UnitPromotions>
		<Row>
			<Type>PROMOTION_1_HORSE</Type>
			...
			<CannotBeChosen>true</CannotBeChosen>
			<CombatPercent>1</CombatPercent>
			...
		</Row>
		<Row>
			<Type>PROMOTION_2_HORSE</Type>
			...
			<CannotBeChosen>true</CannotBeChosen>
			<CombatPercent>2</CombatPercent>
			...
		</Row>
		etc.
	</UnitPromotions>
</GameData>
The "..." parts would be the other necessary promotion fields -- description, help tooltip, portrait, civilopedia info, etc. That's something you'll have to decide on.

As has been said before, you can either do this using promotions in powers of 2 (1, 2, 4, 8, 16, 32) and combining them in various ways, or you can make 35 promotions (with the final being +35%). The former involves less code but will display multiple promotions if the player has horses of any amount different than an exact power of 2, the latter involves more code but will display one promotion.

Good point... what do I need to have to just have melee units's gain the promotions?
The promotion I provided above will affect both melee and ranged units' strength, but if you wanted to affect only melee units, just search for the unit's CombatClass in the same way as JFD mentioned searching for the Combat--UNITCOMBAT_MELEE/UNITCOMBAT_MOUNTED designates a melee unit (and UNITCOMBAT_GUN if you want to include gunpowder units, which technically still function as melee). If you wanted to affect ranged units as well as melee, it can be done using the same info, just using UNITCOMBAT_ARCHER/UNITCOMBAT_SIEGE. Note that using CombatClass to distinguish between units can get a bit iffy, because there are a variety of CombatClasses to check for. I just named the biggest ones. It also wouldn't be compatible with any mod that messed with the CombatClasses, like NQMod (which adds Mounted Ranged units).

If you really want to only include Melee units, just check for the unit's Combat being >0 and RangedCombat == 0. Including Ranged units with this method requires simply changing the check to search for RangedCombat >0.
 
Placed at the top of the lua script:
Code:
local tUnitCombatTypesToAffect = { [GameInfoTypes.UNITCOMBAT_MELEE]=true, [GameInfoTypes.UNITCOMBAT_GUN]=true}
Placed somewhere in the PlayerDoTurn (for example)
Code:
for pUnit in pPlayer:Units() do
	if tUnitCombatTypesToAffect[pUnit:GetUnitCombatType()] then
		--add the promotions needed here based on number of horses available to the empire
	end
end
Then you only need to add or remove designations from the original definition of the lua table tUnitCombatTypesToAffect, and you do not list any UnitCombatTypes you do not want to have the promotions.

------------------------------------------------------------------------------------------------------------------------------------

It would also be pretty easy to alter the table tUnitCombatTypesToAffect to register unit-classes instead of unit-combat-types, and then adjust this line
Code:
if tUnitCombatTypesToAffect[pUnit:GetUnitCombatType()] then
to read as
Code:
if tUnitCombatTypesToAffect[pUnit:GetUnitClassType()] then
The reasoning for this alteration is that UNITCOMBAT_GUN includes a lot of stuff you might not want, such as AA Guns, Mobile Sams, and AT Guns.
 
...the latter involves more code but will display one promotion.

What about the Civilopedia promotion tab? :p

As for the text entries for all those promotions in the Civilopedia tab, you could simply use the same text for all of them, without defining 35 different TXT_KEY's. Simply use the TXT_KEY_1_HORSE_HELP text for all 35 promotion <Help>-tags. (I feel like I explained this very vague... :sad:)
 
What about the Civilopedia promotion tab? :p
Bah, who cares about the Civilopedia promotion tab anyway :lol:

In all seriousness, I'm fairly sure there's a way to not have promotions show up in the Civilopedia, but I'm not positive on how it's done. Is it as simple as not defining a <PediaType> or <PediaEntry>? I don't work with promotions often, and I'm always afraid to bug out the Civilopedia (since it can be done in any number of ways), so...

As for the text entries for all those promotions in the Civilopedia tab, you could simply use the same text for all of them, without defining 35 different TXT_KEY's. Simply use the TXT_KEY_1_HORSE_HELP text for all 35 promotion <Help>-tags. (I feel like I explained this very vague... :sad:)
The promotions can have the same <Description> (i.e. name) but not the same <Help>. Their <Help> tags would need to differ if you want to show the exact amount of strength being given, though if you wanted something general like "Increased :c5strength: Combat Strength from the empire's Horses" without any actual numbers, yeah they could all be the same.
 
Top Bottom