C++/Lua Request Thread

The location depends on the Scenario (since several of them came with the big G&K or BNW DLC).
Anyhow, this is the location of the Mongol Scenario (or well, for the lua for it at least, which is what's important for you): C:\Program Files (x86)\Steam\steamapps\common\Sid Meier's Civilization V\Assets\DLC\DLC_01. (this Scenario seems to be the most appropriate)
I've peeked a quick look into the lua and this is what I found (CivsAlive.lua):
Code:
function TestVictory()
    -- Game over?
    local iRemainingToDestroy, iTurnsRemaining = GetVictoryValues();
    if (iRemainingToDestroy < 1) then
        Game.SetWinner(Game.GetActiveTeam(), GameInfo.Victories["VICTORY_DOMINATION"].ID);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
    elseif (iTurnsRemaining < 1) then
        Game.SetGameState(GameplayGameStateTypes.GAMESTATE_OVER);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
    end
end
GameEvents.GameCoreTestVictory.Add(TestVictory);
Where you lose if you run out of time, and you win if you destroy a specific number of civs.

Good Luck ;)
Thank you!
I have checked through the scenarios, but all of them are based on victory conditions as opposed to failure conditions. I.e. I don't know how to push the other player to win when the current active civ has met the failure condition. The next best thing I can think of is using GetMilitaryMight == 0 code that you've mentioned and make it so that if the active player meets that condition, it's eliminated from play. Then using another loop to check total alive civs, and if that number is 1, i.e. only civ left, then declare the active civ a victory. However, I can't for the life of me find how to put the lua together. :cry::cry::cry:

Here's what I have so far:
Code:
function GetVictoryValues()
    local iNumPlayersLeft = 0;
    local iTurnsRemaining = 100 - Game.GetGameTurn();
   
    -- Loop through all the Majors
    for iPlayerLoop = 0, GameDefines.MAX_MAJOR_CIVS-1, 1 do
       
        if (Players[iPlayerLoop]:IsAlive()) then
            iNumPlayersLeft = iNumPlayersLeft + 1;
        end
    end
end

function CheckMilitarySize(iPlayer)
    local pPlayer = Players[iPlayer];
    if pPlayer:GetMilitaryMight() == 0 then
    --push the victory condition for the other player here
        Game.SetGameState(GameplayGameStateTypes.GAMESTATE_OVER);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
   end
end

GameEvents.PlayerDoTurn.Add(CheckMilitarySize)

function TestVictory()
    -- Game over?
    local iNumPlayersLeft, iTurnsRemaining = GetVictoryValues();
    if (iNumPlayersLeft == 1) then
        Game.SetWinner(Game.GetActiveTeam(), GameInfo.Victories["VICTORY_DOMINATION"].ID);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
    elseif (iTurnsRemaining < 1) then
        Game.SetGameState(GameplayGameStateTypes.GAMESTATE_OVER);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
    end
end
GameEvents.GameCoreTestVictory.Add(TestVictory);
How should I manipulate this?
 
Thank you!
I have checked through the scenarios, but all of them are based on victory conditions as opposed to failure conditions. I.e. I don't know how to push the other player to win when the current active civ has met the failure condition. The next best thing I can think of is using GetMilitaryMight == 0 code that you've mentioned and make it so that if the active player meets that condition, it's eliminated from play. Then using another loop to check total alive civs, and if that number is 1, i.e. only civ left, then declare the active civ a victory. However, I can't for the life of me find how to put the lua together. :cry::cry::cry:

Here's what I have so far:
Code:
function GetVictoryValues()
    local iNumPlayersLeft = 0;
    local iTurnsRemaining = 100 - Game.GetGameTurn();
 
    -- Loop through all the Majors
    for iPlayerLoop = 0, GameDefines.MAX_MAJOR_CIVS-1, 1 do
    
        if (Players[iPlayerLoop]:IsAlive()) then
            iNumPlayersLeft = iNumPlayersLeft + 1;
        end
    end
end

function CheckMilitarySize(iPlayer)
    local pPlayer = Players[iPlayer];
    if pPlayer:GetMilitaryMight() == 0 then
    --push the victory condition for the other player here
        Game.SetGameState(GameplayGameStateTypes.GAMESTATE_OVER);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
   end
