Deal Window: Deal with Units?

Zegangani

King
Joined
Oct 9, 2020
Messages
898
I wanted to make the Deal Window to also make Deals with Units (Arms Trade, Historically starting from Early Modern Era) not just Resources, Artefacts... . I've Tryed something out but no results yet. I hoped someone would help me to make this to work!

DiplomacyDealView.lua:
Code:
function CreatePlayerAvailablePanel(playerType : number, rootControl : table)

    --local playerPanel = ms_PlayerPanelIM:GetInstance(rootControl);

    if(AvailableDealItemGroupTypes.FAVOR ~= nil) then
        g_AvailableGroups[AvailableDealItemGroupTypes.GOLD][playerType]                = g_AvailableGroups[AvailableDealItemGroupTypes.FAVOR][playerType];
    else
        -- base game
        g_AvailableGroups[AvailableDealItemGroupTypes.GOLD][playerType] = CreateHorizontalGroup(rootControl);
    end

    g_AvailableGroups[AvailableDealItemGroupTypes.LUXURY_RESOURCES][playerType]    = CreateHorizontalGroup(rootControl, "LOC_DIPLOMACY_DEAL_LUXURY_RESOURCES");
    g_AvailableGroups[AvailableDealItemGroupTypes.STRATEGIC_RESOURCES][playerType] = CreateHorizontalGroup(rootControl, "LOC_DIPLOMACY_DEAL_STRATEGIC_RESOURCES");
    g_AvailableGroups[AvailableDealItemGroupTypes.AIR_UNITS][playerType] = CreateHorizontalGroup(rootControl, "LOC_DIPLOMACY_DEAL_AIR_UNITS");
    g_AvailableGroups[AvailableDealItemGroupTypes.LAND_COMBAT_UNITS][playerType] = CreateHorizontalGroup(rootControl, "LOC_DIPLOMACY_DEAL_LAND_COMBAT_UNITS");
    g_AvailableGroups[AvailableDealItemGroupTypes.NAVAL_UNITS][playerType] = CreateHorizontalGroup(rootControl, "LOC_DIPLOMACY_DEAL_NAVAL_UNITS");
    g_AvailableGroups[AvailableDealItemGroupTypes.SUPPORT_UNITS][playerType] = CreateHorizontalGroup(rootControl, "LOC_DIPLOMACY_DEAL_SUPPORT_UNITS");
    g_AvailableGroups[AvailableDealItemGroupTypes.AGREEMENTS][playerType]            = CreateVerticalGroup(rootControl, "LOC_DIPLOMACY_DEAL_AGREEMENTS");
    g_AvailableGroups[AvailableDealItemGroupTypes.CITIES][playerType]                = CreateVerticalGroup(rootControl, "LOC_DIPLOMACY_DEAL_CITIES");
    g_AvailableGroups[AvailableDealItemGroupTypes.OTHER_PLAYERS][playerType]        = CreateVerticalGroup(rootControl, "LOC_DIPLOMACY_DEAL_OTHER_PLAYERS");
    g_AvailableGroups[AvailableDealItemGroupTypes.GREAT_WORKS][playerType]            = CreateVerticalGroup(rootControl, "LOC_DIPLOMACY_DEAL_GREAT_WORKS");
    g_AvailableGroups[AvailableDealItemGroupTypes.CAPTIVES][playerType]            = CreateVerticalGroup(rootControl, "LOC_DIPLOMACY_DEAL_CAPTIVES");

    rootControl:CalculateSize();
    rootControl:ReprocessAnchoring();

    return playerPanel;
