Unit:SetBaseCombatStrength

dartmor

Chieftain
Joined
Oct 23, 2010
Messages
55
Location
Russia
When unit receives damage, i need to change it's Base Combat Strength to % of damage received.
For example, Warrior with str 8 received 50% damage, down to 50/100.
So Warrior's str should be changed from 8 to 4 ( by half ).

I need it because i want to make attack in game more valuable. Currently when you attack enemy, you still has advantage dealing more damage, but it's a small one.

What i want it's if Warrior attacks another Warrior with both being at full health, it would end with something like 70-80/100 for attacker and 30-40/100 for defender.

This is my pseudo-code:
Code:
if  Unit:GetDamage() then
	Unit:SetBaseCombatStrength(int combat)
		combat=% of Damage
	end
end

I didn't found GameEvent/Event to trigger it, which one would suit? Or i don't need any event?
And i don't know how to change "combat" depending on % of damage received...
I still don't feel ok with lua, so please help here :)
I am working on huge mode that changes overall tactics and strategy of warfare in civ.
 
There isn't an event that fires when units are damaged. The ones I know of are for the animation system and are unsuitable for your needs. It will take a DLL mod to achieve what you want.
 
What does int means in "int Unit:GetDamage()" from modiki? Does it mean that "GetDamage" is integral that can be used?
Do i need Event/GameEvent to trigger "if Unit:GetDamage()" or no?

Pseudo-code update:
Code:
if  Unit:GetDamage() then
	Unit:SetBaseCombatStrength(int combat)
		combat = ( combat / 100 ) * GetDamage
	end
end

to Machiavelli24:
I am not sure about DLL. It changes only XML/SQL, right? I don't see any ways to achieve it through XML/SQL.
By the way, nice mode with "Race for Religion"
 
Update
Code:
GameEvents.PlayerDoTurn.Add(function()
print("1")
if  Unit:GetDamage() then
	print("2")
	local damage = unit:GetDamage()
[B]line 10 here[/B]	Unit:SetBaseCombatStrength(int combat)
		print("3")
		combat = ( combat / 100 ) * damage
end)

[90019.394] Syntax Error: C:\Users\Dartmor\Documents\My Games\Sid Meier's Civilization 5\MODS\Advance Warfare (v 1)\Lua/Lua Script1.lua:10: ')' expected near 'combat'
[90019.394] Runtime Error: Error loading C:\Users\Dartmor\Documents\My Games\Sid Meier's Civilization 5\MODS\Advance Warfare (v 1)\Lua/Lua Script1.lua.

I feel i am on the right way, but something must be still certainly wrong or missing
 
The error on line 10 is because you need to remove the word "int".

This goes back to your earlier question. The "int" in the parameter list tells you that combat is an integer, however you don't use int in the function call. Similarly, the "int" in "int Unit:GetDamage()" means that the GetDamage function returns an integer value.

There are many problems with your current code, but let's start with noticing that you're using the PlayerDoTurn event, which runs at the start of each player's turn rather than when combat occurs. That may actually be fine for your needs, if you are only concerned about changing the combat strength of the attacker (since, if you're attacking, it must be your turn). I'm confused a bit by your description of what you want to achieve, as something like that already exists in-game. A unit that's almost dead will be about half as effective. So you want to make the existing effect more pronounced for defenders?

Going back to your other question, the DLL is a large chunk of the game's C++ source code that Firaxis released. The Community Patch is a replacement DLL (not to be confused with the Community Balance Patch, part of the same project, and using the CP DLL). It has some additional combat events that you might use, if you were OK with your mod requiring the CP DLL to operate.

Other issues with your code:
First, the Unit in "Unit:GetDamage()" tells you that GetDamage() is a method of the Unit class, but when you make your function call, you're doing work related to a specific unit. So you need to replace "Unit" on your code with a variable containing a Unit object.

What you want may be to go through all of a player's units and make whatever adjustments you need every turn (note that I think that after doing a SetBaseCombatStrength(), the combat strength is only adjusted for the current turn, and returns to its default on the next turn, but I'm not entirely sure of that point).

You'd use a loop like:
Code:
for unit in player:Units() do
   ...