end

GameEvents.PlayerDoTurn.Add(CheckMilitarySize)

function TestVictory()
    -- Game over?
    local iNumPlayersLeft, iTurnsRemaining = GetVictoryValues();
    if (iNumPlayersLeft == 1) then
        Game.SetWinner(Game.GetActiveTeam(), GameInfo.Victories["VICTORY_DOMINATION"].ID);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
    elseif (iTurnsRemaining < 1) then
        Game.SetGameState(GameplayGameStateTypes.GAMESTATE_OVER);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
    end
end
GameEvents.GameCoreTestVictory.Add(TestVictory);
How should I manipulate this?

I think that this might work [UNTESTED]
(assuming one army is player 0 (and is the human player) and the other army is player 1, which can be specified when creating a custom map)
Code:
local iPlayer0 = 0;
local iPlayer1 = 1;
local iAllmightyCommander = GameInfoTypes.PROMOTION_IM_THE_ALLMIGHTY_COMMANDER;

--the game immediately ends if one player kills the commander of the other, so only 1 variable is required
local iCommanderKilledOfPlayer = -1;


function IsArmyDead(iPlayer)
     local pPlayer = Players[iPlayer];
     if pPlayer:GetMilitaryMight() == 0 then
          print("the army of player "..iPlayer.." is dead");
          return true;
     end
     return false;
end

function CheckCommanderKilled(iPlayer,iUnit)
    local pPlayer = Players[iPlayer];
    local pUnit = pPlayer:GetUnitByID(iUnit);
    if pUnit:IsHasPromotion(iAllmightyCommander) then
          print("The Allmighty Commander of "..iPlayer.." has been killed!");
          iCommanderKilledOfPlayer = iPlayer;
          TestVictory();
    end
end
GameEvents.UnitPrekill.Add(CheckCommanderKilled);


function TestVictory()
    -- Game over?
    if (IsArmyDead(iPlayer1) or iCommanderKilledOfPlayer == iPlayer1) then
        --if the commander of a player is dead or the whole army is dead then the other player wins
        Game.SetWinner(Game.GetActiveTeam(), GameInfo.Victories["VICTORY_DOMINATION"].ID);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
        GameEvents.UnitPrekill.Remove(CheckCommanderKilled);
    elseif (IsArmyDead(iPlayer0) or iCommanderKilledOfPlayer == iPlayer0) then
        Game.SetGameState(GameplayGameStateTypes.GAMESTATE_OVER);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
        GameEvents.UnitPrekill.Remove(CheckCommanderKilled);
    end
end
GameEvents.GameCoreTestVictory.Add(TestVictory);
Now that I think of it, if you need to kill the whole army then that must mean you also have to kill the commander right (unless he is a civillian)?

Now, I'm not sure when 'GameCoreTestVictory' fires, but I assume it does so every turn. I will probably test this in the near future
 
Last edited:
I think that this might work [UNTESTED]
(assuming one army is player 0 (and is the human player) and the other army is player 1, which can be specified when creating a custom map)
Code:
local iPlayer0 = 0;
local iPlayer1 = 1;
local iAllmightyCommander = GameInfoTypes.PROMOTION_IM_THE_ALLMIGHTY_COMMANDER;

--the game immediately ends if one player kills the commander of the other, so only 1 variable is required
local iCommanderKilledOfPlayer = -1;


function IsArmyDead(iPlayer)
     local pPlayer = Players[iPlayer];
     if pPlayer:GetMilitaryMight() == 0 then
          print("the army of player "..iPlayer.." is dead");
          return true;
     end
     return false;
end

function CheckCommanderKilled(iPlayer,iUnit)
    local pPlayer = Players[iPlayer];
    local pUnit = pPlayer:GetUnitByID(iUnit);
    if pUnit:IsHasPromotion(iAllmightyCommander) then
          print("The Allmighty Commander of "..iPlayer.." has been killed!");
          iCommanderKilledOfPlayer = iPlayer;
          TestVictory();
    end
end
GameEvents.UnitPrekill.Add(CheckCommanderKilled);


