Science on kill and other mod possibilities??

porkysports

Chieftain
Joined
Nov 22, 2011
Messages
16
Location
the Little Apple
I've been browsing and searching these forums the last few days for anyone that had any info on what I'm trying to add to my mod. (Thanks to Kael's Modder Guide for everything I have accomplished so far, which is more than I even thought I would be able to accomplish!) So figured I'd finally post and see if anyone has any ideas or thoughts on how one would go about about adding in these ideas.

The websites I build are in xml so that is what gave me the idea in the first place I might be able to pull off a mod. The building 2-d graphics part of things seems rather easy for me to understand as well and I might even look at seeing what it would take to be able to add the actual unit art later. What I can't do, at the current moment, is anything using LUA. I've tried peeking into learning that but realize now it would take a lot more time than I have at the current moment to even get started. So I'm hoping someone else has thought about adding in ideas similar to mine and found a way to do something like I want already?? :)

Science on Unit Kill:
I'm looking for a way to change the value of a few things when certain events trigger. For instance, there are promotions and policies that give culture or gold when you kill an enemy unit. I was hoping to change the reward given as science or research but can't for the life of me figure out how something like that could be done in xml alone.

Science on City Capture:
Much like the above but you get a science bonus, or free tech, when taking an enemy city.

Moai Science:
I was also hoping it was rather simple to change the Culture given from the Moai Statues to Science. After understanding how the development team incorporated Culture into things as opposed to the way they do the yields of Food, Gold and Science I see now it will probably take a lil more than my XML skills to accomplish something like this.

Mr. Knowitall:
I'd also like to add a trait to one of my units that improves the science yield of whichever tile he is standing on. Tho I saw in a couple of places on this forum this weekend that not only would that be a very tough thing to add in it would also be very hard to balance with the AI. So have given up on that.

So I guess what I'm asking is has anyone witnessed anything similar to these things already incorporated in a mod that I could look at as an example for my mod? Does anyone know if things like this can even be incorporated if I took the time to learn some LUA? OR would that be more like a source code type dealio.

Thanks in advance to anyone that can help!
 
Most of your answers boil down to the same thing:

I was hoping to change the reward given as science or research but can't for the life of me figure out how something like that could be done in xml alone.

XML does not work that way. If it's not explicitly there, you can't do it. Period. The XML you see in those files is simply a formatted input for an SQL converter the game uses; if you add a new table, a new schema, etc. then the game won't do anything with it. So no, you can't do anything like you've described solely in XML.

But, that's what Lua is for. You can make Lua functions that do all of the things you've described. It's quite a bit of work, of course, and there are a few inherent limitations at the moment (combat-related Events won't work in Strategic View, for instance), but you can still do it.
 
Thank You for the reply and explanation. I had a feeling that it was going to take more than XML to pull those things off.

The Science on Unit Kill and City Capture would be great for the mod I'm working on (and I think just a cool thing to have for any other future mods I might do.) So I guess it's time to start learning some Lua!

If (and I emphasize IF! lol)I ever figure it out I'll be sure to post what it takes exactly so if others would like to do something similar they can.
 
If (and I emphasize IF! lol)I ever figure it out I'll be sure to post what it takes exactly so if others would like to do something similar they can.

Or, you could just ask.