end
-- ===========================================================================
-- ===========================================================================
function CreatePlayerDealPanel(playerType : number, rootControl : table)
--This creates the containers for the offer area...
    --ms_DealGroups[DealItemGroupTypes.RESOURCES][playerType]    = CreateHorizontalGroup(rootControl);
    --ms_DealGroups[DealItemGroupTypes.AGREEMENTS][playerType]    = CreateVerticalGroup(rootControl);
    --**********************************************************************
    -- Currently putting them all in the same control.
    ms_DealGroups[DealItemGroupTypes.RESOURCES][playerType] = rootControl;
    ms_DealGroups[DealItemGroupTypes.UNITS][playerType] = rootControl;
    ms_DealGroups[DealItemGroupTypes.AGREEMENTS][playerType] = rootControl;
    ms_DealGroups[DealItemGroupTypes.CITIES][playerType] = rootControl;
    ms_DealGroups[DealItemGroupTypes.GREAT_WORKS][playerType] = rootControl;
    ms_DealGroups[DealItemGroupTypes.CAPTIVES][playerType] = rootControl;

end

-- ===========================================================================
function CreateGroupTypes()
    AvailableDealItemGroupTypes = {
        GOLD                    = 1,
        LUXURY_RESOURCES        = 2,
        STRATEGIC_RESOURCES            = 3,
        AIR_UNITS                    = 4,
        LAND_COMBAT_UNITS                    = 5,
        NAVAL_UNITS                    = 6,
        SUPPORT_UNITS                    = 7,
        AGREEMENTS              = 8,
        CITIES                  = 9,
        OTHER_PLAYERS           = 10,
        GREAT_WORKS             = 11,
        CAPTIVES                = 12,
    };

    DealItemGroupTypes = {
        GOLD                    = 1,
        RESOURCES                                = 2,
        UNITS                                = 3,
        AGREEMENTS                            = 4,
        CITIES                                    = 5,
        GREAT_WORKS                            = 6,
        CAPTIVES                                = 7
    };
end

-- ===========================================================================
function GetItemTypeIcon(pDealItem: table)
    local itemType = pDealItem:GetType();
    if (itemType == DealItemTypes.GOLD) then
        return "ICON_YIELD_GOLD_5";
    elseif (itemType == DealItemTypes.RESOURCES) then
        local resourceType = pDealItem:GetValueType();
        local resourceDesc = GameInfo.Resources[resourceType];
        return "ICON_" .. resourceDesc.ResourceType;
    else
        if    (itemType == DealItemTypes.UNITS) then
        local unitType = pDealItem:GetValueType();
        local unitDesc = GameInfo.Units[unitType];
        return "ICON_" .. unitDesc.UnitType;
    end
    return nil;