function TestVictory()
    -- Game over?
    if (IsArmyDead(iPlayer1) or iCommanderKilledOfPlayer == iPlayer1) then
        --if the commander of a player is dead or the whole army is dead then the other player wins
        Game.SetWinner(Game.GetActiveTeam(), GameInfo.Victories["VICTORY_DOMINATION"].ID);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
        GameEvents.UnitPrekill.Remove(CheckCommanderKilled);
    elseif (IsArmyDead(iPlayer0) or iCommanderKilledOfPlayer == iPlayer0) then
        Game.SetGameState(GameplayGameStateTypes.GAMESTATE_OVER);
        GameEvents.GameCoreTestVictory.Remove(TestVictory);
        GameEvents.UnitPrekill.Remove(CheckCommanderKilled);
    end
end
GameEvents.GameCoreTestVictory.Add(TestVictory);
Now that I think of it, if you need to kill the whole army then that must mean you also have to kill the commander right (unless he is a civillian)?

Now, I'm not sure when 'GameCoreTestVictory' fires, but I assume it does so every turn. I will probably test this in the near future

I have tested this code and it works perfectly! I cannot express my gratitude!:bowdown::bowdown:

You have mentioned that it only requires one variable because it is a 1 vs 1, if I were to modify the code for more civs, how would I do that? Add more variables is what I would imagine but I'm still struggling with what everything means :confused::confused:
 
I have tested this code and it works perfectly! I cannot express my gratitude!:bowdown::bowdown:

You have mentioned that it only requires one variable because it is a 1 vs 1, if I were to modify the code for more civs, how would I do that? Add more variables is what I would imagine but I'm still struggling with what everything means :confused::confused:
Depends on what you want. I mean, how would a 1v1v1 interact? Would 2 players win if one of them kills the Almighty General? (You cannot detect which unit was the killer, you can only detect the killed unit in the unmodded DLL)
 
Depends on what you want. I mean, how would a 1v1v1 interact? Would 2 players win if one of them kills the Almighty General? (You cannot detect which unit was the killer, you can only detect the killed unit in the unmodded DLL)
Although, you're somewhat correct. You can detect a killer if it was melee(assuming that the melee unit takes over the spot over the killed unit)
 
Depends on what you want. I mean, how would a 1v1v1 interact? Would 2 players win if one of them kills the Almighty General? (You cannot detect which unit was the killer, you can only detect the killed unit in the unmodded DLL)
Would it be possible to use lua to eliminate civs? So the game checks for whether the Almighty Commander is alive or not. If not, remove the civ from game. Same goes for the GetMilitaryMight == 0, if so, eliminate from game, until number of active civs is 1 and then make active civ winner?
 
If they have no military left, they won't have anything to do so they could be considered to be eliminated; they can't train any (additional) units whatsoever!.
If the Almighty Commander gets killed, then you can probably use pPlayer:KillUnits(), which I assume kills all units of pPlayer.
I'm not sure if the is an actuall 'Kill' function for players.

Now that I think of it, you wouldn't even need 'Korea's Trait' from the 'Samurai Invasion of Korea'-scenario. You could just enable 'complete kills' in the game-setup, which means you can still eliminate civs from the game (by killing all of their units and cities), but that civs can still survive without cities!

EDIT: I'd recommend you'd create a specific thread for your Scenario Questions, that way we won't spam this thread ;)
 
If you made it work for 1 dummy building per technology, then changing it to 1 dummy building for 4 techs shouldn't be that difficult:
Assuming that the amount of dummy buildings given to a specific city is equal to a value of how many techs a player has, you can divide that value by 4.
This way, instead of dividing the yield by 4 (which results in decimal numbers), you just give 4 times as less dummies, which is pretty much what you want. ;)
Well, what I actually did took a lot of work and just used XML (cause I sorta suck at Lua). Basically, I added 80 Dummybuildings to my Civ, then gave them tags (FreeBuildingThisCity) so that each would provide the next (with the Palace providing the base) and then they all simply have a TechEnhancedYields tag so that each individual building has its own tech which will result in a +1 Culture yield. As I said, this method works but again, the +80 Culture per turn at endgame is quite powerful. In the meantime I did add something to de-buff the civ I'm making, but if I could, I'd rather not have the de-buff and just have the ability just provide a total of ~20 Culture by endgame.
 
