Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function FindBestBaseItem( unit, aiBrain, action, sellItemData )
- local bestValue = 0
- local bestItems = {}
- local shops = {}
- local asset = action.StrategicAsset
- if not asset or not asset.ItemPriorities then
- return false
- end
- local inventoryOpen = {}
- for invName,inv in unit.Inventory do
- inventoryOpen[invName] = ValidateInventory.NumFreeSlots( inv )
- end
- local highestPriority = false
- local maxCost = false
- --Mithy: New save-for logic that takes into account item cost mods
- local savingForUpgrade, savingForCost = AIGlobals.SaveForUpgrade(unit, aiBrain)
- local gold = aiBrain.mGold - (savingForCost or 0 * (unit.Sync.ItemCostMod) or 1)
- local syncData = Common.GetSyncData(unit)
- for _,itemData in asset.ItemPriorities do
- --this number can increase for stackable items
- local purchaseQuantity = 1
- local currentPriority = 0
- if itemData.Priority <= 0 then
- continue
- end
- --If we have a highest priority and this next item won't be higher; break the loop
- if highestPriority and itemData.Priority < highestPriority then
- continue
- end
- --Store out each shop only once; this way we don't have to find shops more like crazy
- if shops[itemData.ItemTable.ShopType] == nil then
- local shop = aiBrain.GoalPlanner:GetFriendlyShop(itemData.ItemTable.ShopType, unit:GetPosition())
- if shop then
- shops[itemData.ItemTable.ShopType] = shop
- else
- shops[itemData.ItemTable.ShopType] = false
- end
- --all shops of this time seem dead, continue to next item
- if not shop then
- continue
- end
- end
- local nearby = shops[itemData.ItemTable.ShopType]
- if not nearby then
- continue
- end
- local hasItem, numHeld = UnitHasItem( unit, itemData.ItemTable.ItemId, itemData.ItemTable.BaseShopType )
- --Figure out if we can carry this item; We have two checks - one for non-stacked items and one for stacks
- if itemData.ItemTable.StacksPerSlot > 1 then
- if hasItem and numHeld >= itemData.ItemTable.StacksPerSlot then
- continue
- end
- local maxPurchasable = itemData.ItemTable.StacksPerSlot - numHeld
- --Already at max; this item is bankrupt
- if maxPurchasable <= 0 then
- continue
- end
- maxPurchasable = math.min( maxPurchasable, AIGlobals.ItemWeights[itemData.ItemTable.ItemId].MaxPurchase or 1 )
- --Mithy: Take into account item cost mult, and make sure we can actually afford one
- local maxAffordable = math.floor( gold / (itemData.ItemTable.ItemCost * (unit.Sync.ItemCostMod or 1)) )
- if maxAffordable < 1 then --was <= 0
- continue
- end
- currentPriority = itemData.Priority
- --Make sure the new item is better than the old item
- if sellItemData[itemData.ItemTable.InventoryType] then
- --[MOD] Fixed amount added to sell priority to ensure new item is greater than 5 priority better. Prevents buy/sell loops
- if sellItemData[itemData.ItemTable.InventoryType].SellItemPriority + 5 > itemData.Priority then
- continue
- end
- end
- else
- --Handle non-stacked items here
- if hasItem then
- continue
- end
- --0.26.40 - removed the code that placed a limitation on what items could be purchased at the start of the game
- --[[ # [MOD] TE Buy more cheaper items at start
- if GetGameTimeSeconds() < 30 and gold < 5000 and itemData.ItemTable.ItemCost >= 1750 then
- continue
- elseif GetGameTimeSeconds() < 30 and gold < 35000 and itemData.ItemTable.ItemCost > 10000 then
- continue
- end
- --]]
- --Get our sell refund and make sure the new item is better than the old item
- local addAmount = 0
- if sellItemData[itemData.ItemTable.InventoryType] then
- addAmount = sellItemData[itemData.ItemTable.InventoryType].SellItemRefund
- --[MOD] Fixed amount added to sell priority to ensure new item is greater than 5 priority better. Prevents buy/sell loops
- if sellItemData[itemData.ItemTable.InventoryType].SellItemPriority + 5 > itemData.Priority then
- continue
- end
- end
- --Mithy: Factor item cost mult
- if gold + (addAmount * (unit.Sync.ItemCostMod or 1)) < (itemData.ItemTable.ItemCost * (unit.Sync.ItemCostMod or 1)) then
- continue
- end
- --[MOD] TE Check idol priority against current idol
- if syncData.Inventory.Generals then
- local buyItem = true
- for slot, invData in syncData.Inventory.Generals.Slots do
- local invItemData = EntityData[invData[1]].Data # [MOD] TE Refrence .Data so item def can get blueprint.
- local invItemDef = Items[invItemData.BlueprintId]
- if invItemDef then
- local idolInSlot = string.sub(invItemDef.Name, 1, -5)
- local idolInShop = string.sub(itemData.ItemTable.ItemId, 1, -5)
- if idolInSlot == idolInShop then
- local invPriority = 0
- for k,v in asset.ItemPriorities do
- if v.ItemTable.ItemId == invItemDef.Name then
- invPriority = v.Priority
- break
- end
- end
- if invPriority + 5 > itemData.Priority then
- --WARN( LOC(aiBrain.Nickname) ..' Current: '..invItemDef.Name ..' - ' .. invPriority + 5 .. ' | vs | ' .. itemData.ItemTable.ItemId .. ' - ' .. itemData.Priority )
- buyItem = false
- else
- buyItem = true
- --WARN( LOC(aiBrain.Nickname) ..' Sell: '..invItemDef.Name ..' - ' .. invPriority .. ' | Buy: ' .. itemData.ItemTable.ItemId .. ' - ' .. itemData.Priority )
- end
- end
- end
- end
- if not buyItem then
- continue
- end
- end
- currentPriority = itemData.Priority
- end
- --Make sure we'll have room for the item
- if inventoryOpen[itemData.ItemTable.InventoryType] <= 0 and not sellItemData[itemData.ItemTable.InventoryType] then
- continue
- end
- --WARN('Items - ' .. itemData.ItemTable.ItemId .. ' - Inventory Type - ' .. inventoryOpen[itemData.ItemTable.InventoryType] )
- --Do NOT allow rebuying of the same item
- if sellItemData[itemData.ItemTable.InventoryType].SellItem == itemData.ItemTable.ItemId then
- continue
- end
- highestPriority = currentPriority
- --[[if (unit:GetArmy() == 1) then
- WARN('*AI SHOP DEBUG: Find Best Item Army= ' .. unit:GetArmy() .. ' - Purchasing item= ' .. itemData.ItemTable.ItemId
- .. ' - Priority= ' .. highestPriority
- .. ' - Quantity= ' .. purchaseQuantity )
- end--]]
- table.insert( bestItems, { ItemName = itemData.ItemTable.ItemId, ShopType = itemData.ItemTable.ShopType,
- Shop = nearby, ItemCost = itemData.ItemTable.ItemCost, ItemPriority = highestPriority, NumPurchase = purchaseQuantity,
- InventoryType = itemData.ItemTable.InventoryType, BaseShopType = itemData.ItemTable.BaseShopType } )
- end
- if table.getn( bestItems ) > 0 then
- return bestItems[Random( 1, table.getn(bestItems) )]
- end
- return false
- end
- ----------------
- function FindBestCitadelUpgrade(unit, aiBrain, action)
- local bestValue = 0
- local bestItems = {}
- local shop = aiBrain:GetStronghold()
- local asset = action.StrategicAsset
- if not asset or not asset.CitadelUpgradePriorities or not shop then
- return false
- end
- local highestPriority = false
- --Mithy: New save-for-upgrade method that only runs once per shopping check
- local savingForUpgrade, savingForCost = AIGlobals.SaveForUpgrade(unit, aiBrain)
- for _,itemData in asset.CitadelUpgradePriorities do
- local purchaseQuantity = 1
- local currentPriority = 0
- if itemData.Priority <= 0 then
- continue
- end
- --If we have a highest priority and this next item won't be higher; break the loop
- if highestPriority and (itemData.Priority) < highestPriority then
- break
- end
- if ValidateUpgrade.CanPickUpgrade(Upgrades.Tree, unit, aiBrain.Score.WarRank, itemData.ItemTable.ItemId) != true then
- continue
- end
- --Mithy: New save-for logic that runs after CanPickUpgrade and takes into account item cost mods
- --Are we saving, and is this what we're saving for?
- if savingForUpgrade and savingForUpgrade ~= itemData.ItemTable.ItemId then
- --If saving, do we have enough excess gold to purchase this?
- if aiBrain.mGold - (savingForCost * (unit.Sync.ItemCostMod or 1)) < (itemData.ItemTable.ItemCost * (unit.Sync.ItemCostMod or 1)) then
- continue
- end
- end
- highestPriority = itemData.Priority
- table.insert( bestItems, { ItemName = itemData.ItemTable.ItemId, ShopType = itemData.ItemTable.ShopType,
- Shop = shop, ItemCost = itemData.ItemTable.ItemCost, ItemPriority = highestPriority } )
- end
- if table.getn( bestItems ) > 0 then
- return bestItems[ Random( 1, table.getn(bestItems) ) ]
- end
- return false
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement