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

[SOLVED] Help with slavery mechanic

Discussion in 'Civ5 - Creation & Customization' started by TheOneHitPupper, Mar 25, 2020.

  1. TheOneHitPupper

    TheOneHitPupper Chieftain

    Joined:
    Jun 15, 2017
    Messages:
    84
    I'm trying to make a generic notification for the player after an enemy unit is killed and turned into a slave. I have the code necessary for the switch, but don't understand how to tie a notification to it. So far, I can only get it to work when an enemy enslaves the human player's units, which is the opposite of what I want. Here's the script I'm working with:

    Code:
    print("Battle capture script loaded")
    
    include("MischaIteratingPlotsFunctions")
    include("CityNearbyMapDatasV4")
    
    function BattleCapture(iPlayer, iUnit, iUnitType, iX, iY, bDelay, iByPlayer)
    
        local pPlayer = Players[iPlayer]
        local pByPlayer = Players[iByPlayer]
        local teamID = pPlayer:GetTeam()
        local pPlayerTeam = Teams[teamID]
        local pUnit = pPlayer:GetUnitByID(iUnit)
        print("Unit destroyed")
    
        print("iPlayer = " .. iPlayer)
        print("iByPlayer = " .. iByPlayer)
        
        -- Must have been killed by another Player
        if iPlayer == iByPlayer then return end
        if iByPlayer == -1 then return end
        
        local pPlot = pUnit:GetPlot()   
        for pAdjacentPlot in PlotAreaSweepIterator(pPlot, 1, SECTOR_NORTH, DIRECTION_CLOCKWISE, DIRECTION_OUTWARDS, CENTRE_EXCLUDE) do
            print("Checking plot")
            for iVal = 0,(pAdjacentPlot:GetNumUnits() - 1) do
                print("Checking unit")
                local loopUnit = pAdjacentPlot:GetUnit(iVal)
                if loopUnit:GetOwner() ~= iPlayer then
                    print("Not same owner")
                    local loopUnitOwner = loopUnit:GetOwner()
                    local otherPlayer = Players[loopUnitOwner]
                    local otherTeamID = otherPlayer:GetTeam()
                    local loopDMG = loopUnit:GetDamage()
                    if pPlayerTeam:IsAtWar(otherTeamID) then
                        if not (pAdjacentPlot:IsCity()) then
                            print("Target affected")
                            local sUnitType = GameInfoTypes.UNIT_LABORER_FREE
                            local nUnit = Players[iByPlayer]:InitUnit(sUnitType, pAdjacentPlot:GetX(), pAdjacentPlot:GetY())
                            nUnit:SetDamage(loopDMG)
                            print("Laborer spawned")
                            
                            if pPlayer:IsHuman() then
                                local title = "Enslaved Laborers!";
                                local descr = "You have successfully captured an enemy unit and enslaved them!";
                                pPlayer:AddNotification(NotificationTypes.NOTIFICATION_GENERIC, descr, title, pAdjacentPlot:GetX(), pAdjacentPlot:GetY());   
                                print("Notification added")
                            end
                        end
                    end
                end
            end
        end   
    end
    GameEvents.UnitPrekill.Add(BattleCapture)
    
    
    I've tried adding a notification onto pByPlayer because that's the variable that specifies which player's attacking and killing the other unit, but it doesn't execute at all when I do that. I don't see any log errors either. Any suggestions?
     
  2. TopHatPaladin

    TopHatPaladin Warlord

    Joined:
    Nov 5, 2017
    Messages:
    123
    Gender:
    Male
    Location:
    New England
    In this section of your code, you'll want to replace both instances of pPlayer with pByPlayer:
    Code:
    if pPlayer:IsHuman() then
        local title = "Enslaved Laborers!";
        local descr = "You have successfully captured an enemy unit and enslaved them!";
        pPlayer:AddNotification(NotificationTypes.NOTIFICATION_GENERIC, descr, title, pAdjacentPlot:GetX(), pAdjacentPlot:GetY());   
        print("Notification added")
    end
    pPlayer is currently defined to point to the player whose unit has just been killed, while pByPlayer points to the player responsible for the killing. Hence, the code as it currently stands provides a notification when your unit gets enslaved by a rival player.

    If I'm interpreting your message correctly, I suspect that you initially changed the code such that pByPlayer called AddNotification, but left it so that pPlayer was calling IsHuman. In this case, the reason the message didn't fire is because it was checking for whether it was the human player whose unit was enslaved— and then sending the notification, not to the human, but to the AI player who enslaved the unit.

    By changing both cases of pPlayer to pByPlayer, though, the notification should fire as intended.
     
    TheOneHitPupper likes this.
  3. TheOneHitPupper

    TheOneHitPupper Chieftain

    Joined:
    Jun 15, 2017
    Messages:
    84
    Haha to think it was something that simple. Thank you for the easy to understand explanation. I'm awful writing in Lua. If you could help, I've run into another problem, one that's been perplexing me for hours now.

    In-game, the code spawns a Laborer unit successfully, but if the attacking unit has another friendly unit next to them, it will spawn 2 Laborers instead. I've sort of cannibalized the code from another script and to rectify this issue I've been trying to get rid of all the loop variables. The new code I have initiates in-game with no log errors, but doesn't actually spawn any Laborers when it's supposed to. Any ideas? This is the code:

    Code:
    print("Battle capture script loaded")
    
    include("MischaIteratingPlotsFunctions")
    include("CityNearbyMapDatasV4")
    
    function JFD_GetRandom(lower, upper)
        return Game.Rand((upper + 1) - lower, "") + lower
    end
    
    function BattleCapture(iPlayer, iUnit, iUnitType, iX, iY, bDelay, iByPlayer)
    
        local pPlayer = Players[iPlayer]
        local pByPlayer = Players[iByPlayer]
        local teamID = pPlayer:GetTeam()
        local pPlayerTeam = Teams[teamID]
        local pUnit = pPlayer:GetUnitByID(iUnit)
        print("Unit destroyed")
    
        print("iPlayer = " .. iPlayer)
        print("iByPlayer = " .. iByPlayer)
        
        -- Must have been killed by another Player
        if iPlayer == iByPlayer then return end
        if iByPlayer == -1 then return end
        
        local pPlot = pUnit:GetPlot()   
        print("pUnitOwner is " .. pUnit:GetOwner())
        if pUnit:GetOwner() ~= iByPlayer then
            print("Not same owner")
            local pUnitOwner = pUnit:GetOwner()
            local otherTeamID = pByPlayer:GetTeam()
            local loopDMG = pUnit:GetDamage()
            if pPlayerTeam:IsAtWar(otherTeamID) then
                local randomNumber = JFD_GetRandom(1, 100)
                print("DMG is " .. loopDMG .. ", random number is " .. randomNumber)
                if (randomNumber < 100) and not (pPlot:IsCity()) then
                    print("Target affected")
                    local sUnitType = GameInfoTypes.UNIT_LABORER_FREE
                    local nUnit = pByPlayer:InitUnit(sUnitType, pPlot:GetX(), pPlot:GetY())
                    nUnit:SetDamage(loopDMG)
                    print("Laborer spawned")
                    
                    if pByPlayer:IsHuman() then
                        local title = "Enslaved Laborers!";
                        local descr = "You have successfully captured an enemy unit and enslaved them!";
                        pByPlayer:AddNotification(NotificationTypes.NOTIFICATION_GENERIC, descr, title, pPlot:GetX(), pPlot:GetY());   
                        print("Notification added")
                    end
                end
            end
        end   
    end
    GameEvents.UnitPrekill.Add(BattleCapture)
    
    
     
  4. TheOneHitPupper

    TheOneHitPupper Chieftain

    Joined:
    Jun 15, 2017
    Messages:
    84
    Found the problem. The damage applied to the new unit was 100, so the Laborer Unit would instantly die. Another easy fix haha. Here's the code for anyone interested.

    Code:
    print("Battle capture script loaded")
    
    include("MischaIteratingPlotsFunctions")
    include("CityNearbyMapDatasV4")
    
    function JFD_GetRandom(lower, upper)
        return Game.Rand((upper + 1) - lower, "") + lower
    end
    
    function BattleCapture(iPlayer, iUnit, iUnitType, iX, iY, bDelay, iByPlayer)
    
        local pPlayer = Players[iPlayer]
        local pByPlayer = Players[iByPlayer]
        local teamID = pPlayer:GetTeam()
        local pPlayerTeam = Teams[teamID]
        local pUnit = pPlayer:GetUnitByID(iUnit)
        print("Unit destroyed")
    
        print("iPlayer = " .. iPlayer)
        print("iByPlayer = " .. iByPlayer)
       
        -- Must have been killed by another Player
        if iPlayer == iByPlayer then return end
        if iByPlayer == -1 then return end
       
        local pPlot = pUnit:GetPlot()  
        print("pUnitOwner is " .. pUnit:GetOwner())
        if pUnit:GetOwner() ~= iByPlayer then
            print("Not same owner")
            local pUnitOwner = pUnit:GetOwner()
            local otherTeamID = pByPlayer:GetTeam()
            if pPlayerTeam:IsAtWar(otherTeamID) then
                local randomNumber = JFD_GetRandom(1, 100)
                if (randomNumber < 25) and not (pPlot:IsCity()) then
                    print("Target affected")
                    local sUnitType = GameInfoTypes.UNIT_LABORER_FREE
                    local nUnit = pByPlayer:InitUnit(sUnitType, pPlot:GetX(), pPlot:GetY())
                    nUnit:SetDamage(80)
                    print("Laborer spawned")
                   
                    if pByPlayer:IsHuman() then
                        local title = "Enslaved Laborers!";
                        local descr = "You have successfully captured an enemy unit and enslaved them!";
                        pByPlayer:AddNotification(NotificationTypes.NOTIFICATION_GENERIC, descr, title, pPlot:GetX(), pPlot:GetY());  
                        print("Notification added")
                    end
                end
            end
        end  
    end
    GameEvents.UnitPrekill.Add(BattleCapture)
    
    
     

Share This Page