If they have no military left, they won't have anything to do so they could be considered to be eliminated; they can't train any (additional) units whatsoever!.
If the Almighty Commander gets killed, then you can probably use pPlayer:KillUnits(), which I assume kills all units of pPlayer.
I'm not sure if the is an actuall 'Kill' function for players.

Now that I think of it, you wouldn't even need 'Korea's Trait' from the 'Samurai Invasion of Korea'-scenario. You could just enable 'complete kills' in the game-setup, which means you can still eliminate civs from the game (by killing all of their units and cities), but that civs can still survive without cities!

EDIT: I'd recommend you'd create a specific thread for your Scenario Questions, that way we won't spam this thread ;)
Okay, thank you for everything thus far! :D
 
Well, what I actually did took a lot of work and just used XML (cause I sorta suck at Lua). Basically, I added 80 Dummybuildings to my Civ, then gave them tags (FreeBuildingThisCity) so that each would provide the next (with the Palace providing the base) and then they all simply have a TechEnhancedYields tag so that each individual building has its own tech which will result in a +1 Culture yield. As I said, this method works but again, the +80 Culture per turn at endgame is quite powerful. In the meantime I did add something to de-buff the civ I'm making, but if I could, I'd rather not have the de-buff and just have the ability just provide a total of ~20 Culture by endgame.
That seems like a lot of work.

Anyhow, I think this small lua code would do the trick'
(Instead of using dummy buildings, I'm adding the culture directly. This does not show up in the +X culture per turn in the top UI. Since I'm not using dummies, it also means that buildings like the Broadcast Tower (+33% culture) do not increase this culture since it's not added via buildings)
Code:
local iCiv = GameInfoTypes.CIVILIZATION_CULTURE_EINSTEIN;
local iOneCulturePerNumTechs = 4;

function AddUABonusCulture(iPlayer)
     local pPlayer = Players[iPlayer];

     if pPlayer:GetCivilizationType() == iCiv then
          local pTeam = Teams[pPlayer:GetTeam()];
          local iNumTechs = pTeam:GetTeamTechs():GetNumTechsKnown(); 
          local iCultureToGrant = iNumTechs/iOneCulturePerNumTechs;
          pPlayer:ChangeJONSCulture(iCultureToGrant);
         print(iCultureToGrant.." Culture was given to "..pPlayer:GetName());
    end
end
GameEvents.PlayerDoTurn.Add(AddUABonusCulture);
The culture is added/updated at the start of every turn

Okay, thank you for everything thus far! :D
No problem, I have the time now and I'm glad I can help! ;)
I gotta return the favour to others too, since I have asked tons of questions here on Civfanatics :p
 
Oooo! Bueno! Just to be clear though: This ability will work with multiple iterations of the same Civ, right?
 
Hi all, I have another request (I'm so sorry:cry:, I know it seems greedy but lua is so confusing and I can't understand what most things do and when to use them!), I need this for a UB (Chronosphere from Red Alert 2) and was wondering if it's possible with lua. When the civ constructs this "superweapon" in a city (only 1 per civ), any unit adjacent to the city can be "teleported"(airlifted), to any tile already discovered by the Civ (so doesn't need to have LOS to the destination tile, but the tile cannot be "shroud"). Once that happens, the unit cannot do anything until the next turn (i.e. like any unit that uses airlift).
Thanks in advance!
 
I've recently been pondering with the idea of a unique Civ ability where: if a Civilization Razes a City, they receive a small amount of Faith that is adjusted for Gamespeed (100 at Standard Speed). That, or: whenever that Civ pillages a tile, a dummybuilding is added into their Capital providing +1 Faith (with no cap as to how many can be added).

These would be to replace another Civ ability I've been working on where said Civ would gain Culture and Faith from working pillaged tile improvements (this ability is definitely thematic and definitely powerful in the late game when lots of cities are likely to be conquered, but is unlikely to be of use much in the early game where Faith is most important, hence making the ability otherwise useless and very situational, seeing as even improved AIs via mods aren't 100% likely to pillage a tile just because they can).