end
-- ===========================================================================
function OnClickAvailableUnit(player, unitType)

    if (ms_bIsDemand == true and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
        -- Can't modifiy demand that is not ours
        return;
    end

    local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
    if (pDeal ~= nil) then

        -- Already there?
        local dealItems = pDeal:FindItemsByType(DealItemTypes.UNITS, DealItemSubTypes.NONE, player:GetID());
        local pDealItem;
        if (dealItems ~= nil) then
            for i, pDealItem in ipairs(dealItems) do
                if pDealItem:GetValueType() == unitType then
                    -- Check for non-zero duration.  There may already be a one-time transfer of the unit if a city is in the deal.
                    if (pDealItem:GetDuration() ~= 0) then
                        return;    -- Already in there.
                    end
                end
            end
        end

        local pPlayerUnits = player:GetUnits();
        -- Get the total amount of the Unit we have. This does not take into account anything already in the deal.
        local iAmount = pPlayerUnits:GetCount( unitType );
        if (iAmount > 0) then
                
            pDealItem = pDeal:AddItemOfType(DealItemTypes.UNITS, player:GetID());
            if (pDealItem ~= nil) then
                -- Add one
                pDealItem:SetValueType(unitType);
                pDealItem:SetAmount(1);
                pDealItem:SetDuration(30);    -- Default to this many turns       

                -- After we add the item, test to see if the item is valid, it is possible that we have exceeded the amount of units we can trade.
                if not pDealItem:IsValid() then
                    pDeal:RemoveItemByID(pDealItem:GetID());
                    pDealItem = nil;
                else
                    UI.PlaySound("UI_GreatWorks_Put_Down");
                end

                UpdateDealPanel(player);
                UpdateProposedWorkingDeal();
            end
        end
    end
end

-- ===========================================================================
function PopulateAvailableUnits(player : table, iconList : table, className : string)

    local availableItemCount : number = 0;
    local pForDeal : table = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
    local possibleUnits : table = DealManager.GetPossibleDealItems(player:GetID(), GetOtherPlayer(player):GetID(), DealItemTypes.UNITS, pForDeal);
    if (possibleUnits ~= nil) then
        for i, entry in ipairs(possibleUnits) do
    
            local unitDesc : table = GameInfo.Units[entry.ForType];
            if (unitDesc ~= nil) then
                -- Do we have some and is it a luxury item?
                if (entry.MaxAmount > 0 and unitDesc.FormationClass == className ) then
                    local uiIcon : table = g_IconOnlyIM:GetInstance(iconList.ListStack);
                    SetIconToSize(uiIcon.Icon, "ICON_" .. unitDesc.UnitType);
                    uiIcon.AmountText:SetText(tostring(entry.MaxAmount));
                    uiIcon.AmountText:SetHide(false);
                    uiIcon.RemoveButton:SetHide(true);

                    local unitType : number = entry.ForType;
                    -- What to do when double clicked/tapped.
                    uiIcon.SelectButton:RegisterCallback( Mouse.eLClick, function() OnClickAvailableUnit(player, unitType); end );
                    -- Set a tool tip
                    if entry.IsValid then
                        uiIcon.SelectButton:LocalizeAndSetToolTip(unitDesc.Name);
                        uiIcon.SelectButton:SetDisabled(false);
                        uiIcon.Icon:SetColor(1, 1, 1);
                    else
                        local tempstr : string = Locale.Lookup(unitDesc.Name).."[NEWLINE][COLOR_RED]";
                        if player ~= g_LocalPlayer then
                            tempstr = tempstr .. Locale.Lookup("LOC_DEAL_PLAYER_HAS_NO_CAP_ROOM");
                            uiIcon.SelectButton:SetToolTipString(tempstr);
                        else
                            tempstr = tempstr .. Locale.Lookup("LOC_DEAL_AI_HAS_NO_CAP_ROOM");
                            uiIcon.SelectButton:SetToolTipString(tempstr);
                        end
                        uiIcon.SelectButton:SetDisabled(true);
                        uiIcon.Icon:SetColor(0.5, 0.5, 0.5);
                    end

                    availableItemCount = availableItemCount + 1;
                end
            end
        end

        iconList.ListStack:CalculateSize();
    end

    -- Hide if empty
    iconList.GetTopControl():SetHide( iconList.ListStack:GetSizeX()==0 );

    return availableItemCount;
end

-- ===========================================================================
function PopulateAvailableAirClassUnits(player : table, iconList : table)

    local availableItemCount : number = 0;
    availableItemCount = availableItemCount + PopulateAvailableUnits(player, iconList, "FORMATION_CLASS_AIR");
    return availableItemCount;
end

-- ===========================================================================
function PopulateAvailableLandCombatClassUnits(player : table, iconList : table)

    local availableItemCount : number = 0;
    availableItemCount = availableItemCount + PopulateAvailableUnits(player, iconList, "FORMATION_CLASS_LAND_COMBAT");
    return availableItemCount;
end

-- ===========================================================================
function PopulateAvailableNavalClassUnits(player : table, iconList : table)

    local availableItemCount : number = 0;
    availableItemCount = availableItemCount + PopulateAvailableUnits(player, iconList, "FORMATION_CLASS_NAVAL");
    return availableItemCount;
end

-- ===========================================================================
function PopulateAvailableSupportClassUnits(player : table, iconList : table)

    local availableItemCount : number = 0;
    availableItemCount = availableItemCount + PopulateAvailableUnits(player, iconList, "FORMATION_CLASS_SUPPORT");
    return availableItemCount;
end

-- ===========================================================================
function PopulatePlayerAvailablePanel(rootControl : table, player : table)

    local iAvailableItemCount = 0;

    if (player ~= nil) then
    
        local playerType = GetPlayerType(player);
        if (ms_bIsDemand and player:GetID() == ms_InitiatedByPlayerID) then
            -- This is a demand, so hide all the demanding player's items
            for i = 1, table.count(AvailableDealItemGroupTypes), 1 do
                g_AvailableGroups[i][playerType].GetTopControl():SetHide(true);
            end
        else
            g_AvailableGroups[AvailableDealItemGroupTypes.GOLD][playerType].GetTopControl():SetHide(false);

            iAvailableItemCount = iAvailableItemCount + PopulateAvailableGold(player, g_AvailableGroups[AvailableDealItemGroupTypes.GOLD][playerType]);
            iAvailableItemCount = iAvailableItemCount + PopulateAvailableLuxuryResources(player, g_AvailableGroups[AvailableDealItemGroupTypes.LUXURY_RESOURCES][playerType]);
            iAvailableItemCount = iAvailableItemCount + PopulateAvailableStrategicResources(player, g_AvailableGroups[AvailableDealItemGroupTypes.STRATEGIC_RESOURCES][playerType]);
            
            iAvailableItemCount = iAvailableItemCount + PopulateAvailableAirClassUnits(player, g_AvailableGroups[AvailableDealItemGroupTypes.AIR_UNITS][playerType]);
            iAvailableItemCount = iAvailableItemCount + PopulateAvailableLandCombatClassUnits(player, g_AvailableGroups[AvailableDealItemGroupTypes.LAND_COMBAT_UNITS][playerType]);
            iAvailableItemCount = iAvailableItemCount + PopulateAvailableNavalClassUnits(player, g_AvailableGroups[AvailableDealItemGroupTypes.NAVAL_UNITS][playerType]);
            iAvailableItemCount = iAvailableItemCount + PopulateAvailableSupportClassUnits(player, g_AvailableGroups[AvailableDealItemGroupTypes.SUPPORT_UNITS][playerType]);

            if (not ms_bIsDemand) then
                iAvailableItemCount = iAvailableItemCount + PopulateAvailableAgreements(player, g_AvailableGroups[AvailableDealItemGroupTypes.AGREEMENTS][playerType]);
            else
                g_AvailableGroups[AvailableDealItemGroupTypes.AGREEMENTS][playerType].GetTopControl():SetHide(true);
            end

            iAvailableItemCount = iAvailableItemCount + PopulateAvailableCities(player, g_AvailableGroups[AvailableDealItemGroupTypes.CITIES][playerType]);

            if (not ms_bIsDemand) then
                iAvailableItemCount = iAvailableItemCount + PopulateAvailableOtherPlayers(player, g_AvailableGroups[AvailableDealItemGroupTypes.OTHER_PLAYERS][playerType]);
            else
                g_AvailableGroups[AvailableDealItemGroupTypes.OTHER_PLAYERS][playerType].GetTopControl():SetHide(false);
            end

            iAvailableItemCount = iAvailableItemCount + PopulateAvailableGreatWorks(player, g_AvailableGroups[AvailableDealItemGroupTypes.GREAT_WORKS][playerType]);
            iAvailableItemCount = iAvailableItemCount + PopulateAvailableCaptives(player, g_AvailableGroups[AvailableDealItemGroupTypes.CAPTIVES][playerType]);

        end

        rootControl:CalculateSize();
        rootControl:ReprocessAnchoring();

    end

    return iAvailableItemCount;
end

-- ===========================================================================
function PopulateDealUnits(player : table, iconList : table)

    local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());

    local playerType = GetPlayerType(player);
    if (pDeal ~= nil) then
        g_IconOnlyIM:ReleaseInstanceByParent(iconList);
        g_IconAndTextIM:ReleaseInstanceByParent(iconList);

        local pDealItem;
        for pDealItem in pDeal:Items() do
            local type = pDealItem:GetType();
            if (pDealItem:GetFromPlayerID() == player:GetID()) then
                local iDuration = pDealItem:GetDuration();
                local dealItemID = pDealItem:GetID();
                -- Gold?
                if (type == DealItemTypes.GOLD) then
                    local icon;
                    if (iDuration == 0) then
                        -- One time
                        icon = g_IconOnlyIM:GetInstance(iconList);
                    else
                        -- Multi-turn
                        icon = g_IconAndTextIM:GetInstance(iconList);
                        icon.IconText:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_FOR_TURNS", iDuration);
                        icon.ValueText:SetHide(true);
                    end
                    SetIconToSize(icon.Icon, "ICON_YIELD_GOLD_5");
                    icon.AmountText:SetText(tostring(pDealItem:GetAmount()));
                    icon.AmountText:SetHide(false);

                    -- Show/hide unacceptable item notification
                    icon.UnacceptableIcon:SetHide(not pDealItem:IsUnacceptable());

                    icon.SelectButton:RegisterCallback(Mouse.eRClick, function(void1, void2, self) OnRemoveDealItem(player, dealItemID, self); end);
                    icon.SelectButton:RegisterCallback( Mouse.eLClick, function(void1, void2, self) OnSelectValueDealItem(player, dealItemID, self); end );
                    icon.SelectButton:SetToolTipString(nil);        -- We recycle the entries, so make sure this is clear.
                    icon.SelectButton:SetDisabled(false);
                    icon.Icon:SetColor(1, 1, 1);
                    if (dealItemID == g_ValueEditDealItemID) then
                        g_ValueEditDealItemControlTable = icon;
                    end
                else
                    if (type == DealItemTypes.UNITS) then

                        local unitType = pDealItem:GetValueType();
                        local icon;
                        if (iDuration == 0) then
                            -- One time
                            icon = g_IconOnlyIM:GetInstance(iconList);
                        else
                            -- Multi-turn
                            icon = g_IconAndTextIM:GetInstance(iconList);
                            icon.IconText:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_FOR_TURNS", iDuration);
                            icon.ValueText:SetHide(true);
                        end
                        local unitDesc = GameInfo.Units[unitType];
                        SetIconToSize(icon.Icon, "ICON_" .. unitDesc.UnitType);
                        icon.AmountText:SetText(tostring(pDealItem:GetAmount()));
                        icon.AmountText:SetHide(false);

                        -- Show/hide unacceptable item notification
                        icon.UnacceptableIcon:SetHide(not pDealItem:IsUnacceptable());

                        local szToolTip = Locale.Lookup(unitDesc.Name);

                        local parentDealItem = pDeal:GetItemParent(pDealItem);

                        if parentDealItem == nil then
                            -- No parent, the user can click on the item to change it.
                            icon.SelectButton:RegisterCallback(Mouse.eRClick, function(void1, void2, self) OnRemoveDealItem(player, dealItemID, self); end);
                            icon.SelectButton:RegisterCallback( Mouse.eLClick, function(void1, void2, self) OnSelectValueDealItem(player, dealItemID, self); end );
                            icon.SelectButton:SetDisabled(false);
                            icon.Icon:SetColor(1, 1, 1);
                        else
                            icon.SelectButton:ClearCallback( Mouse.eRClick );        -- Clear, we are re-using control instances
                            icon.SelectButton:ClearCallback( Mouse.eLClick );

                            szToolTip = szToolTip .. GetParentItemTransferToolTip(parentDealItem);
                        end

                        -- Set a tool tip
                        icon.SelectButton:SetToolTipString(szToolTip);

                        -- KWG: Make a way for the icon manager to have categories, so the API is like this
                        -- icon.Icon:SetTexture(IconManager:FindIconAtlasForType(IconTypes.RESOURCE, resourceType));

                        if (dealItemID == g_ValueEditDealItemID) then
                            g_ValueEditDealItemControlTable = icon;
                        end
                    end --end else if the item isn't gold
                end -- end for each item in dael
            end -- end if deal
        end

        iconList:CalculateSize();
        iconList:ReprocessAnchoring();

    end

end

-- ===========================================================================
function PopulatePlayerDealPanel(rootControl : table, player : table)

    if (player ~= nil) then
        
        local playerType = GetPlayerType(player);
        PopulateDealResources(player, ms_DealGroups[DealItemGroupTypes.RESOURCES][playerType]);
        PopulateDealUnits(player, ms_DealGroups[DealItemGroupTypes.UNITS][playerType]);
        PopulateDealAgreements(player, ms_DealGroups[DealItemGroupTypes.AGREEMENTS][playerType]);
        PopulateDealCaptives(player, ms_DealGroups[DealItemGroupTypes.CAPTIVES][playerType]);
        PopulateDealGreatWorks(player, ms_DealGroups[DealItemGroupTypes.GREAT_WORKS][playerType]);
        PopulateDealCities(player, ms_DealGroups[DealItemGroupTypes.CITIES][playerType]);

        rootControl:CalculateSize();
        rootControl:ReprocessAnchoring();
    end
end

-- ===========================================================================
function PopulateHistoryUnits(player : table, iconList : table, transformedDeal : table)
    local playerType = GetPlayerType(player);
    if (transformedDeal ~= nil) then
        g_IconOnlyIM:ReleaseInstanceByParent(iconList);
        g_IconAndTextIM:ReleaseInstanceByParent(iconList);

        local pDealItem;
        for i, pDealItem in pairs(transformedDeal.Items) do
            local type = pDealItem.Type;
            if (pDealItem.FromPlayerID == player:GetID()) then
                local iDuration = pDealItem.Duration;
                local dealItemID = pDealItem.ID;
                local remainingTurns = Locale.Lookup("LOC_BDW_ENDED");

                if(pDealItem.EndTurn >= Game:GetCurrentGameTurn()) then
                    remainingTurns = (pDealItem.EndTurn - Game:GetCurrentGameTurn()) .. " " .. Locale.Lookup("LOC_BDW_REMAINING");
                end

                -- Gold?
                if (type == DealItemTypes.GOLD) then
                    local icon;
                    if (iDuration == 0) then
                        -- One time
                        icon = g_IconOnlyIM:GetInstance(iconList);
                    else
                        -- Multi-turn
                        icon = g_IconAndTextIM:GetInstance(iconList);
                        icon.IconText:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_FOR_TURNS", iDuration);
                        icon.IconText:SetText(icon.IconText:GetText() .. " (" .. remainingTurns .. ")");
                        icon.ValueText:SetHide(true);
                    end
                    SetIconToSize(icon.Icon, "ICON_YIELD_GOLD_5");
                    icon.AmountText:SetText(tostring(pDealItem.Amount));
                    icon.AmountText:SetHide(false);

                    icon.SelectButton:SetToolTipString(nil);        -- We recycle the entries, so make sure this is clear.
                    icon.SelectButton:SetDisabled(true);
                    icon.Icon:SetColor(1, 1, 1);
                    if (dealItemID == g_ValueEditDealItemID) then
                        g_ValueEditDealItemControlTable = icon;
                    end
                elseif (DealItemTypes.FAVOR ~= nil and type == DealItemTypes.FAVOR) then
                    local icon;
                    if (iDuration == 0) then
                        -- One time
                        icon = g_IconOnlyIM:GetInstance(iconList);
                        SetIconToSize(icon.Icon, "ICON_YIELD_FAVOR");
                        icon.AmountText:SetText(tostring(pDealItem.Amount));
                        icon.AmountText:SetHide(false);
                        icon.Icon:SetColor(1, 1, 1);

                        icon.SelectButton:SetToolTipString(nil);        -- We recycle the entries, so make sure this is clear.
                        icon.SelectButton:SetDisabled(true);
                        if (dealItemID == g_ValueEditDealItemID) then
                            g_ValueEditDealItemControlTable = icon;
                        end
                    else
                        -- Multi-turn
                        UI.DataError("Favor can only be traded in lump sums, but gamecore is indicating duration. This may be an issue @sbatista & @agarrett");
                    end
                else
                    if (type == DealItemTypes.UNITS) then

                        local unitType = pDealItem.ValueType;
                        local icon;
                        if (iDuration == 0) then
                            -- One time
                            icon = g_IconOnlyIM:GetInstance(iconList);
                        else
                            -- Multi-turn
                            icon = g_IconAndTextIM:GetInstance(iconList);
                            icon.IconText:LocalizeAndSetText("LOC_DIPLOMACY_DEAL_FOR_TURNS", iDuration);
                            icon.IconText:SetText(icon.IconText:GetText() .. " (" .. remainingTurns .. ")");
                            icon.ValueText:SetHide(true);
                        end
                        local unitDesc = GameInfo.Units[unitType];
                        SetIconToSize(icon.Icon, "ICON_" .. unitDesc.UnitType);
                        icon.AmountText:SetText(tostring(pDealItem.Amount));
                        icon.AmountText:SetHide(false);

                        local szToolTip = Locale.Lookup(unitDesc.Name);

                            icon.SelectButton:SetDisabled(true);
                            icon.Icon:SetColor(1, 1, 1);

                        -- Set a tool tip
                        icon.SelectButton:SetToolTipString(szToolTip);

                        if (dealItemID == g_ValueEditDealItemID) then
                            g_ValueEditDealItemControlTable = icon;
                        end
                    end --end else if the item isn't gold
                end -- end for each item in dael
            end -- end if deal
        end

        iconList:CalculateSize();
        iconList:ReprocessAnchoring();

    end