Code:
function MyEndCombat(iAttackingPlayer, iAttackingUnit, iDefendingUnitDamage, iAttackingUnitFinalDamage, iAttackingUnitMaxHitPoints, iDefendingPlayer, iDefendingUnit, iAttackingUnitDamage, iDefendingUnitFinalDamage, iDefendingUnitMaxHitPoints, bContinuation)
	local aPlayer;
	local aUnit;
	local aType = -1;
	local aName = "";

	local dPlayer;
	local dUnit;
	local dType = -1;
	local dName = "";

	if( iAttackingPlayer ~= -1 and  iAttackingUnit ~= -1  and iDefendingUnitFinalDamage >= iDefendingUnitMaxHitPoints) then
		aPlayer = Players[iAttackingPlayer];
		aUnit = aPlayer:GetUnitByID(iAttackingUnit);
		aType = aUnit:GetUnitType();
		aName = GameInfo.Units[aType].Type

		if aUnit:IsHasPromotion(GameInfoTypes.PROMOTION_RESEARCH_KILL) then
			local pTeamTechs = Teams[aPlayer:GetTeam()]:GetTeamTechs();
			pTeamTechs:ChangeResearchProgressTimes100(aPlayer:GetCurrentResearch(), 10000);
		end
	end

	if( iDefendingPlayer ~= -1 and iDefendingUnit ~= -1   and iAttackingUnitFinalDamage >= iAttackingUnitMaxHitPoints) then
		dPlayer = Players[iDefendingPlayer];
		dUnit = dPlayer:GetUnitByID(iDefendingUnit);
		dType = dUnit:GetUnitType();
		dName = GameInfo.Units[dType].Type

		if dUnit:IsHasPromotion(GameInfoTypes.PROMOTION_RESEARCH_KILL) then
			local pTeamTechs = Teams[dPlayer:GetTeam()]:GetTeamTechs();
			pTeamTechs:ChangeResearchProgressTimes100(dPlayer:GetCurrentResearch(), 10000);
		end
	end
end
Events.EndCombatSim.Add( MyEndCombat );

Now, this assumes you're intending to create a custom promotion (PROMOTION_RESEARCH_KILL) to designate this ability. If you want it to explicitly be by unit type, change the IsHasPromotion lines to
Code:
if (aName == "UNIT_MY_UNIT") then
or if you want it to be for all unit types, but unique to your one civilization, then
Code:
if ( aPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_MINE ) then
and the same for the defending unit check, replacing the "a" prefix with a "d".

The above code adds 100 beakers when the unit is killed; if you want to change the amount, change the 10000 down to 100 times whatever amount you decide on. (For instance, it could easily scale with the cost of the unit killed.)

And note, the above code will not work in Strategic View, or if the player has turned on the "Quick Combat" option. It's a known limitation of the Lua combat events.
 
:thumbsup: Holy Hannah! I Don't know if you had this previously built or just put it together just for me but either way thanks a ton!!! This sounds beautiful! And I didn't want to sound greedy and/or like I wasn't willing to put some sort of work into it. :) I think having something that I can work backwards from will help me out a lot in my venture into learning Lua.

I will go try to set up something similar and see if I have any luck with it.

Thanks for the last couple tips also. Good to know and understand that it still has it's limitations but should be able to be played in a format that will let it work, for the most part, as intended. I'll just need a few disclaimers!

Really excellent job!
 
I Don't know if you had this previously built or just put it together just for me but either way thanks a ton!!!

My mod (in sig) has a pretty hefty number of units that have triggered combat abilities like this. None of them explicitly give science, but I DO have several other functions (specifically, the Event code in my Mythology mod) that do give science, so I just mixed the two as necessary.

