1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

C++/Lua Request Thread

Discussion in 'Civ5 - SDK / LUA' started by Nefliqus, Jun 11, 2012.

  1. Harkodos

    Harkodos Warlord

    Joined:
    Feb 9, 2016
    Messages:
    178
    -EDIT-
    I've now solved my problem and a fully working FaithFromDyingUnits routine. It is limited in scope, only providing Faith from land units that are not unique to other civilizations (adding in compatibility for the possible thousands of unique units of other civilizations, or heck, even just the ones from the base game and expansions, does not sound fun).

    I may decide to post a modified version of the code later for use by other users, but right now I'd rather just enjoy the fruits of my labors.

    -OLD-
    Alright, let's try this once more. Still trying to get the "Units provide Faith from Dying" thing working, and now I've tweaked a code that formerly provided Specialist points in the Capital from killing enemy units. I'm trying to tweak it so it will simply provide Faith to a chosen Civilization when their units die, and I know that this code can work for what I need it to, I just don't have the proper knowledge to fully realize it. If anyone could help me tweak it to get the results I'm looking for, that'd be fantastic.

    Code here:
    Code:
    include("FLuaVector.lua")
    include( "ModTools.lua" );
    
    local defUnitID;
    function GetVoPDeadUnit(player, unitID)
       defUnitID = unitID;
       return false;
    end
    GameEvents.CanSaveUnit.Add(GetVoPDeadUnit);
    
    function FaithFromDyingUnit(attPlayerID,defPlayerID,defUnitTypeID)
        local attPlayer    = Players[attPlayerID];
        local defPlayer    = Players[defPlayerID];
        local defUnit    = defPlayer:GetUnitByID(defUnitID);
        if defPlayer:GetCivilizationType() ~= GameInfoTypes.CIVILIZATION_AMERICA then return end
        local fyModifier = 0;
        local fy = 0;
        local tempCount = 0;
        local maxCount = 0;
        local fyType = "YIELD_FAITH";
        local fyYield = GameInfo.Yields["YIELD_FAITH"];
        local fyID = fyYield.ID;
    
        if not defUnit then
          print("FaithFromDyingUnitNodefUnit!");
          return;
        end
      
        local fyPlayer = defPlayer:GetCivilizationType();--local fyCity = defPlayer:GetCapitalCity();
        local HexPos = ToHexFromGrid(Vector2( defUnit:GetX(), defUnit:GetY()));
        if not defUnit:IsCombatUnit() then
            print("FaithFromDyingUNitNotCombatUnit!");
           return;
        end
        if not IsMajorCiv(defPlayer) or not IsMajorCiv(attPlayer) then return;
        end
      
        print("FaithFromDyingUnitStartCalculate");
      
        local fyModifier = 50;
        if fyModifier == 0 then
           return;
        end
        local defCombat = defUnit:GetBaseCombatStrength();
        fy = defCombat*fyModifier;   
        --for pPlayer in defPlayer:CivilizationType() do
            for tempYield in  GameInfo.Yields() do
               local tempType = tempYield.Type;
               if tempType == "YIELD_FAITH" then
                  local tempID = tempYield.ID;
                  tempCount =player:GetFaith(tempID);
                  print("FaithFromDyingUnitFaith="..tempCount);
                  if tempCount > maxCount then
                     maxCount = tempCount;
                     fyType = tempType;
                     fyID = tempID;
                     fyPlayer = pPlayer;--fyCity = pCity;
                  end
               end
            end      
        --end
    print("FaithFromDyingUnitAddFaith");
    local rand = Game.Rand(100,"Faith From Dying Promotion");
    if fyPlayer then--if fyCity then
        fyPlayer:ChangeFaith(fyID,fy);--fyCity:ChangeFaith(fyID,fy);
    end
    print("FaithFromDyingUnitComplete");
    local popupstr = "+".. math.floor(fy/100).." [ICON_PEACE]" ;
    Events.AddPopupTextEvent(HexToWorld(HexPos),popupstr, 2);
    end
    
    GameEvents.UnitKilledInCombat.Add(FaithFromDyingUnit);
    And just to be safe and for reference, here's the original code I modified the above code from:
    Code:
    include("FLuaVector.lua")
    include( "ModTools.lua" );
    
    local defUnitID;
    function GetVoPDeadUnit(player, unitID)
       defUnitID = unitID;
       return false;
    end
    GameEvents.CanSaveUnit.Add(GetVoPDeadUnit);
    
    function AwardGreatPersonPoint(attPlayerID,defPlayerID,defUnitTypeID)
        local attPlayer    = Players[attPlayerID];
        local defPlayer    = Players[defPlayerID];
        local defUnit    = defPlayer:GetUnitByID(defUnitID);
        if attPlayer:GetCivilizationType() ~= GameInfoTypes.CIVILIZATION_AMERICA then return end
        local gpModifier = 0;
        local gp = 0;
        local tempCount = 0;
        local maxCount = 0;
        local gpType = "SPECIALIST_SCIENTIST";
        local gpSpecialist = GameInfo.Specialists["SPECIALIST_SCIENTIST"];
        local gpID = gpSpecialist.ID;
    
        if not defUnit then
          print("AwardCombatGPPNodefUnit!");
          return;
        end
      
        local gpCity = attPlayer:GetCapitalCity();
        local HexPos = ToHexFromGrid(Vector2( defUnit:GetX(), defUnit:GetY()));
        if not defUnit:IsCombatUnit() then    --Uncombat units do not count.
            print("AwardCombatGPPNotCombatUnit!");
           return;
        end
        if not IsMajorCiv(defPlayer) or not IsMajorCiv(attPlayer) then return;  -- City-States and Barbarian do not count;
        end
      
        print("AwardCombatGPPStartCalculate");
      
        --local Trait = GetPlayerTrait(attPlayer);
        local gpModifier = 50; --local gpModifier = Trait.CombatGPP;
        if gpModifier == 0 then
           return;
        end
        local defCombat = defUnit:GetBaseCombatStrength();
        gp = defCombat*gpModifier;   
        for pCity in attPlayer:Cities() do
            for tempSpecialist in  GameInfo.Specialists() do
               local tempType = tempSpecialist.Type;
               if tempType == "SPECIALIST_SCIENTIST" then
                  local tempID = tempSpecialist.ID;
                  tempCount =pCity:GetSpecialistGreatPersonProgress(tempID);
                  print("AwardCombatGPPSpecialistGPP="..tempCount);
                  if tempCount > maxCount then
                     maxCount = tempCount;
                     gpType = tempType;
                     gpID = tempID;
                     gpCity = pCity;
                  end
               end
            end      
        end
    print("AwardCombatGPPAddGPP");
    local TextType=" ";
    local name = gpCity:GetName();
    if gpType ==  "SPECIALIST_SCIENTIST" then
       TextType = TextType..Locale.ConvertTextKey("TXT_KEY_COMBAT_GREAT_SCIENTIST_POINT");
    end
    local Fin=" ";
    Fin = Fin..Locale.ConvertTextKey("TXT_KEY_IN");
    local rand = Game.Rand(100,"Great Scientist Points Promotion");
    if gpCity then
        gpCity:ChangeSpecialistGreatPersonProgressTimes100(gpID,gp);
    end
    print("AwardCombatGPPComplete");
    local popupstr = "[COLOR:255:87:155:255]+".. math.floor(gp/100).."[ENDCOLOR] [ICON_GREAT_PEOPLE] " ..TextType..Fin.." "..name.."." ;
    Events.AddPopupTextEvent(HexToWorld(HexPos),popupstr, 2);
    end
    
    GameEvents.UnitKilledInCombat.Add(AwardGreatPersonPoint); --Now works in quick combat mode.
    I've taken bits and pieces of different codes and seen them work to varying degrees of success, but I just know that this particular one hides the secrets to what I desire. I just need this particular code problem solved, and I can probably stop spamming this thread with requests as my other, early posts are mute at this point.
     
    Last edited: Apr 2, 2017
  2. psparky

    psparky Prince

    Joined:
    Feb 24, 2011
    Messages:
    401
    Gender:
    Male
    Can I trigger a save from LUA? Similar to an autosave - I just want it to happen with no action from me and preferably with no message displayed.

    The reason is that the game crashes sometimes, usually on the barbs turn or an AI turn, and I have to replay the turn. It happens often enough that I would like to do something to reduce the impact. What I want to do is to automatically save the game at the end of my turn before the other players turn. I can use the ActivePlayerTurnEnd event to identify the correct time to save, but have not found a method to make the save.

    Any help or thoughts appreciated.

    Update: I found the quicksave() routine (don't know how I missed it before) and called that from the ActivePlayerTurnEnd event. If sort of worked, but on loading the saved game, there were sometimes some odd side effects, so I guess that event is actually too late for what I want.
     
    Last edited: Jun 29, 2017
  3. GreatBayethe

    GreatBayethe Chieftain

    Joined:
    Jul 12, 2017
    Messages:
    20
    Gender:
    Male
    I want to add a trait that If my diplomats are in the other Capitals, the other Civs get 10% Tourism Pressure.
    So, I made a lua code, but I don't know what should I do next. Please help me.

    Code:
    local catherinetrait    =    GameInfoTypes["BUILDING_CATHERINE_FRANCE_TRAIT2"]
    function CatherineTourism(playerID)
        local pPlayer = Players[playerID]
        if pPlayer:GetCivilizationType() == catherine and pPlayer:IsAlive() then
            local iSurveillanceSpy = 0
            for i,v in pairs(pPlayer:GetEspionageSpies()) do
                if v.IsDiplomat then
            end
        end
    end
     
  4. Enginseer

    Enginseer Salientia of the Community Patch Supporter

    Joined:
    Nov 7, 2012
    Messages:
    3,215
    Gender:
    Male
    Location:
    Somewhere in California
    (pActivePlayer:IsMyDiplomatVisitingThem(iPlayer))

    Although, I don't know how to add tourism separately to each civ after this.
     
  5. GreatBayethe

    GreatBayethe Chieftain

    Joined:
    Jul 12, 2017
    Messages:
    20
    Gender:
    Male
    I want to boost science by producing per turn when my scientist appear. But, my code doesn't work. Please help me.


    Code:
    if pUnit:GetUnitClassType() == unitClassGreatScientistID then
                local teamID = pPlayer:GetTeam()
                local pTeam = Teams[teamID]
                local TurnScience = pPlayer:GetScience()
                local pTechs = pTeam:GetTeamTechs()
                pTechs:ChangeResearchProgress(pTechs, TurnScience, pPlayer)
            end
     
  6. Enginseer

    Enginseer Salientia of the Community Patch Supporter

    Joined:
    Nov 7, 2012
    Messages:
    3,215
    Gender:
    Male
    Location:
    Somewhere in California
    This can't be all. There's no GameEvent to initiate the code.
     
  7. GreatBayethe

    GreatBayethe Chieftain

    Joined:
    Jul 12, 2017
    Messages:
    20
    Gender:
    Male
    Well, there is a GameEvent under the code. It is omitted during copy and paste. So, it isn't a problem.
     
  8. Enginseer

    Enginseer Salientia of the Community Patch Supporter

    Joined:
    Nov 7, 2012
    Messages:
    3,215
    Gender:
    Male
    Location:
    Somewhere in California
    N
    No omitting. I want the rest of the code. You may have not even used the right GameEvent or function identifier.
     
  9. GreatBayethe

    GreatBayethe Chieftain

    Joined:
    Jul 12, 2017
    Messages:
    20
    Gender:
    Male
    Code:
    local JeongJo    =    GameInfoTypes["CIVILIZATION_JEONGJO"]
    local unitClassGreatScientistID      = GameInfoTypes["UNITCLASS_SCIENTIST"]
    function JeongJoGreatPeople(playerID, unitID, teamID)
     local pPlayer = Players[playerID]
     if pPlayer:GetCivilizationType() == JeongJo and pPlayer:IsAlive() then
      local pUnit = pPlayer:GetUnitByID(unitID)
      if pUnit:GetUnitClassType() == unitClassGreatScientistID then
       local teamID = pPlayer:GetTeam()
       local pTeam = Teams[teamID]
       local TurnScience = pPlayer:GetScience()
       local pTechs = pTeam:GetTeamTechs()
       pTechs:ChangeResearchProgress(pTechs, TurnScience, pPlayer)
      end
     end
    end
    
    Events.SerialEventUnitCreated.Add(JeongJoGreatPeople)
     
     
  10. Enginseer

    Enginseer Salientia of the Community Patch Supporter

    Joined:
    Nov 7, 2012
    Messages:
    3,215
    Gender:
    Male
    Location:
    Somewhere in California
    Try this.
    Code:
    local JeongJo    =    GameInfoTypes["CIVILIZATION_JEONGJO"]
    local unitClassGreatScientistID      = GameInfoTypes["UNITCLASS_SCIENTIST"]
    function JeongJoGreatPeople(playerID, unitID, hexVec, unitType, cultureType, civID, primaryColor, secondaryColor, unitFlagIndex, fogState, selected, military, notInvisible)
        local pPlayer = Players[playerID]
        if pPlayer:GetCivilizationType() == JeongJo and pPlayer:IsAlive() then
            local pUnit = pPlayer:GetUnitByID(unitID)
            if (pUnit:IsDead() or pUnit:GetUnitClassType() ~= unitClassGreatScientistID) then
                return
            end
            local iTurnScience = pPlayer:GetScience()
            local pTeamTechs = Teams[pPlayer:GetTeam()]:GetTeamTechs()
            pTeamTechs:ChangeResearchProgress(pPlayer:GetCurrentResearch(), iTurnScience, pPlayer:GetID())
        end
    end
    Events.SerialEventUnitCreated.Add(JeongJoGreatPeople)
    
     
  11. Troller0001

    Troller0001 Not an actual Troll

    Joined:
    Mar 9, 2016
    Messages:
    732
    Gender:
    Male
    Location:
    The Netherlands
    He should use Machiavelli's version of SerialEventUnitCreated though, as the normal SerialEventUnitCreated will fire when the player reloads the game, embarks the unit, or upgrades it (though the latter will not be a problem with the Scientist)
    LINK: Machiavelli's SerialEventUnitCreatedGood
     
  12. Enginseer

    Enginseer Salientia of the Community Patch Supporter

    Joined:
    Nov 7, 2012
    Messages:
    3,215
    Gender:
    Male
    Location:
    Somewhere in California
    The only thing that Machiavelli adds is a failsafe to ensure no duplicate unit code. I can just add one line and make one simple adjustment to ensure that the great scientist that was originally born isn't just re-made into the same coding again.
    Code:
    local JeongJo    =    GameInfoTypes["CIVILIZATION_JEONGJO"]
    local unitClassGreatScientistID      = GameInfoTypes["UNITCLASS_SCIENTIST"]
    function JeongJoGreatPeople(playerID, unitID, hexVec, unitType, cultureType, civID, primaryColor, secondaryColor, unitFlagIndex, fogState, selected, military, notInvisible)
        local pPlayer = Players[playerID]
        if pPlayer:GetCivilizationType() == JeongJo and pPlayer:IsAlive() then
            local pUnit = pPlayer:GetUnitByID(unitID)
            if (pUnit:IsDead() or pUnit:GetUnitClassType() ~= unitClassGreatScientistID or pUnit:IsHasPromotion(whateverthisstupidcodeis)) then
                return
            end
            pUnit:SetHasPromotion(whateverthisstupidcodeis, true)
            local iTurnScience = pPlayer:GetScience()
            local pTeamTechs = Teams[pPlayer:GetTeam()]:GetTeamTechs()
            pTeamTechs:ChangeResearchProgress(pPlayer:GetCurrentResearch(), iTurnScience, pPlayer:GetID())
        end
    end
    Events.SerialEventUnitCreated.Add(JeongJoGreatPeople)
    
     
  13. GreatBayethe

    GreatBayethe Chieftain

    Joined:
    Jul 12, 2017
    Messages:
    20
    Gender:
    Male
    Thank you. Well, I have another question. Can I spread tourism when my Musician birth by lua?
     
  14. Enginseer

    Enginseer Salientia of the Community Patch Supporter

    Joined:
    Nov 7, 2012
    Messages:
    3,215
    Gender:
    Male
    Location:
    Somewhere in California
    I don't think Tourism is a yield in BNW, thus you can't just add Tourism naturally via Lua. I mod mainly within CP DLL now, so I don't know.
     
  15. Troller0001

    Troller0001 Not an actual Troll

    Joined:
    Mar 9, 2016
    Messages:
    732
    Gender:
    Male
    Location:
    The Netherlands
    There is this code from the Futurism Tenet in BNW. (+250 Tourism to all Civilizations when a Great Writer, Artist or Musician is born)
    So just give your civ a dummy policy which has the same effect, but with your desired amount of tourism and instead only add it for the Musician unitclass.
    Code:
    <Policy_TourismOnUnitCreation>
            <Row>
                <PolicyType>POLICY_FUTURISM</PolicyType>
                <UnitClassType>UNITCLASS_WRITER</UnitClassType>
                <Tourism>250</Tourism>
            </Row>
            <Row>
                <PolicyType>POLICY_FUTURISM</PolicyType>
                <UnitClassType>UNITCLASS_ARTIST</UnitClassType>
                <Tourism>250</Tourism>
            </Row>
            <Row>
                <PolicyType>POLICY_FUTURISM</PolicyType>
                <UnitClassType>UNITCLASS_MUSICIAN</UnitClassType>
                <Tourism>250</Tourism>
            </Row>
        </Policy_TourismOnUnitCreation>
    
     
  16. GreatBayethe

    GreatBayethe Chieftain

    Joined:
    Jul 12, 2017
    Messages:
    20
    Gender:
    Male
    Thank you!
    Can I give bonuses by the number of policies and kinds of them that I have adopt when my specific building is in the city?
     
  17. Troller0001

    Troller0001 Not an actual Troll

    Joined:
    Mar 9, 2016
    Messages:
    732
    Gender:
    Male
    Location:
    The Netherlands
    I don't think I get what you mean... Do you want the effect to only appear when a Musician is spawned in a city with a specific building? If yes, you'd need a different approach than the dummy policies.
     
  18. GreatBayethe

    GreatBayethe Chieftain

    Joined:
    Jul 12, 2017
    Messages:
    20
    Gender:
    Male
    Not musician. I mean that for example, Can I get bonuses by kind of policies and the number of them when I have built Gyujanggak(Unique Building)?
     
  19. GreatBayethe

    GreatBayethe Chieftain

    Joined:
    Jul 12, 2017
    Messages:
    20
    Gender:
    Male
    To get tourism bonuses, I made the code. But It doesn't work well. I want that if the number of policies that I have adopt is 30 or more and less than 40, I get 5 tourism, and If it is 40 or more, I get 10.

    Code:
    local JeongJoDummy = GameInfoTypes["BUILDING_JEONGJO_DUMMY"]
    local JeongJoDummy2 = GameInfoTypes["BUILDING_JEONGJO_DUMMY2"]
    local JeongJoDummy3 = GameInfoTypes["BUILDING_JEONGJO_DUMMY3"]
    local JeongJoDummy4 = GameInfoTypes["BUILDING_JEONGJO_DUMMY4"]
    local GyujanggakID = GameInfoTypes["BUILDING_GYUJANGGAK"]
    function JeongJoGyujanggak(playerID, policyID)
        local pPlayer = Players[playerID]
        if pPlayer:GetCivilizationType() == JeongJo and pPlayer:IsAlive() then
            for pCity in pPlayer:Cities() do
                if pCity:IsHasBuilding(GyujanggakID) then
                    local NumberOfPolicies = pPlayer:GetNumPolicies()
                    if NumberOfPolicies >= 5 and NumberOfPolicies < 10 then
                        pCity:SetNumRealBuilding(JeongJoDummy, 1)
                    end
                    if NumberOfPolicies >= 10 and NumberOfPolicies < 15 then
                        pCity:SetNumRealBuilding(JeongJoDummy, 1)
                        pCity:SetNumRealBuilding(JeongJoDummy2, 1)
                    end
                    if NumberOfPolicies >= 15 and NumberOfPolicies < 20 then
                        pCity:SetNumRealBuilding(JeongJoDummy, 1)
                        pCity:SetNumRealBuilding(JeongJoDummy2, 2)
                    end
                    if NumberOfPolicies >= 20 and NumberOfPolicies < 25 then
                        pCity:SetNumRealBuilding(JeongJoDummy, 1)
                        pCity:SetNumRealBuilding(JeongJoDummy2, 2)
                        pCity:SetNumRealBuilding(JeongJoDummy3, 1)
                    end
                    if NumberOfPolicies >= 25 and NumberOfPolicies < 30 then
                        pCity:SetNumRealBuilding(JeongJoDummy, 2)
                        pCity:SetNumRealBuilding(JeongJoDummy2, 3)
                        pCity:SetNumRealBuilding(JeongJoDummy3, 1)
                    end
                    if NumberOfPolicies >= 30 and NumberOfPolicies < 40 then
                        pCity:SetNumRealBuilding(JeongJoDummy, 2)
                        pCity:SetNumRealBuilding(JeongJoDummy2, 3)
                        pCity:SetNumRealBuilding(JeongJoDummy3, 1)
                        pCity:SetNumRealBuilding(JeongJoDummy4, 1)
                    end
                    if NumberOfPolicies >= 40 then
                        pCity:SetNumRealBuilding(JeongJoDummy, 3)
                        pCity:SetNumRealBuilding(JeongJoDummy2, 4)
                        pCity:SetNumRealBuilding(JeongJoDummy3, 1)
                        pCity:SetNumRealBuilding(JeongJoDummy4, 0)
                        pCity:SetNumRealBuilding(JeongJoDummy5, 1)
                    end
                end
            end
        end
    end
    JeongJoDummy4 produces 5 tourism and JeongJoDummy5 does 10.
     
  20. Troller0001

    Troller0001 Not an actual Troll

    Joined:
    Mar 9, 2016
    Messages:
    732
    Gender:
    Male
    Location:
    The Netherlands
    You forgot to hook up a (Game)Event to your function, so it never runs.
    Try adding
    Code:
    GameEvents.PlayerDoTurn.Add(JeongJoGyujanggak)
    Adding one or more print()'s to the code allows you to spot these kinds of mistakes way easier when you open up the Lua.log.

    --
    I'm assuming that JeongJoDummy, JeongJoDummy2, and JeongJoDummy3 do not provide tourism as you add multiple copies of those while tourism doesn't stack.
     

Share This Page