Of course, this leads me into another quandary, this ability may have some use if it were possible to: enable said Civ to pillage improvements in Friendly Territory (possibly also incurring a small Diplomatic Penalty if done so in another player's territory).

If anyone is willing to help me out with any of these proposed ideas, that'd be super.

-EDIT-
Another question I have is: is it possible to replace the City Ruins improvement with one specific to a specific Civ for a UA? So say for instance: Said Civ razes a city, which generates a unique City Ruins Improvement which would then trigger a Culture Bomb effect, allowing them to keep the immediate surrounding terrain of that city. But then if one of that Civ's own cities is razed by another Civ (that presumably doesn't have said UA), then that razed city would not generate the unique City Ruins Improvement.

Adding the new improvement is no problem, it's making sure that the Civ with the UA can generate them from razing enemy cities that's the problem.

Actually, if anyone could simply help with the Razing a city to gain Faith, and the unique City Ruins Improvement upon razing an enemy city abilities, those two would probably be good enough for what I need.

-EDIT- #2
Okay I decided I'd just like to have a UA for a Civ where Razing a City provides Faith (100 at Standard Speed, 67 at Quick, etc.) and when a City has been Razed, all of that City's territory remains as a part of that Civ's territory instead of just retaining the portion adjacent to the City Ruins (hence, negating the need for a unique City Ruins Improvement).

If anyone could help with that specifically, that'd be great.
 