Other custom combat-related functions in my mod (spoiler'd because of the length):
Spoiler :
> A "rookie" promotion that gives all units -10% to combat in their first fight, but doubles the XP reward of that first fight.
> Unit types that begin with extra XP, or with extra "mutation" promotions randomly chosen from a set of tables.
> Nuke interception, with the percentage chance varying with how many civs you're at war with, what type of nuke is used, and so on.
> Units that can move across both land and sea.
> A whole series of units that adjust their strength up or down (within certain limits) depending on the strength of the opponent (so that it's almost always an even fight).
> Units that have a 10% chance of healing 5 points at the start of a fight, and units that have a 10% chance of dealing 5 additional damage at the end of a fight
> Units that take 1 less damage in every combat (meaning a minimum of 0 instead of 1), units that deal 1 extra damage in every combat, and units that do both but only when attacking.
> Units whose strength decreases as the enemy builds more instances of a certain defensive Project
> A missile that damages all enemies adjacent to the target and places Fallout in the target's hex
> A unit that gives a temporary defensive promotion to any unit passing within 2 hexes of it.
> Units that can plant Forests and Jungles, raise and lower hills, and terraform terrain
> A barbarian unit that awards anyone who kills it some Gold, but if left alone spawns other barbarian units as if it were a camp (and unlike a camp, it can spawn in your territory).
> Units that, instead of gaining XP, permanently gain a random promotion the opposing unit has (assuming they survive the fight), even if that promotion is a unique ability, and units that (again instead of XP) gain a random promotion that THEY can qualify for.
> Units that damage all foes adjacent to the target, but for each enemy damaged this way the unit's strength decreases by 10%.
> Units that heal all adjacent friendly units when they attack, but for each ally healed this way its strength decreases by 10%.
> Units that, if they kill an opposing unit, can spawn a copy of themselves (i.e., Zombies) and a unit that, when killed, spawns a copy of itself in your own capital (the Phoenix).
> Units that steal gold from the owner of the unit they attack, regardless of whether they actually kill the opposing unit or not.
> A unit promotion, given by a certain building, that makes it so that when any one of your units dies, an undead unit can spawn in the nearest friendly city. Similarly, I have a unit promotion, also given by buildings, that makes it so that if one of your units is killed inside your territory, its killer pays YOU gold (in reparations).


Point being, if you ever come up with an idea for a combat-related ability, we've probably already done something similar in Lua. I'm not the only one who's done stuff like this, of course, so look through some of the larger mods for inspiration if you feel yourself getting too bogged down in Lua.

And I didn't want to sound greedy and/or like I wasn't willing to put some sort of work into it.

Definitely a good attitude to have. It's just that this is one of those things that we've done more than enough times, and most of it's pretty straightforward once you understand Lua syntax. Using bits and pieces of other folks' code is not a big deal, and as you get the hang of Lua you'll get all sorts of ideas of things you can do.

And if you haven't done so already, make sure you bookmark this page of the wiki. You'll find yourself CONSTANTLY coming back to this, especially the Events, Player, Unit, and City pages that link off that page; without those pages, you'd have no way of knowing what is and isn't possible in Lua.
 
Just built a new promotion named Research_Kill, loaded it up and gained 100 science when I killed each barb! Beautiful! My sixth Civilization can now be built! Onto the Scenerio building!! And not only does it work great as a promotion you told me how to set it up basically as a UU and Civ Trait! :)

Most of your other combat-related mods sound pretty impressive also. Your Zombies/Phoenix builds sound like they would fit not only into my same mod but the exact same civilization!! I think I'll have to check your mods out.

And I was really hoping that someone had come up with something like this before. I didn't think the concept was too off the wall especially when you consider the fact Civ 1?? had it set so you would get a tech when you conquered a city I thought and this version has culture and gold variants already. I just know a lot of work can go into these types of things and didn't want to offend anyone that has taken the time to learn this type of stuff.

Thanks for the tip on the wiki page. I had already found that on my previous searching but never really looked to deep inside. Think I'll give it a lil better look.
 
Hey Spatzimaus. Didn't know if I could get some more help after I've fiddled with things for a couple of days and can't quite find the correct way of doing things.

You said earlier that in the code you gave me above the amount of Science given could be adjusted to the cost of the unit killed. I was wondering what it would take to do that? Actually I would like it to scale to the killed unit's strength if possible, similar to Monte's Culture kill trait.

I've been looking through all the lua files I can find and the Wiki pages to see if I can find exactly what I need to add in there to get it to identify the killed units strength but have had no luck. Found something in one of the Lua files called theirUnitStrength but don't think that's correct.

On a side note, while looking through the lua files for the korea dlc I saw something in there about
GameEvents.UnitKilledIncombat.Add similar to the regular Event.EndCombatSim.Add you use here. From what I can tell this code is what gives the player Future Tech Points when they kill an opposing civ's unit. I was wondering can GameEvents be used as Events? Would it be possible to use something like this event and get around the no animations or no strategic view?
 
You said earlier that in the code you gave me above the amount of Science given could be adjusted to the cost of the unit killed. I was wondering what it would take to do that? Actually I would like it to scale to the killed unit's strength if possible, similar to Monte's Culture kill trait.

There are two ways to do this:
1> A direct database read.
Take the code I gave before. The key is the line
aName = GameInfo.Units[aType].Type

You can just use a database access, like
aSTR = GameInfo.Units[aType].Combat;
to get a unit's strength. (Note that Combat is the melee strength. ".RangedCombat" is for ranged attacks.) Do the same for the defending unit. Similarly, GameInfo.Units[aType].Cost gives the cost in hammers, .Description gives the text key, and so on down the line of every value within the <Units> block.

(Note that this only modifies the unit's BASE strength value, not its "current" strength as boosted by promotions, terrains, and such.)

2> Unit:GetBaseCombatStrength() and Unit:GetBaseRangedCombatStrength().
These aren't quite as reliable, so I don't use them. The main reason they come up is that there's a Unit:SetBaseCombatStrength() function that you can use to override the base game's values. (I use this for the Psi units in my mods.) These functions are useful for telling if a unit's been shifted using that Set function. Also, for no apparent reason there are Gets for the Combat strength and Ranged Combat strength, but there's only a Set for Combat, and no Set for RangedCombat. It's not just the wiki, the function just doesn't exist at all.


So go with either of the above. (I suggest option #1.) Now, in the file I gave you, in the part that says
Code:
			pTeamTechs:ChangeResearchProgressTimes100(aPlayer:GetCurrentResearch(), 10000);
replace the "10000" with, say, "(200*dSTR)". (Note dSTR for the line that boosts aPlayer's research, and vice versa.) That'd give 2 beakers per point of strength, so a dead Warrior would give 12 beakers, a dead Tank would give 100, and so on. Note that Workers, Settlers, Air units, missiles, and Great People all have zero Combat, so this method would give nothing for killing/capturing one of those; you could easily add a minimum, like (200*dSTR + 500), or just add a special check like
if dSTR == 0 then dSTR = 20 end;
to give a flat amount for these types of units.

There's one other thing to note: the code I gave before would work fine if a unit attacked a city, or vice versa. (Cities trigger the combat events with the correct player number, hit points, damage, etc., but their unit ID number will always be -1.) But if you want to use that strength to set the reward, though, then you'll need to make sure it's a unit-on-unit combat, or else that Combat read above will fail as there'll be no unit type to parse. So you'd need to put that whole thing inside something like
Code:
if ( iAttackingUnit >= 0 and iDefendingUnit >= 0 ) then
and if you feel like it, throw on an Else to give a flat amount when a city is involved.

On a side note, while looking through the lua files for the korea dlc I saw something in there about
GameEvents.UnitKilledIncombat.Add similar to the regular Event.EndCombatSim.Add you use here. From what I can tell this code is what gives the player Future Tech Points when they kill an opposing civ's unit. I was wondering can GameEvents be used as Events? Would it be possible to use something like this event and get around the no animations or no strategic view?

I don't buy the DLCs (why bother when I keep making content of my own?), and that one isn't on the wiki's list of GameEvents (although that part of the wiki hasn't been updated in far too long). But assuming it works, yes, that'd be a far better choice than the EndCombatSim, assuming you ONLY want combat effects that trigger when a unit is killed. Since most of my other combat effects don't require a unit to die to be used, that GameEvent wouldn't help me very much, but for you it'd be fine. Since I don't have the DLC, though, I have no idea what the argument list for that event would be, and I can't guarantee exactly when it'll trigger in relation to any other Lua events.
 
Tried the first option as you suggested and it too works beautifully!! And I think that part is setup better than I ever thought I would be able to set it up! I'll get to adding in the base modifier for civilian and air/missile types later...:thumbsup: Thank you for the help!

On the DLC content... I understand it wouldn't really fit your current needs but would you be interested in what's posted in the Scenerio's Lua file that talks about the GameEvent.UnitKilled.Add?

And do you know is it even safe for me to post either part of or the entirety of one of Firaxis' Lua files? I don't know what type of code gets posted on these forums, I see a ton!, and not for sure where it comes from. If it's all from users or some of the "official" files thrown in. I would think all of the mods started by people looking at what was already built and going from there but don't know if they had intended for any part of an actual file to be posted on a forum. I would be more than happy to either cut out the section that talked about the specific GameEvent or that whole file if you thought I would be ok doing it and not breaking any rules if you wanted to see it for future knowledge.
 
And do you know is it even safe for me to post either part of or the entirety of one of Firaxis' Lua files?

It's not really okay. It's copyrighted material; I know, it's strange because modifying most Lua or non-gamedata XML requires copying the entirety of the original, so if you were to make a mod that modified that file it'd be okay to post your mod. But if you're just posting the contents of a DLC for the sake of providing its information to someone who doesn't have the DLC... well, I wouldn't.

Anyway, it's not really a problem. There's a trick with Lua where you write a "listener" function like this:
Code:
function TestFunction(...)
  print(unpack({...}));
end
Events.Whatever.Add( TestFunction);
(replacing "Whatever" with the name of the function, and changing the Events to a GameEvents call if necessary).

When you run that, it'll list, in order, the arguments of the function. Not the variable names, but the values each time the function triggers; in most cases, though, it's pretty obvious what each value means, since nearly every GameEvent has a player ID, a city/unit ID, and an X and Y position as an argument. So once you know the name of the event function, it's pretty easy to work out the rest.
 
Ok, I was afraid of that. So I am now hoping I can look at both your code and their code and put the two together so I'll try that when I get time. And Like you said, a lot of the variables in there so far from what I've seen look very easily deciphered.

I'll update later with hopefully good news!! :)

Thanks again for the time and effort!
 
@Spatzimaus,

I need to do something like this but I need to know exact xp gained by both attacker and defender. I don't see xp in any of the EndCombatSim arguments. However, it seems like it could be calculated from all of the args if I knew the equation.

Alternatively, I guess I could grab xp from both units on both RunCombatSim and EndCombatSim. I don't have much experience with these but I assume they are before and after combat. Of course I'd have to check to see that both units exist after. Would that work and would it be my best approach?
 
I need to do something like this but I need to know exact xp gained by both attacker and defender. I don't see xp in any of the EndCombatSim arguments. However, it seems like it could be calculated from all of the args if I knew the equation.

There is no equation. XP is a flat value that depends only on the XPgranted variables in the Units table and/or the XP-related global values in GlobalDefines. None of the arguments for RunCombatSim or EndCombatSim (all of which deal with how much damage was dealt in each direction) make any difference at all in the amount of XP given.
So you CAN change the amounts given; in my own mods, for instance, I lowered all air units to only gain 2 XP per fight instead of 4. But the amount doesn't vary from fight to fight, with the exception of certain unit types that can participate in multiple types of combat (ranged, melee, interceptions, etc.) I'd tell you exactly which variables to change, but I'm out of town at a conference and won't be home until this weekend.

I don't have much experience with these but I assume they are before and after combat. Of course I'd have to check to see that both units exist after.

Not exactly. It's more like "before the amount of damage dealt is finalized" and "after the amount of damage dealt is finalized" which is mostly the same thing, but you might occasionally run into problems because a killed unit won't be fully dead by the time EndCombatSim triggers. He'll be MOSTLY dead, which means slightly alive... never mind. Point is, it's not quite as simple as you might think, because the game can execute multiple combats simultaneously and the UI might fall a bit behind as a result. As these two events are UI-driven, their timing can occasionally be off; I've had times where the EndCombatSim function began before the corresponding RunCombatSim event had ended. Any EndCombatSim event should check to see if the final damage taken is less than the participants' maximum HP, just to be on the safe side.
 
Well this is going to save me 4 or 5 hours. I knew about the unit xml tags, but I was convinced for some reason that xp wasn't that simple (perhaps remembering Civ4).

There is XPValueAttack and XPValueDefense, which are usually both 3 (exceptions: workboats only have XPValueDefense; other civilian don't have either; air units have XPValueDefense=2 and XPValueAttack=3; missile only has XPValueDefense=2). However, it's still not clear to me who gets what xp value. Does the attacker gain xp equal to its own XPValueAttack, the defender's XPValueAttack, or the defender's XPValueDefense? Similar queston for the defender. (I'm trying to figure out the sensible answer based on the workboat values above, but only confusing myself more.) Also, is xp completely unaffected by victory?

I'm not trying to change xp. But I need to capture all xp gained in the game from every source (even buildings, but that's a different topic). That should not include a unit that dies in combat, so I'll compare iAttackingUnitFinalDamage and maximum HP as you suggest. Can I take it that iAttackingUnitFinalDamage really means final (cumulative) damage for this unit and not just damage from this event?

Also, are iDefendingUnitDamage and iAttackingUnitDamage swapped in your code above--
Code:
iAttackingPlayer, iAttackingUnit, iDefendingUnitDamage, iAttackingUnitFinalDamage, iAttackingUnitMaxHitPoints, iDefendingPlayer, iDefendingUnit, iAttackingUnitDamage, iDefendingUnitFinalDamage, iDefendingUnitMaxHitPoints
--or is this just random arg ordering by the developers?
 
Well this is going to save me 4 or 5 hours. I knew about the unit xml tags, but I was convinced for some reason that xp wasn't that simple (perhaps remembering Civ4).

It might not even use those, and might just be using the globals in GlobalDefines. Look for something like XP_ATTACKING_AIR or something like that. But yes, it's a VERY simple system; once you know how much XP a unit gets from a fight, it'll get the same amount in every fight of that type.

Now, you can tweak this in other ways; in my Empires mod there's an "Elite" promotion given by the Military Academy (in lieu of the old XP boost) that makes the unit gain +25% XP in every fight (and also adds +1 visibility and makes upgrades 20% cheaper for that unit, but those don't really apply to this issue). Likewise, my Rookie promotion makes every unit gain twice the normal XP from its first fight. So it IS possible to have varying amounts per fight, through other mechanisms.

Also, is xp completely unaffected by victory?

Yes. It doesn't matter how much damage is dealt, if the opponent is killed, etc.; if the unit is in the fight and survives, it gains X experience. If you want to add a mechanism where a unit gains bonus experience for killing its opponent, you can add logic for this in EndCombatSim, although simply using ECS puts several uncomfortable limitations on your gameplay; no Quick Combat, and no Strategic View. But if you're using the CombatSim functions anyway, then feel free to modify.

Can I take it that iAttackingUnitFinalDamage really means final (cumulative) damage for this unit and not just damage from this event?

Yes. iAttackingUnitDamage tells you how much damage the unit took before the fight started (I think; like I said, I'm not at home, and it might be how much damage was dealt in this fight. If you look in my Mythology mod, I use how much damage was dealt in the fight to allocate Favor so it'd be easy enough to check), and iAttackingUnitFinalDamage tells you how much cumulative damage it's taken at the end of the fight. The only thing this won't account for is mid-combat healing; if you put code in place to heal a unit +1 HP at the start of each combat, it won't change those numbers.

This is why the example code I posted at the top of this thread compared iAttackingUnitFinalDamage to iAttackingUnitMaxHitPoints; it doesn't check whether the unit IS dead (which'd make it hard to access the Units structure), it just checks whether the unit has taken so much damage that it WILL die once the combat completes. In theory, you could use this loophole to make a unit prevent its own death (heal enough damage so that it's left with 1 HP and doesn't die, and then retreat to an adjacent hex, for instance).

Also, are iDefendingUnitDamage and iAttackingUnitDamage swapped in your code above?

It's not a mistake. The order of arguments used by RunCombatSim is slightly different than the order used by EndCombatSim, with those two variables swapped. Yes, it's as stupid as it sounds. I hadn't noticed this for a long time since I didn't use those values in my own EndCombatSim-using functions, but once I did it was pretty easy to see what was going wrong.
 
OK so I should ignore Units.xml and only pay attention to the GlobalDefines.xml:
Spoiler :
Code:
		<Row Name="EXPERIENCE_PER_LEVEL">
			<Value>10</Value>
		</Row>
		<Row Name="EXPERIENCE_ATTACKING_UNIT_MELEE">
			<Value>5</Value>
		</Row>
		<Row Name="EXPERIENCE_DEFENDING_UNIT_MELEE">
			<Value>4</Value>
		</Row>
		<Row Name="EXPERIENCE_ATTACKING_UNIT_AIR">
			<Value>4</Value>
		</Row>
		<Row Name="EXPERIENCE_DEFENDING_UNIT_AIR">
			<Value>2</Value>
		</Row>
		<Row Name="EXPERIENCE_ATTACKING_UNIT_RANGED">
			<Value>2</Value>
		</Row>
		<Row Name="EXPERIENCE_DEFENDING_UNIT_RANGED">
			<Value>2</Value>
		</Row>
		<Row Name="EXPERIENCE_ATTACKING_AIR_SWEEP">
			<Value>5</Value>
		</Row>
		<Row Name="EXPERIENCE_DEFENDING_AIR_SWEEP_AIR">
			<Value>5</Value>
		</Row>
		<Row Name="EXPERIENCE_DEFENDING_AIR_SWEEP_GROUND">
			<Value>2</Value>
		</Row>
		<Row Name="EXPERIENCE_ATTACKING_CITY_MELEE">
			<Value>5</Value>
		</Row>
		<Row Name="EXPERIENCE_ATTACKING_CITY_RANGED">
			<Value>3</Value>
		</Row>
		<Row Name="EXPERIENCE_ATTACKING_CITY_AIR">
			<Value>4</Value>
		</Row>

So I can infer this in almost every situation by knowing who the attacker is. But: How do I know if the defender is a city? (What is iDefendingUnit in this case?) I have a unit line in the game that do both melee and ranged attack (elephant-mounted units). Any way to know which attack type was just performed?
 
But: How do I know if the defender is a city? (What is iDefendingUnit in this case?)

There is no "defender in a city" in Civ5. If a unit garrisons in a city then it boosts the city's defense rating, but the city always is the defender whenever it's attacked, not the units within it. If a city is attacked, iDefendingUnit is always -1, although iDefendingPlayer will still tell you which player owns the city being attacked. (Likewise, when a city bombards a unit, iAttackingUnit is -1.) For obvious reasons you can't use iDefendingUnit=-1 as the index in a Units structure, hence the if checks I put in the logic I posted above to make sure it wasn't negative.

There IS a way to extract the mission info from the attacking unit, to figure out where it was attacking. I don't have the command offhand, though. Without that, it's impossible to know which city was being attacked. It's even worse for nukes, since iDefendingPlayer = -1 for them as well as the nuke attacks a hex, not a city or unit.

Also note that while for a city iDefendingUnit = -1, it WILL at least use the correct values for the damage values like MaxHitPoints (20, or 25 in my mod). So if you really needed to you could figure out which city was attacked simply based on how damaged each city owned by that player is.

I have a unit line in the game that do both melee and ranged attack (elephant-mounted units). Any way to know which attack type was just performed?

Sure. If the attacking unit took no damage during this fight, it must have been a ranged attack, since melee attacks deal a minimum of 1 damage to both combatants. The mission info command I mentioned above could also tell you this, or you could check the distance between the two units' hexes (which doesn't rule out a range-1 ranged attack), but the damage bit is by far the best way.
 
Thanks for all the help. This makes things super easy now.

A couple final (I think) questions: If I grab experience from a unit during EndCombatSim, is that likely to be pre- or post-combat? (And if that has no definite answer, would the answer be different for RunCombatSim?) For the sole purpose of gathering information, is there any difference between using RunCombatSim and EndCombatSim?
 
If I grab experience from a unit during EndCombatSim, is that likely to be pre- or post-combat?

I'm honestly not sure. It'd be easy enough to find out; just make a RunCombatSim and an EndCombatSim event, and print the XP values for the units involved. I'd do it myself, but again, I'm out of town. My guess is that it'd be after the combat was resolved, but before the effects of the combat (like death) are applied.

For the sole purpose of gathering information, is there any difference between using RunCombatSim and EndCombatSim?

See previous answer. There's no question that RunCombatSim occurs before the combat actually takes place, because if you use the Kill() command to destroy the attacking unit during an RCS event, it prevents the combat from taking place and the defender is unharmed. (That's how I do the nuke inteception in my own mods.) I just don't know about ECS, though; it might be after the XP is gained, and might be before. You should just try it and see; what's the worst that can happen?

The thing with modifying XP through a SetExperience() function is that it's not an immediate effect. If you use a SerialEventUnitCreated function to check when the unit is first created, and give the unit a bunch of XP in that event, then the unit does get the XP, but can't actually USE it right away. The unit has to either wait until the next turn, or use it after participating in a combat. That's probably just a UI limitation in UnitPanel.lua, but there might be something on the internal side that doesn't treat XP as being truly awarded right away. So I don't know for sure how well an XP check during the combat would work. You're PROBABLY okay with using ECS for this, but it's definitely something to test in practice.
 
Back
Top Bottom