end
Then all of your Unit calls between "do" and "end" would be referring to a specific unit called "unit" with a lowercase u. The Units() function I used above is an iterator, meaning it will give you a list of all of the objects of that type. You also need to define WHICH player you want to do that loop on, but PlayerDoTurn has a parameter for the player ID of whose turn it is. So you need to change your code to give a name to that parameter. That appears to be line 5:
Code:
GameEvents.PlayerDoTurn.Add(function(iPlayer)
player = Players[iPlayer]
The second line is necessary to get a reference to the player itself, not just the player's ID (what I called iPlayer here). Now you can use methods of Player objects that refer to the player whose turn it is, like player:Units(), the iterator mentioned above.

Now when you use unit:GetDamage() within the "for unit" loop it will give you the number of hit points less than the maximum that a particular unit has (not how much damage it has just received), so your check is actually to see whether it's > 0.

...That's all I have energy for at the moment, but hopefully it gets you started. Good luck!
 
I was busy, restarting working with this modification.
I've found new event that seems to suit my case better, new pseudo-code:

Code:
Events.EndCombatSim.Add(

 function(attackingPlayer, attackingUnit, attackingUnitDamage, attackingUnitFinalDamage, attackingUnitMaxHitPoints, defendingPlayer, defendingUnit, defendingUnitDamage, defendingUnitFinalDamage, defendingUnitMaxHitPoints)

 local pAttackingPlayer = Players[attackingPlayer]
 local pDefendingPlayer = Players[defendingPlayer]
 local attackUnit = pAttackingPlayer:GetUnitByID(attackingUnit)
 local defendUnit = pDefendingPlayer:GetUnitByID(defendingUnit)
 local attackDamage = attackingUnitDamage
 
defendUnit:SetBaseCombatStrength(combat)
			print("SetBaseCombatStrength")
			combat = ( combat / 100 ) * attackDamage
end)

[1184.234] Lua Script2: SetBaseCombatStrength
[1184.234] Runtime Error: C:\Users\Dartmor\Documents\My Games\Sid Meier's Civilization 5\MODS\Advance Warfare (v 1)\Lua/Lua Script2.lua:17: attempt to perform arithmetic on global 'combat' (a nil value)

When enemy or my unit is attacked, it receives Strength = 0 after combat
i guess there is minor problem in
combat = ( combat / 100 ) * attackDamage

i think i need to get actual combat strength of unit, not from Unit:SetBaseCombatStrength(combat)?
 
Ok, it works somehow! update
Code:
Events.EndCombatSim.Add(

 function(attackingPlayer, attackingUnit, attackingUnitDamage, attackingUnitFinalDamage, attackingUnitMaxHitPoints, defendingPlayer, defendingUnit, defendingUnitDamage, defendingUnitFinalDamage, defendingUnitMaxHitPoints)

 local pAttackingPlayer = Players[attackingPlayer]
 local pDefendingPlayer = Players[defendingPlayer]
 local attackUnit = pAttackingPlayer:GetUnitByID(attackingUnit)
 local defendUnit = pDefendingPlayer:GetUnitByID(defendingUnit)
 local attackingDamage = attackingUnitDamage
 local defendingDamage = defendingUnitDamage
 local defendHP = defendingUnitMaxHitPoints
 local attackHP = attackingUnitMaxHitPoints
 local defendStrength = defendUnit:GetBaseCombatStrength()
 local attackStrength = attackUnit:GetBaseCombatStrength()

defendUnit:SetBaseCombatStrength(combat)
			print("SetBaseCombatStrength")
			combat = ( defendStrength / 100 ) * ( defendHP - attackingDamage )

attackUnit:SetBaseCombatStrength(combat)
			print("SetBaseCombatStrength 2")
			combat = ( attackStrength / 100 ) * ( attackHP - defendingDamage )

end)



But i have a feeling it don't count damage as i want to, maybe because of this:
[9535.420] Runtime Error: C:\Users\Dartmor\Documents\My Games\Sid Meier's Civilization 5\MODS\Advance Warfare (v 1)\Lua/Lua Script2.lua:18: attempt to index local 'attackUnit' (a nil value)
[9598.710] Runtime Error: C:\Users\Dartmor\Documents\My Games\Sid Meier's Civilization 5\MODS\Advance Warfare (v 1)\Lua/Lua Script2.lua:17: attempt to index local 'defendUnit' (a nil value)

With such errors it shouldn't work, but it works, odd
 
EndCombatSim is an odd beast. Many modders have concluded that it's nigh useless after one of the patches. It gets called more than once after a combat, and one or both of the units might be dead. It gets called after a city is attacked or is bombarding, and defendingUnit or attackingUnit will be nil in that case.

At least throw a check after attackUnit and defendUnit are defined, something like:
Code:
if (not attackUnit or not defendUnit) then
   return
end
 
Back
Top Bottom