end
These are just the functions I Added/changed for this mod

DiplomacyDealView_Expansion2.lua:
Code:
BASE_PopulateDealUnits = PopulateDealUnits;

function OnClickAvailableUnits(player, unitType)

    if ((ms_bIsDemand == true or ms_bIsGift == true) and ms_InitiatedByPlayerID == ms_OtherPlayerID) then
        -- Can't modifiy demand that is not ours
        return;
    end

    local pBaseUnitDef = GameInfo.Units[unitType];
    local pUnitDef = GameInfo.Units[pBaseUnitDef.UnitType];

    local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, Game.GetLocalPlayer(), GetOtherPlayer():GetID());
    if (pDeal ~= nil) then

        -- Already there?
        local dealItems = pDeal:FindItemsByType(DealItemTypes.UNITS, DealItemSubTypes.NONE, player:GetID());
        local pDealItem;
        if (dealItems ~= nil) then
            for i, pDealItem in ipairs(dealItems) do
                if pDealItem:GetValueType() == unitType then
                    -- Check for non-zero duration.  There may already be a one-time transfer of the resource if a city is in the deal.
                    if (pDealItem:GetDuration() ~= 0) then
                        return;    -- Already in there.
                    end
                    if (pUnitDef ~= nil and pUnitDef.CanTrain) then
                        -- already have this, up the amount
                        local iAddAmount = pDealItem:GetAmount() + 1;
                        iAddAmount = clip(iAddAmount, nil, pDealItem:GetMaxAmount());
                        if (iAddAmount ~= pDealItem:GetAmount()) then
                            pDealItem:SetAmount(iAddAmount);

                            if not pDealItem:IsValid() then
                                pDealItem:SetAmount(iAddAmount-1);
                                return;
                            else
                                UI.PlaySound("UI_GreatWorks_Put_Down");
                                UpdateDealPanel(player);

                                UpdateProposedWorkingDeal();
                                return;
                            end
                        else
                            return;
                        end
                    end
                end
            end
        end

        -- we don't need to check how many the player has, the deal manager will reject if we try to add too many
        local pPlayerUnits = player:GetUnits();
        pDealItem = pDeal:AddItemOfType(DealItemTypes.UNITS, player:GetID());
        if (pDealItem ~= nil) then
            -- Add one
            pDealItem:SetValueType(unitType);
            pDealItem:SetAmount(1);
            if (pUnitDef ~= nil and pUnitDef.CanTrain) then
                pDealItem:SetDuration(0);
            else
                pDealItem:SetDuration(30);    -- Default to this many turns       
            end

            -- After we add the item, test to see if the item is valid, it is possible that we have exceeded the amount of resources we can trade.
            if not pDealItem:IsValid() then
                pDeal:RemoveItemByID(pDealItem:GetID());
                pDealItem = nil;
            else
                UI.PlaySound("UI_GreatWorks_Put_Down");
            end

            UpdateDealPanel(player);
            UpdateProposedWorkingDeal();
        end
    end