Last edited:
Alright, I've tried fiddling with the concept of receiving Faith from Razing a City, but I don't seem to be getting it. Here's the code I have so far (adapted somewhat from the code in the Alan Civilization).
Code:
function RazeFaith(playerID)
    local player = Players[playerID]
    if player:GetCivilizationType() == GameInfoTypes["CIVILIZATION_AMERICA"] then
        for city in player:Cities() do
            if Player:Raze() then
                if (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_QUICK"]) then
                    pPlayer:ChangeFaith(67)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_STANDARD"]) then
                    pPlayer:ChangeFaith(100)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_EPIC"]) then
                    pPlayer:ChangeFaith(150)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_MARATHON"]) then
                    pPlayer:ChangeFaith(300)
                else
                    pPlayer:ChangeFaith(100)
                end
                player:Disband(city)
            end
        end
    end
end
GameEvents.PlayerDoTurn.Add(RazeFaith)

        --for city in player:Cities() do
                --if city:GetPopulation() <= 0 then
                    --if (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_QUICK"]) then
                        --pPlayer:ChangeFaith(67)
                    --elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_STANDARD"]) then
                        --pPlayer:ChangeFaith(100)
                    --elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_EPIC"]) then
                        --pPlayer:ChangeFaith(150)
                    --elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_MARATHON"]) then
                        --pPlayer:ChangeFaith(300)
                    --else
                        --pPlayer:ChangeFaith(100)
                    --end
                    --player:Disband(city)
                --end
            --end
        --end
    --end
--end
--GameEvents.PlayerDoTurn.Add(RazeFaith)
The code at the top is what I'm using so far, and the code at the bottom is a snippet I have commented out for now, but I included it here just in case it might be of some use.
 
Alright, I've tried fiddling with the concept of receiving Faith from Razing a City, but I don't seem to be getting it. Here's the code I have so far (adapted somewhat from the code in the Alan Civilization).
Code:
function RazeFaith(playerID)
    local player = Players[playerID]
    if player:GetCivilizationType() == GameInfoTypes["CIVILIZATION_AMERICA"] then
        for city in player:Cities() do
            if Player:Raze() then
                if (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_QUICK"]) then
                    pPlayer:ChangeFaith(67)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_STANDARD"]) then
                    pPlayer:ChangeFaith(100)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_EPIC"]) then
                    pPlayer:ChangeFaith(150)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_MARATHON"]) then
                    pPlayer:ChangeFaith(300)
                else
                    pPlayer:ChangeFaith(100)
                end
                player:Disband(city)
            end
        end
    end
end
GameEvents.PlayerDoTurn.Add(RazeFaith)

        --for city in player:Cities() do
                --if city:GetPopulation() <= 0 then
                    --if (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_QUICK"]) then
                        --pPlayer:ChangeFaith(67)
                    --elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_STANDARD"]) then
                        --pPlayer:ChangeFaith(100)
                    --elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_EPIC"]) then
                        --pPlayer:ChangeFaith(150)
                    --elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_MARATHON"]) then
                        --pPlayer:ChangeFaith(300)
                    --else
                        --pPlayer:ChangeFaith(100)
                    --end
                    --player:Disband(city)
                --end
            --end
        --end
    --end
--end
--GameEvents.PlayerDoTurn.Add(RazeFaith)
The code at the top is what I'm using so far, and the code at the bottom is a snippet I have commented out for now, but I included it here just in case it might be of some use.

You have many inconsistencies already. Using "player" and "pPlayer" when they are supposed to be unified not to mention I don't think you're using the right Lua functions as well.
 
I vaguely understand what I'm doing, aside from the various pieces of code I keep referencing while working, I'm still learning how all this gobbledygook works.

I made some modifications, but the code still doesn't work. Could you tell me if I'm headed in the right direction?
Code:
local iCiv = GameInfoTypes.CIVILIZATION_AMERICA

function RazeFaith(iPlayer)
    local player = Players[iPlayer]
    if player:GetCivilizationType() == iCiv then
        for pCity in iPlayer:Cities() do
            if pCity:IsRazing() then
                if (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_QUICK"]) then
                    pPlayer:ChangeFaith(67)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_STANDARD"]) then
                    pPlayer:ChangeFaith(100)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_EPIC"]) then
                    pPlayer:ChangeFaith(150)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_MARATHON"]) then
                    pPlayer:ChangeFaith(300)
                else
                    pPlayer:ChangeFaith(100)
                end
            end
        end
    end
end
GameEvents.PlayerDoTurn.Add(RazeFaith)
 
While I'm at it, I'd like help with another UA that I'm trying to implement.

I'm trying to add a UA that enables that Civ's units to provide Faith equal to 50% of the Strength Value after they're defeated in Combat. I've looked over the method used by qqqbbb, but that method would require me to define unique variants for all of the standard land units in the game, very time consuming and needlessly complicated. The way I've been trying to implement it is with a unique Promotion, so as long as units have that promotion, they'll provide Faith when they expire.

The code in its current state provided here:
Code:
function FaithFromDying(playerID, iKiller, iOwner)
    local pPlayer = Players[playerID]
    if pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_AMERICA then
        for unit in player:Units() do
            local pUnit = pPlayer:GetUnitByID(unit)
            if (unit:IsHasPromotion(GameInfoTypes["PROMOTION_HK_MARTYR"])) and (pUnit:GetUnitType() == GameInfoTypes.UNIT_SCOUT) then -- I've shortened this considerably; only one unit needs to be present for reference.
                local function OnUnitKilledInCombat(iKiller, iOwner)
                    print(pUnit:GetX())
                    Players[iOwner]:ChangeFaith(Unit.GetBaseCombatStrength()/2)
            end
                end
        end
    end   
    end
end
GameEvents.UnitKilledInCombat.Add(OnUnitKilledInCombat)
GameEvents.UnitSetXY.Add(FaithFromDying)
 
I vaguely understand what I'm doing, aside from the various pieces of code I keep referencing while working, I'm still learning how all this gobbledygook works.

I made some modifications, but the code still doesn't work. Could you tell me if I'm headed in the right direction?
Code:
local iCiv = GameInfoTypes.CIVILIZATION_AMERICA

function RazeFaith(iPlayer)
    local player = Players[iPlayer]
    if player:GetCivilizationType() == iCiv then
        for pCity in iPlayer:Cities() do
            if pCity:IsRazing() then
                if (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_QUICK"]) then
                    pPlayer:ChangeFaith(67)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_STANDARD"]) then
                    pPlayer:ChangeFaith(100)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_EPIC"]) then
                    pPlayer:ChangeFaith(150)
                elseif (gameSpeed == GameInfo.GameSpeeds["GAMESPEED_MARATHON"]) then
                    pPlayer:ChangeFaith(300)
                else
                    pPlayer:ChangeFaith(100)
                end
            end
        end
    end
end
GameEvents.PlayerDoTurn.Add(RazeFaith)
Still inconsistent variables when they need to be unified.

While I'm at it, I'd like help with another UA that I'm trying to implement.

I'm trying to add a UA that enables that Civ's units to provide Faith equal to 50% of the Strength Value after they're defeated in Combat. I've looked over the method used by qqqbbb, but that method would require me to define unique variants for all of the standard land units in the game, very time consuming and needlessly complicated. The way I've been trying to implement it is with a unique Promotion, so as long as units have that promotion, they'll provide Faith when they expire.

The code in its current state provided here:
Code:
function FaithFromDying(playerID, iKiller, iOwner)
    local pPlayer = Players[playerID]
    if pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_AMERICA then
        for unit in player:Units() do
            local pUnit = pPlayer:GetUnitByID(unit)
            if (unit:IsHasPromotion(GameInfoTypes["PROMOTION_HK_MARTYR"])) and (pUnit:GetUnitType() == GameInfoTypes.UNIT_SCOUT) then -- I've shortened this considerably; only one unit needs to be present for reference.
                local function OnUnitKilledInCombat(iKiller, iOwner)
                    print(pUnit:GetX())
                    Players[iOwner]:ChangeFaith(Unit.GetBaseCombatStrength()/2)
            end
                end
        end
    end  
    end
end
GameEvents.UnitKilledInCombat.Add(OnUnitKilledInCombat)
GameEvents.UnitSetXY.Add(FaithFromDying)
... why not just let the UA provide the free promotion, and any unit that has that free promotion be granted faith...? Nevertheless, you already have excessive ends.
 
-For the first code box:
Still not unified you say? Could you provide a direct example, because from what I've been referencing, I've not been able to catch my mistakes (at present, it all looks like it should go through to me).

-For the second code box:
Well, the promotion itself can't exactly do that. Yes, the Civ receives the Promotion via the Traits table (specifically FreePromotionUnitCombat) But having the promotion itself does nothing. There was a Faith Belief FaithFromDyingUnit (or something along those lines) that was hinted at in the code, but does not actually have any functionality.

The basic thing I could do is use this code from the Kid Icarus Palutena Civilizatiob by OTiger (which was provided by qqqbbb):
Code:
local iCenturion = GameInfoTypes.UNIT_KI_CENTURION
local iFaithFromCenturion = 4

local function OnUnitKilledInCombat(iKiller, iOwner, iUnitType)
    if iUnitType == iCenturion then
        Players[iOwner]:ChangeFaith(iFaithFromCenturion)
    end
end
GameEvents.UnitKilledInCombat.Add(OnUnitKilledInCombat)
But the way that code works is while it is all-inclusive for any Centurion units, which are a unique unit, I need a method that can affect non-unique units for only a specific Civilization, hence why I have to use the code and fiddle with promotions and all that noise. Because there is no base code in Firaxis' game design that allows units to provide Faith in death, programming it in becomes necessary. Otherwise the option is to define Civilization-unique variants for all of the game's land-based military units, which adds more work than should be necessary.

Another code I've been using to try and get this to work is from the Ace Attorney Rayfa and Khura'in Civilization:
Code:
function KhurainDanceofDevotion(player, unit, x, y)
    local pPlayer = Players[player]
    if pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_KHURAIN then
        local pUnit = pPlayer:GetUnitByID(unit)
        if (pUnit:GetUnitType() == GameInfoTypes.UNIT_MISSIONARY) or (pUnit:GetUnitType() == GameInfoTypes.UNIT_INQUISITOR) or (pUnit:GetUnitType() == GameInfoTypes.UNIT_KHURAINIST_MONK) or (pUnit:GetUnitType() == GameInfoTypes.UNIT_PROPHET) then
            print(pUnit:GetX())
            if x < 0 then
                pPlayer:ChangeJONSCulture(Game.GetGameTurn())
            end
        end
    end
end
GameEvents.UnitSetXY.Add(KhurainDanceofDevotion)
I've been trying to adapt this code to use the bits from the Centurion code to get what I want (with a bit of code from the Alan Civilization in for the promotions). I know the bits and pieces for what I want are all here somewhere, I just haven't quite learned how to mash them together into something coherent just yet.
 
Top Bottom