end

-- ===========================================================================
function PopulateDealUnits(player: table, iconList: table)

    BASE_PopulateDealUnits(player, iconList);

    local pDeal = DealManager.GetWorkingDeal(DealDirection.OUTGOING, g_LocalPlayer:GetID(), g_OtherPlayer:GetID());
    local playerType = GetPlayerType(player);
    if (pDeal ~= nil) then
        for pDealItem in pDeal:Items() do
            if (pDealItem:GetFromPlayerID() == player:GetID()) then
                local type = pDealItem:GetType();
                local iDuration = pDealItem:GetDuration();
                local dealItemID = pDealItem:GetID();
                -- Gold?
                if (type == DealItemTypes.FAVOR) then
                    local icon;
                    if (iDuration == 0) then
                        -- One time
                        icon = g_IconOnlyIM:GetInstance(iconList);
                        SetIconToSize(icon.Icon, "ICON_YIELD_FAVOR");
                        icon.AmountText:SetText(tostring(pDealItem:GetAmount()));
                        icon.AmountText:SetHide(false);
                        icon.Icon:SetColor(1, 1, 1);

                        -- Show/hide unacceptable item notification
                        icon.UnacceptableIcon:SetHide(not pDealItem:IsUnacceptable());

                        icon.SelectButton:RegisterCallback(Mouse.eRClick, function(void1, void2, self) OnRemoveDealItem(player, dealItemID, self); end);
                        icon.SelectButton:RegisterCallback( Mouse.eLClick, function(void1, void2, self) OnSelectValueDealItem(player, dealItemID, self); end );
                        icon.SelectButton:SetToolTipString(nil);        -- We recycle the entries, so make sure this is clear.
                        icon.SelectButton:SetDisabled(false);
                        if (dealItemID == g_ValueEditDealItemID) then
                            g_ValueEditDealItemControlTable = icon;
                        end
                    else
                        -- Multi-turn
                        UI.DataError("Favor can only be traded in lump sums, but gamecore is indicating duration. This may be an issue @sbatista & @agarrett");
                    end
                end -- end for each item in deal
            end -- end if deal
        end
    end
    
end

The DiplomacyDealView.xml is the only file I didn't touch (cause I don't know how to do it - lost all my orientation just looking at it).
 
Changing the DiplomacyDealView.lua (UI) would only affect the human Player. So is there any other way to alter/change the Deal behavior of AI, so it would make use of this Concept (Dealing with Units)? And is it even possible to mod the Deal mechanisms of the Game (e. g. adding the possibility to deal with Units, Improvements, trading Strategic Resources per turn (not just the existing possibility to trade them in amounts)...)?
 
Last edited:
Top Bottom