• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[System]Gcsn- Costs and States

Level 31
Joined
Jul 10, 2007
Messages
6,306
being rewritten to increase efficiency

JASS:
native GetUnitGoldCost takes integer unitid returns integer
native GetUnitWoodCost takes integer unitid returns integer

library Stock initializer Initialization uses PlayerTracker
/*Utility Information
//===================================================================
Name: Stock (gold/wood stock, item charge stock, bounty stock)
Version: 6.2
Author: Nestharus

Settings:
*///===================================================================
//! textmacro Stock_USER_SETTINGS
    set coordX = GetRectCenterX(bj_mapInitialPlayableArea)
    set coordY = GetRectCenterY(bj_mapInitialPlayableArea)
//! endtextmacro

//! textmacro Stock_EXTRA_PLAYERS
    /*call TriggerRegisterPlayerUnitEvent(unitUpgradeStartTracking, GetPlayer(x), EVENT_PLAYER_UNIT_UPGRADE_START, null)
    call TriggerRegisterPlayerUnitEvent(unitUpgradeFinishTracking, GetPlayer(x), EVENT_PLAYER_UNIT_UPGRADE_FINISH, null)
    call TriggerRegisterPlayerUnitEvent(unitFinishResearching, GetPlayer(x), EVENT_PLAYER_UNIT_RESEARCH_FINISH, null)*/
//! endtextmacro

globals
    private constant integer BOUNTY_ACCURACY = 3
    private constant damagetype damageType = DAMAGE_TYPE_UNKNOWN
    private constant attacktype attackType = ATTACK_TYPE_CHAOS
    private constant weapontype weaponType = WEAPON_TYPE_WHOKNOWS
endglobals
/*//===================================================================

Description:
    What does it do-
        Retrieves various costs and states for players, units, and items
        Players: 
            Total Gold including all owned items, units, and techs.
        Units: 
            total gold/wood cost (all items on them), unit type id
            gold/wood cost, unit average cached bounty, on the spot
            bounty, and gold/wood upgrades
        Items:
            total gold/wood cost including charges, item type id
            gold/wood cost, default item charges
        Research:
            gold/wood cost in a range. Powerful but hard to use.
    How does it do it-
        Creates a unit for player 14 at designed coordinates. It hides it, gives it
        locust, etc, etc so that it is as safe as possible. 
        
        To get item and or gold cost, the hidden unit sells the item to itself and records the cost. Items
        are enumerated in a removal rect and if the enumerated item matches the type of the item running
        through the system, it is removed. This is the primary reason why it can be dangerous for this system
        to be running in an open area where items may be dropped. Also, this is the reason that the area
        has to be a place where items can be dropped, otherwise it cannot retrieve the items for cleaning.
        
        For unit costs, it sells the unit to itself and records the cost. When the unit enters the removal 
        area, it is removed. Only units owned by Player 14 of the current type are removed, but again
        can be dangerous if the map is using player 14. It only uses this method if the unit is a hero, 
        otherwise it defaults to the JASS AI Natives.
        
        For unit bounty, it creates a unit at the invis unit's coordinates and then makes the invis unit
        kill it with a damage function. The bounty is then recorded and the unit is removed.
        
        Item default charges are recorded as the item is enumerated in the removal area.
        
        For upgrades on units, it runs whenever a unit begins upgrading. When units go out of scope (leave the
        rect), they are automatically cleaned. For the tracking to work, TrackUpgrades must be called. 
        The reason for this is so that everything can run as efficiently and as quickly as possible. 
        There is no point to track upgrades on a unit that will never upgrade.
        
Requirements: PTN- hiveworkshop.com/forums/jass-functions-413/system-pt-player-tracking-142554/
              Recycle- thehelper.net/forums/showthread.php?t=136087
            
Installation: NA

Variables and Settings:
------------------------------------------------------------------
BOUNTY_ACCURACY- how accurate bounty will be. Higher is slower and more
accurate. Smaller is faster and less accurate.

coordX- the x coordinate where the invisible unit that runs this
system will be. Keep this at edge of map.

coordY- the y coordinate where the invisible unit that runs this
system will be. Keep this at edge of map.

damage/attack/weapon type- used when killing a unit to determine
its bounty.
    
Stock_EXTRA_PLAYERS-
    Refers to other players that this system runs for. Does not go
    through a loop. All players from 0-11 are automatically registered.
------------------------------------------------------------------

Functions:
------------------------------------------------------------------
-GetResearchGoldCost(unitTypeId, techId, start, finish)
    will return the gold tech cost of techId for upgrading from
    level start to level finish, aka level 0 to 1. The unitTypeId
    is used to create a unit for retrieving the tech cost. The unit
    must have the tech on it or the cost cannot be retrieved.
    
-GetResearchWoodCost(unitTypeId, techId, start, finish)
    will return the wood tech cost of techId for upgrading from
    level start to level finish, aka level 0 to 1. The unitTypeId
    is used to create a unit for retrieving the tech cost. The unit
    must have the tech on it or the cost cannot be retrieved.
    
-GetUnitCachedBounty(unitTypeId)
    will return the current cached value of gold bounty
    for a unit and cache it if the record is new
    
-GetUnitBounty(unitTypeId, accuracy)
    will return an average gold bounty given an accuracy
    and will always do it new. Accuracy should typically be 1
    
-UpdateBounty(integer unitTypeId, integer min, integer max)
    Will forcefully update the averaged bounty for a given unit id if the
    min is smaller than the currently registered min and or the max is greater
    than the currently registered max. Bounty is automatically updated
    to get the best possible average as GetUnitBounty is used and it is updated
    as the Bounty utility runs (an optional add-on to this).
    
-GetUnitGold(unitTypeId)
    will return the gold cost of the unit type

-GetUnitWood(unitTypeId)
    will return the wood cost of the unit type
    
-GetUnitGoldUpgrades(unit)
    will return the total gold upgrades of a unit
    
-GetUnitWoodUpgrades(unit)
    will return the total wood upgrades of a unit
    
-TrackUpgrades(unit)
    will make the system track a unit's upgrades. It
    will only track the unit's upgrades if this is called.
    Once tracking has begun, it cannot be stopped until the unit
    is removed from the game.
    
-StopUpgradeTracking(unit)
    Will stop tracking a unit and clean it from the system
    
-GetItemGoldCost(itemTypeId)
    will return the gold cost of the item type
    
-GetItemWoodCost(itemTypeId)
    will return the wood cost of the item type
    
-GetItemCharge(itemTypeId)
    will return the starting charges of the item type
    
-GetItemTotalGoldCost(item)
    will return the total gold cost of the item, charges and all
    
-GetItemTotalWoodCost(item)
    will return the total wood cost of the item, charges and all
    
-GetUnitTotalGoldCost(unit)
    will return the total gold cost of the unit, items and all
    
-GetUnitTotalWoodCost(unit)
    will return the total wood cost of the unit, items and all
    
-GetPlayerGoldResearch(player)
    returns the the total gold the player spent on researching
    
-GetPlayerWoodResearch(player)
    retursn the total wood the player spent on researching
    
-UpdatePlayer(player)
    will update the player's total gold and wood, including all
    units and items that player owns
    
-GetPlayerTotalGold(player)
    will return the player's total gold. The player must
    be updated for this to work.
    
-GetPlayerTotalWood(player)
    will return the player's total wood. The player must
    be updated for this to work.
------------------------------------------------------------------*/
    globals
        private rect removalArea
        private integer unitCheckerId = 'hpea'
        private real coordX
        private real coordY
        private player playerChecker
        private unit costRetriever
        private integer array goldResource[24]
        private integer array woodResource[24]
        private constant integer RESOURCE_LIMIT = 1000000
        private group unitGroup = CreateGroup()
        private trigger unitRemoval = CreateTrigger()
        private region unitRemovalRegion
        private trigger unitUpgradeStartTracking = CreateTrigger()
        private trigger stopUnitUpgradeTracking = CreateTrigger()
        private trigger unitUpgradeFinishTracking = CreateTrigger()
        private trigger unitFinishResearching = CreateTrigger()
        private region world
        private hashtable items = InitHashtable()
        private hashtable units = InitHashtable()
        private hashtable unitTypes = InitHashtable()
        private hashtable research = InitHashtable()
        private integer runningUnitTypeId = 0
        private integer runningItemTypeId = 0
        private unit runningUnit = null
        private integer runningUnitTypeStackId = 0
        private integer runningItemTypeStackId = 0
        private integer runningUnitStackId = 0
        private item runningItem = null
        private integer runningItemStackId = 0
        private boolexpr removeItems
        private boolexpr checkUnit
    endglobals
    
    private struct ItemTypeStack
    endstruct
    
    private struct UnitTypeStack
    endstruct
    
    private struct UnitStack
    endstruct
    
    //Items
        globals
            private integer array itemGoldCost
            private integer array itemWoodCost
            private integer array itemCharges
        endglobals
        
        globals
            private integer currentItemType
            private integer currentItemId
        endglobals
        
        private function RemoveItems takes nothing returns boolean
            local item i = GetFilterItem()
            local integer typeId = GetItemTypeId(i)
            if typeId == currentItemType then
                set itemCharges[currentItemId] = GetItemCharges(i)
                call RemoveItem(i)
                set currentItemType = 0
                set currentItemId = 0
            endif
            set i = null
            return false
        endfunction
        
        private function GetItemId takes integer itemTypeId returns integer
            local integer playerGold
            local integer playerWood
            local integer id
            if runningItemTypeId != itemTypeId then
                if not HaveSavedInteger(items, itemTypeId, 0) then
                    set id = ItemTypeStack.create()
                    call SaveInteger(items, itemTypeId, 0, id)
                    set playerGold = GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD)
                    set playerWood = GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER)
                    set currentItemType = itemTypeId
                    set currentItemId = id
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, RESOURCE_LIMIT)
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER, RESOURCE_LIMIT)
                    call AddItemToStock(costRetriever, itemTypeId, 1, 1)
                    call IssueNeutralImmediateOrderById(playerChecker, costRetriever, itemTypeId)
                    set itemGoldCost[id] = RESOURCE_LIMIT - GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD)
                    set itemWoodCost[id] = RESOURCE_LIMIT - GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER)
                    call RemoveItemFromStock(costRetriever, itemTypeId)
                    call EnumItemsInRect(removalArea, removeItems, null)
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, playerGold)
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER, playerWood)
                    set runningItemTypeStackId = id
                else
                    set runningItemTypeStackId = LoadInteger(items, itemTypeId, 0)
                endif
                set runningItemTypeId = itemTypeId
            endif
            return runningItemTypeStackId
        endfunction
    //End Items
    
    //Units
        globals
            private integer array unitGoldCost
            private integer array unitWoodCost
            private integer array goldBountyMax
            private integer array goldBountyMin
            private integer array goldBounty
            
            private integer array unitGoldUpgrades
            private integer array unitWoodUpgrades
            private integer array unitGoldUpgradesLast
            private integer array unitWoodUpgradesLast
            private integer array unitGoldUpgradesPending
            private integer array unitWoodUpgradesPending
        endglobals
        
        globals
            private integer currentUnitType = 0
        endglobals
        
        private function RemoveUnits takes nothing returns boolean
            local unit u = GetFilterUnit()
            if GetUnitTypeId(u) == currentUnitType and GetOwningPlayer(u) == playerChecker then
                call RemoveUnit(u)
                set currentUnitType = 0
            endif
            set u = null
            return false
        endfunction
        
        private function UnitGetId takes integer unitTypeId returns integer
            local integer id
            if runningUnitTypeId != unitTypeId then
                if not HaveSavedInteger(unitTypes, unitTypeId, 0) then
                    set id = UnitTypeStack.create()
                    call SaveInteger(unitTypes, unitTypeId, 0, id)
                    set runningUnitTypeStackId = id
                else
                    set runningUnitTypeStackId = LoadInteger(unitTypes, unitTypeId, 0)
                endif
                set runningUnitTypeId = unitTypeId
            endif
            return runningUnitTypeStackId
        endfunction
        
        function UpdateBounty takes integer unitTypeId, integer min, integer max returns nothing
            local integer id = UnitGetId(unitTypeId)
            if min < goldBountyMin[id] then
                set goldBountyMin[id] = min
            endif
            if max > goldBountyMax[id] then
                set goldBountyMax[id] = max
            endif
            set goldBounty[id] = (goldBountyMin[id]+goldBountyMax[id])/2
        endfunction
        
        function GetUnitBounty takes integer unitTypeId, integer accuracy returns integer
            local integer averageGold = 0
            local integer count = 0
            local unit array u
            local boolean bounty = (GetPlayerState(playerChecker, PLAYER_STATE_GIVES_BOUNTY) == 1)
            local integer playerGold = GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD)
            local boolean allied = GetPlayerAlliance(playerChecker, Player(12), ALLIANCE_PASSIVE)
            local integer minGold = 1000000
            local integer maxGold = 0
            local integer currentGold
            if not bounty then
                call SetPlayerState(playerChecker, PLAYER_STATE_GIVES_BOUNTY, 1)
            endif
            if allied then
                call SetPlayerAlliance(playerChecker, Player(12), ALLIANCE_PASSIVE, false)
            endif
            loop
                exitwhen count == accuracy
                call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, 0)
                set u[count] = CreateUnit(Player(12), unitTypeId, coordX, coordY, 270)
                call ShowUnit(u[count], false)
                call SetUnitState(u[count], UNIT_STATE_LIFE, 1)
                call SetUnitInvulnerable(u[count], false)
                call UnitDamageTarget(costRetriever, u[count], 100000000, true, false, attackType, damageType, weaponType)
                call RemoveUnit(u[count])
                set u[count] = null
                set currentGold = GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD)
                if currentGold < minGold then
                    set minGold = currentGold
                endif
                if currentGold > maxGold then
                    set maxGold = currentGold
                endif
                if averageGold == 0 then
                    set averageGold = currentGold
                else
                    set averageGold = (averageGold+GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD))/2
                endif
                set count = count + 1
            endloop
            call UpdateBounty(unitTypeId, minGold, maxGold)
            if not bounty then
                call SetPlayerState(playerChecker, PLAYER_STATE_GIVES_BOUNTY, 0)
            endif
            if allied then
                call SetPlayerAlliance(playerChecker, Player(12), ALLIANCE_PASSIVE, true)
            endif
            call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, playerGold)
            return averageGold
        endfunction
        
        private function GetTypeUnitId takes integer unitTypeId returns integer
            local integer id = UnitGetId(unitTypeId)
            local integer foodCap
            local integer playerGold
            local integer playerWood
            local unit u
            if not HaveSavedBoolean(unitTypes, unitTypeId, 1) then
                call SaveBoolean(unitTypes, unitTypeId, 1, true)
                set u = CreateUnit(Player(12), unitTypeId, coordX, coordY, 0)
                if not IsUnitType(u, UNIT_TYPE_HERO) then
                    set unitGoldCost[id] = GetUnitGoldCost(unitTypeId)
                    set unitWoodCost[id] = GetUnitWoodCost(unitTypeId)
                else
                    set currentUnitType = unitTypeId
                    set foodCap = GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_FOOD_CAP)
                    set playerGold = GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD)
                    set playerWood = GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER)
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_FOOD_CAP, -1)
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, RESOURCE_LIMIT)
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER, RESOURCE_LIMIT)
                    call AddUnitToStock(costRetriever, unitTypeId, 1, 1)
                    call IssueNeutralImmediateOrderById(playerChecker, costRetriever, unitTypeId)
                    set unitGoldCost[id] = RESOURCE_LIMIT - GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD)
                    set unitWoodCost[id] = RESOURCE_LIMIT - GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER)
                    call RemoveUnitFromStock(costRetriever, unitTypeId)
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_FOOD_CAP, foodCap)
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, playerGold)
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER, playerWood)
                endif
                call RemoveUnit(u)
                call GetUnitBounty(unitTypeId, BOUNTY_ACCURACY)
                set u = null
            endif
            return id
        endfunction
        
        private function GetUnitId takes unit u returns integer
            local integer handleId
            debug if GetHandleId(u) > 0 then
                if runningUnit != u then
                    set handleId = GetHandleId(u)
                    if not HaveSavedInteger(units, handleId, 0) then
                        set runningUnitStackId = UnitStack.create()
                        call SaveInteger(units, handleId, 0, runningUnitStackId)
                    else
                        set runningUnitStackId = LoadInteger(units, handleId, 0)
                    endif
                    set runningUnit = u
                endif
                return runningUnitStackId
            debug endif
            debug return 0
        endfunction
        
        private function TrackUpgradeFinish takes nothing returns nothing
            local unit u = GetTriggerUnit()
            local integer handleId = GetHandleId(u)
            local integer id
            if HaveSavedInteger(units, handleId, 0) then
                set id = LoadInteger(units, handleId, 0)
                set unitGoldUpgrades[id] = unitGoldUpgrades[id] + unitGoldUpgradesPending[id]
                set unitWoodUpgrades[id] = unitWoodUpgrades[id] + unitWoodUpgradesPending[id]
                set unitGoldUpgradesPending[id] = unitWoodUpgradesLast[id]
                set unitWoodUpgradesPending[id] = unitWoodUpgradesLast[id]
            endif
            set u = null
        endfunction
        
        private function TrackUpgradeStart takes nothing returns nothing
            local unit u = GetTriggerUnit()
            local integer handleId = GetHandleId(u)
            local integer id
            local integer unitTypeId
            if HaveSavedInteger(units, handleId, 0) then
                set id = LoadInteger(units, handleId, 0)
                set unitTypeId = GetTypeUnitId(GetUnitTypeId(u))
                set unitGoldUpgradesLast[id] = unitGoldCost[unitTypeId]
                set unitWoodUpgradesLast[id] = unitWoodCost[unitTypeId]
            endif
            set u = null
        endfunction
        
        private function StopTrackUpgrade takes nothing returns boolean
            local integer id
            local integer handleId = GetHandleId(GetTriggerUnit())
            if HaveSavedInteger(units, handleId, 0) then
                set id = LoadInteger(units, handleId, 0)
                call RemoveSavedInteger(units, handleId, 0)
                call UnitStack(id).destroy()
                set unitGoldUpgrades[id] = 0
                set unitWoodUpgrades[id] = 0
            endif
            return false
        endfunction
    //End Units
    
    //Research
        globals
            private integer array researchGold[30]
            private integer array researchWood[30]
        endglobals
        
        function GetResearchGoldCost takes integer unitTypeId, integer techId, integer levelStart, integer levelFinish returns integer
            local integer playerGold = GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD)
            local integer playerWood = GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER)
            local integer techLevel = GetPlayerTechCount(playerChecker, techId, true)
            local integer cost = 0
            local integer count = levelStart
            local unit u = CreateUnit(playerChecker, unitTypeId, coordX, coordY, 0)
            call SetUnitPosition(u, coordX, coordY)
            call SetPlayerTechResearched(playerChecker, techId, levelStart)
            loop
                exitwhen count >= levelFinish
                if not HaveSavedInteger(research, techId, count) then
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, RESOURCE_LIMIT)
                    call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER, RESOURCE_LIMIT)
                    call IssueImmediateOrderById(u, techId)
                    call AddPlayerTechResearched(playerChecker, techId, 1)
                    set cost = RESOURCE_LIMIT - GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD) + cost
                    call SaveInteger(research, techId, count, RESOURCE_LIMIT - GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD))
                else
                    set cost = cost + LoadInteger(research, techId, count)
                endif
                set count = count + 1
            endloop
            call RemoveUnit(u)
            call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, 0)
            call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER, 0)
            call SetPlayerTechResearched(playerChecker, techId, 0)
            set u = null
            call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, playerGold)
            call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER, playerWood)
            call SetPlayerTechResearched(playerChecker, techId, techLevel)
            return cost
        endfunction
        
        function GetResearchWoodCost takes integer unitTypeId, integer techId, integer levelStart, integer levelFinish returns integer
            local integer playerGold = GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD)
            local integer playerWood = GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER)
            local integer techLevel = GetPlayerTechCount(playerChecker, techId, true)
            local integer cost = 0
            local integer count = levelStart
            local unit u = CreateUnit(playerChecker, unitTypeId, coordX, coordY, 0)
            call SetUnitPosition(u, coordX, coordY)
            call SetPlayerTechResearched(playerChecker, techId, levelStart)
            loop
                exitwhen count >= levelFinish
                call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, RESOURCE_LIMIT)
                call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER, RESOURCE_LIMIT)
                call IssueImmediateOrderById(u, techId)
                call AddPlayerTechResearched(playerChecker, techId, 1)
                set cost = RESOURCE_LIMIT - GetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER) + cost
                set count = count + 1
            endloop
            call RemoveUnit(u)
            call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, 0)
            call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER, 0)
            call SetPlayerTechResearched(playerChecker, techId, 0)
            set u = null
            call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_GOLD, playerGold)
            call SetPlayerState(playerChecker, PLAYER_STATE_RESOURCE_LUMBER, playerWood)
            call SetPlayerTechResearched(playerChecker, techId, techLevel)
            return cost
        endfunction
        
        private function TrackResearch takes nothing returns nothing
            local player p = GetTriggerPlayer()
            local integer playerId = GetPlayerId(p)
            local integer unitTypeId = GetUnitTypeId(GetTriggerUnit())
            local integer researched = GetResearched()
            local integer techCount = GetPlayerTechCount(p, researched, true)
            set researchGold[playerId] = researchGold[playerId] + GetResearchGoldCost(unitTypeId, researched, techCount, techCount+1)
            set researchWood[playerId] = researchWood[playerId] + GetResearchWoodCost(unitTypeId, researched, techCount, techCount+1)
        endfunction
    //End Research
    
    function StopUpgradeTracking takes unit u returns nothing
        local integer handleId = GetHandleId(u)
        local integer id
        if HaveSavedInteger(units, handleId, 0) then
            set id = LoadInteger(units, handleId, 0)
            call RemoveSavedInteger(units, handleId, 0)
            call UnitStack(id).destroy()
            set unitGoldUpgrades[id] = 0
            set unitWoodUpgrades[id] = 0
        endif
    endfunction
    
    function TrackUpgrades takes unit u returns nothing
        local integer id = GetUnitId(u)
        local integer unitTypeId = GetTypeUnitId(GetUnitTypeId(u))
        set unitGoldUpgradesPending[id] = unitGoldCost[unitTypeId]
        set unitWoodUpgradesPending[id] = unitWoodCost[unitTypeId]
    endfunction
    
    function GetPlayerGoldResearch takes player p returns integer
        return researchGold[GetPlayerId(p)]
    endfunction
    
    function GetPlayerWoodResearch takes player p returns integer
        return researchWood[GetPlayerId(p)]
    endfunction
    
    function GetUnitGoldUpgrades takes unit u returns integer
        return unitGoldUpgrades[GetUnitId(u)]
    endfunction
    
    function GetUnitWoodUpgrades takes unit u returns integer
        return unitWoodUpgrades[GetUnitId(u)]
    endfunction
    
    function GetUnitCachedBounty takes integer unitTypeId returns integer
        return goldBounty[GetTypeUnitId(unitTypeId)]
    endfunction
    
    function GetUnitGold takes integer unitTypeId returns integer
        return unitGoldCost[GetTypeUnitId(unitTypeId)]
    endfunction
    
    function GetUnitWood takes integer unitTypeId returns integer
        return unitWoodCost[GetTypeUnitId(unitTypeId)]
    endfunction
    
    function GetItemGoldCost takes integer itemTypeId returns integer
        return itemGoldCost[GetItemId(itemTypeId)]
    endfunction
    
    function GetItemWoodCost takes integer itemTypeId returns integer
        return itemWoodCost[GetItemId(itemTypeId)]
    endfunction
    
    function GetItemCharge takes integer itemTypeId returns integer
        return itemCharges[GetItemId(itemTypeId)]
    endfunction
    
    function GetItemTotalGoldCost takes item i returns integer
        local integer itemTypeId = GetItemId(GetItemTypeId(i))
        return (itemGoldCost[itemTypeId]*GetItemCharges(i))/itemCharges[itemTypeId]
    endfunction
    
    function GetItemTotalWoodCost takes item i returns integer
        local integer itemTypeId = GetItemId(GetItemTypeId(i))
        return (itemWoodCost[itemTypeId]*GetItemCharges(i))/itemCharges[itemTypeId]
    endfunction
    
    function GetUnitTotalGoldCost takes unit u returns integer
        local integer unitTypeId = GetUnitTypeId(u)
        local integer handleId = GetHandleId(u)
        local integer cost = unitGoldCost[GetTypeUnitId(unitTypeId)]
        local integer x = 0
        local integer inventorySize = UnitInventorySize(u)
        local item i
        if HaveSavedInteger(units, handleId, 0) then
            set cost = cost + GetUnitGoldUpgrades(u)
        endif
        if inventorySize > 0 then
            loop
                exitwhen x == inventorySize
                set i = UnitItemInSlot(u, x)
                if i != null then
                    set cost = cost + GetItemTotalGoldCost(i)
                endif
                set x = x + 1
            endloop
        endif
        set i = null
        set u = null
        return cost
    endfunction
    
    function GetUnitTotalWoodCost takes unit u returns integer
        local integer unitTypeId = GetUnitTypeId(u)
        local integer cost = unitWoodCost[GetTypeUnitId(unitTypeId)]
        local integer handleId = GetHandleId(u)
        local integer x = 0
        local integer inventorySize = UnitInventorySize(u)
        local item i
        if HaveSavedInteger(units, handleId, 0) then
            set cost = cost + GetUnitWoodUpgrades(u)
        endif
        if inventorySize > 0 then
            loop
                exitwhen x == inventorySize
                set i = UnitItemInSlot(u, x)
                if i != null then
                    set cost = cost + GetItemTotalWoodCost(i)
                endif
                set x = x + 1
            endloop
        endif
        set i = null
        set u = null
        return cost
    endfunction
    
    private function CheckUnit takes nothing returns boolean
        local integer playerId
        local unit u = GetFilterUnit()
        if GetUnitState(u, UNIT_STATE_LIFE) > 0 or IsUnitType(u, UNIT_TYPE_HERO) then
            set playerId = GetPlayerId(GetOwningPlayer(u))
            set goldResource[playerId] = goldResource[playerId] + GetUnitTotalGoldCost(u)
            set woodResource[playerId] = woodResource[playerId] + GetUnitTotalWoodCost(u)
        endif
        set u = null
        return false
    endfunction
    
    function UpdatePlayer takes player p returns nothing
        local integer playerId = GetPlayerId(p)
        set goldResource[playerId] = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD) + researchGold[playerId]
        set woodResource[playerId] = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER) + researchWood[playerId]
        call GroupEnumUnitsOfPlayer(unitGroup, p, checkUnit)
        call GroupClear(unitGroup)
    endfunction
    
    constant function GetPlayerTotalGold takes integer playerId returns integer
        return goldResource[playerId]
    endfunction
    
    constant function GetPlayerTotalWood takes integer playerId returns integer
        return woodResource[playerId]
    endfunction
    
    private function StopBug takes nothing returns nothing
        if (GetUnitX(costRetriever) != coordX) or (GetUnitY(costRetriever) != coordY-64) then
            call IssueImmediateOrder(costRetriever, "stop")
            call IssuePointOrder(costRetriever, "move", coordX, coordY-64)
        endif
    endfunction
    
    private function Initialization takes nothing returns nothing
        local integer x = 11
        //! runtextmacro Stock_USER_SETTINGS()
        playerChecker = Player(14)
        set world = CreateRegion()
        set unitRemovalRegion = CreateRegion()
        set removalArea = Rect(coordX-64, coordY-128, coordX+64, coordY+64)
        call RegionAddRect(unitRemovalRegion, removalArea)
        call RegionAddRect(world, bj_mapInitialPlayableArea)
        call TriggerRegisterEnterRegion(unitRemoval, unitRemovalRegion, Condition(function RemoveUnits))
        set costRetriever = CreateUnit(playerChecker, unitCheckerId, 0, 0, 270)
        call SetUnitUseFood(costRetriever, false)
        call UnitAddAbility(costRetriever,'Asid')
        call UnitAddAbility(costRetriever,'Asud')
        call UnitAddAbility(costRetriever, 'Aloc')
        call UnitRemoveAbility(costRetriever, 'Awan')
        call UnitRemoveAbility(costRetriever, 'Aneu')
        call UnitRemoveAbility(costRetriever, 'Ane2')
        call ShowUnit(costRetriever, false)
        call SetUnitPosition(costRetriever, coordX, coordY-64)
        call SetUnitAcquireRange(costRetriever, 0)
        loop
            set x = x - 1
            call TriggerRegisterPlayerUnitEvent(unitUpgradeStartTracking, GetPlayer(x), EVENT_PLAYER_UNIT_UPGRADE_START, null)
            call TriggerRegisterPlayerUnitEvent(unitUpgradeFinishTracking, GetPlayer(x), EVENT_PLAYER_UNIT_UPGRADE_FINISH, null)
            call TriggerRegisterPlayerUnitEvent(unitFinishResearching, GetPlayer(x), EVENT_PLAYER_UNIT_RESEARCH_FINISH, null)
            exitwhen x == 0
        endloop
        //! runtextmacro Stock_EXTRA_PLAYERS()
        call TriggerRegisterLeaveRegion(stopUnitUpgradeTracking, world, Condition(function StopTrackUpgrade))
        call TriggerAddAction(unitUpgradeStartTracking, function TrackUpgradeStart)
        call TriggerAddAction(unitUpgradeFinishTracking, function TrackUpgradeFinish)
        call TriggerAddAction(unitFinishResearching, function TrackResearch)
        call TimerStart(CreateTimer(), .5, true, function StopBug)
        set removeItems = Condition(function RemoveItems)
        set checkUnit = Condition(function CheckUnit)
    endfunction
endlibrary

JASS:
library Bounty initializer Initialization requires Stock
/*Utility Information
//===================================================================
Name: Bounty
Version: 1.1
Author: Nestharus

Settings:
*///===================================================================
globals
    private constant boolean ARCHIVES = false
    private constant real GOLD_UPDATE_INTERVAL = .03125
endglobals
/*//===================================================================

Description:
    What does it do-
        This creates a variable that stores the bounty of the last killed unit. This will not
        get bounty at a whim. Stock has various functions for retrieving cached bounty and randomized
        bounty on a whim. This will also make Stock's cached bounty more accurate.
        
    How does it do it-
        Player gold is stored through out the game. As players kill, the gold is updated
        and the difference between the new gold and the old gold is stored into the bounty
        variable. From here, the bounty variable can be retrieved at any time. Bounty is also archived
        for each unit type. There is a function for retrieving bounty from 30 kills back for a specific
        unit type. This archiving is only done if it is turned on.
        There is a function for retrieving bounty from 30 kills back for a specific unit type.
        
Requirements: PTN- hiveworkshop.com/forums/jass-functions-413/system-pt-player-tracking-142554/
              Recycle- thehelper.net/forums/showthread.php?t=136087
              Stock
            
Installation: NA

Variables and Settings:
------------------------------------------------------------------
ARCHIVES- whether the system archives bounty or not.

GOLD_UPDATE_INTERVAL- How often gold is updated. Gold is updated
to keep bounty accurate. Whenever players buy units or items or sell
things or gold is added to them, the gold value stored in the system
differs from that of the actual player. This results in a bounty that
isn't accurate.
------------------------------------------------------------------

Functions:
------------------------------------------------------------------
-Bounty_GetLastBounty() returns integer
    A constant function that returns the last bounty.

-Bounty_GetArchivedBounty(integer unitTypeId, integer stepsBack) returns integer
    Will return archived bounty from x steps back. 0 would be
    exactly like GetLastBounty. Stores the archive into a hashtable.
------------------------------------------------------------------*/
    globals
        private integer array playerGold
        private trigger unitBountyRecord = CreateTrigger()
        private integer lastBounty
        private hashtable bountyArchive
        private timer goldUpdate = CreateTimer()
    endglobals
    
    public function GetLastBounty takes nothing returns integer
        return lastBounty
    endfunction
    
    public function GetArchivedBounty takes integer unitTypeId, integer stepsBack returns integer
        if ARCHIVES then
            return LoadInteger(bountyArchive, unitTypeId, LoadInteger(bountyArchive, unitTypeId, -1)-stepsBack)
        endif
        return 0
    endfunction
    
    private function IntervalBounty takes nothing returns nothing
        local integer x = 16
        loop
            set x = x - 1
            set playerGold[x] = GetPlayerState(GetPlayer(x), PLAYER_STATE_RESOURCE_GOLD)
            exitwhen x == 0
        endloop
    endfunction
    
    private function UpdateBounty takes nothing returns boolean
        local player p = GetOwningPlayer(GetTriggerUnit())
        local integer playerId = GetPlayerId(p)
        local integer unitTypeId = GetUnitTypeId(GetTriggerUnit())
        local integer index
        local integer gold = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
        set lastBounty = gold-playerGold[playerId]
        set playerGold[playerId] = gold
        call Stock_UpdateBounty(unitTypeId, lastBounty, lastBounty)
        if ARCHIVES then
            set index = LoadInteger(bountyArchive, unitTypeId, -1)+1
            call SaveInteger(bountyArchive, unitTypeId, -1, index)
            call SaveInteger(bountyArchive, unitTypeId, index, lastBounty)
        endif
        return false
    endfunction
    
    private function Initialization takes nothing returns nothing
        local integer x = 16
        call TriggerAddCondition(unitBountyRecord, Condition(function UpdateBounty))
        loop
            set x = x - 1
            call TriggerRegisterPlayerUnitEvent(unitBountyRecord, GetPlayer(x), EVENT_PLAYER_UNIT_DEATH, null)
            exitwhen x == 0
        endloop
        if ARCHIVES then
            set bountyArchive = InitHashtable()
        endif
        call TimerStart(goldUpdate, GOLD_UPDATE_INTERVAL, true, function IntervalBounty)
    endfunction
endlibrary
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
New Features-
Get research gold/wood costs
Research tracking for players
Upgrade tracking for enabled units

Improvements-
Speed improvement by using a combination of hashtables and attached ids for maximum performance. The original hashed integers into array indexes.

Tighter removal area meaning not as prone to bugs when placed in a poor spot.

Faster cleanup by the use of regions instead of groups

Player Totals now include (don't think there's anything else)-
Techs, Upgrades, Units, Items, Resources
 
Level 11
Joined
Nov 4, 2007
Messages
337
Get research gold/wood costs
Tighter removal area meaning not as prone to bugs when placed in a poor spot.

Two ideas of mine that you stole.

+mine is still more efficient

-Gcsn_GetPlayerGoldResearch(player)
returns the the total gold the player spent on researching

-Gcsn_GetPlayerWoodResearch(player)
retursn the total wood the player spent on researching

-Gcsn_UpdatePlayer(player)
will update the player's total gold and wood, including all
units and items that player owns

-Gcsn_GetPlayerTotalGold(player)
will return the player's total gold. The player must
be updated for this to work.

-Gcsn_GetPlayerTotalWood(player)
will return the player's total wood. The player must
be updated for this to work.

-Gcsn_GetItemCharge(itemTypeId)

available as natives

-Gcsn_GetUnitTotalGoldCost(unit)
will return the total gold cost of the unit, items and all

-Gcsn_GetUnitTotalWoodCost(unit)
will return the total wood cost of the unit, items and all

-Gcsn_TrackUpgrades(unit)
will make the system track a unit's upgrades. It
will only track the unit's upgrades if this is called.
Once tracking has begun, it cannot be stopped until the unit
is removed from the game.

-Gcsn_StopUpgradeTracking(unit)
Will stop tracking a unit and clean it from the system

Same things mine does more efficient

-Gcsn_GetResearchGoldCost(unitTypeId, techId, start, finish)
will return the gold tech cost of techId for upgrading from
level start to level finish, aka level 0 to 1. The unitTypeId
is used to create a unit for retrieving the tech cost. The unit
must have the tech on it or the cost cannot be retrieved.

-Gcsn_GetResearchWoodCost(unitTypeId, techId, start, finish)
will return the wood tech cost of techId for upgrading from
level start to level finish, aka level 0 to 1. The unitTypeId
is used to create a unit for retrieving the tech cost. The unit
must have the tech on it or the cost cannot be retrieved.

Well, its much better/easier/more efficient to look the direct cost up in the editor instead of looking up the unit that can research the tech and the tech ID.
So in fact, those functions are totally useless.


So most of this system is useless.
Change it, really, just make a GetUnitBounty library (otherwise, i'll steal the idea and make one).
The rest is useless.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
First, updates on v5.1
-----------------------------
Multitude of speed improvements. Total costs should now be "much" faster. Getting multiple things like gold and wood cost from the same unit type or unit or item type should also be much faster. It now uses variables for currentRunningUnits, currentRunningUnitTypes, and currentRunningItemTypes =). These variables, if equal to the unit being passed into the system, will return their stack id values, currentRunningUnitStackId, currentRunningUnitTypeStackId, currentRunningItemTypeStackId =). If they are not the current running, then the ids of those 3 variables and the values of the previous 3 are updated and everything's fine =). In short, most of the time it's a very simple variable return.
-----------------------------

Two ideas of mine that you stole.
Stole nothing -.-

Your saying because yours has features nobody else can do them all of a sudden?? Those features were on my to be added list way before you even started working on yours mate.

available as natives

You're telling me these are natives?
-Gcsn_GetPlayerGoldResearch(player)
returns the the total gold the player spent on researching

-Gcsn_GetPlayerWoodResearch(player)
retursn the total wood the player spent on researching

-Gcsn_UpdatePlayer(player)
will update the player's total gold and wood, including all
units and items that player owns

-Gcsn_GetPlayerTotalGold(player)
will return the player's total gold. The player must
be updated for this to work.

-Gcsn_GetPlayerTotalWood(player)
will return the player's total wood. The player must
be updated for this to work.

-Gcsn_GetItemCharge(itemTypeId)

Did you even read the descriptions?
-Gcsn_UpdatePlayer(player)
will update the player's total gold and wood, including all
units and items that player owns

Update player gets all techs, resources, units, items, and upgrades... that is not included as a native.

Item Charges returns the default item charges, which is again, not included as a native -.-.

Also-
Well, its much better/easier/more efficient to look the direct cost up in the editor instead of looking up the unit that can research the tech and the tech ID.
So in fact, those functions are totally useless.

99% of the time, people will be getting the tech cost of a unit they are currently using...

And I would like to know what natives return the gold and wood cost of the total techs of a player =).
 
Last edited:
Level 11
Joined
Nov 4, 2007
Messages
337
Stole nothing -.-

Your saying because yours has features nobody else can do them all of a sudden?? Those features were on my to be added list way before you even started working on yours mate.

You implemented these thigns after I said so.
And you don't know when I started my library.
Stop writing things without having knowledge!
I have got proof that they haven't been on your
feature list (I can add it then, too).

You're telling me these are natives?

Yes.

Did you even read the descriptions?

Yes.

Item Charges returns the default item charges, which is again, not included as a native -.-.

wrong.

http://peeeq.de/gui.php?id=1274

Pay attention to the word 'remaining'

99% of the time, people will be getting the tech cost of a unit they are currently using...

And I would like to know what natives return the gold and wood cost of the total techs of a player =).

Well, ok.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
wrong.

http://peeeq.de/gui.php?id=1274

Pay attention to the word 'remaining'

Pay attention to the word 'default' lol

You implemented these thigns after I said so.
And you don't know when I started my library.
Stop writing things without having knowledge!
I have got proof that they haven't been on your
feature list (I can add it then, too).

I stole nothing... and I had submitted Gcsn a long long time before you had submitted GetUnitCost and it had my To Be Added List on first submission, of course the first submission required Mfn ^_^.

http://www.hiveworkshop.com/forums/graveyard-418/vjass-utility-gicn-get-item-cost-137431/

Read news 2 -.-

Oh, and look at last edited
Last edited by Nestharus; 07-31-2009 at 01:28 AM.

I'd love to see this proof of yours considering I just linked you to my oldest submission of Gcsn.
 
Level 11
Joined
Nov 4, 2007
Messages
337
Pay attention to the word 'default' lol

There is no world default lol
Fail!

[quote
I stole nothing
[/quote]

You stole the idea of tracking upgrades.

I wrote:

I would also completely remove the GetUnitGold/WoodCost functions, since the natives to the same job.
And my system is still accurrate when the units upgrade.

when you didn't have the upgrade tracking.
And then you answered:

In fact, I just figured out a good way to track the upgrades of units ^_^
In fact, that's what I'll do : D.

and added the upgrade tracking.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
In fact, I just figured out a good way to track the upgrades of units ^_^
In fact, that's what I'll do : D.

Key word, just figured out a good way to track upgrades of units
Key word, that's what I'll do

and added the upgrade tracking.

No kidding. Why do you think I hadn't added it before? Because I hadn't thought of a good way to do it without tracking all units on the map.
 
Level 11
Joined
Nov 4, 2007
Messages
337
Of course I'm not the owner of any ideas.
But isn't it clear that I see this as a competition?

Just think of this situation:
Somebody makes a system, introduces it to a website.
Then sb. comes, sees and thinks 'hey, that's a nice idea. But this and that could be made better'. And instead of telling the person what he could make better, he just makes is own system.

But well, I can accept it. Actually I don't find it very important whether this is my idea or not, but it gets different in a competition, where I want to get my system approved with my idea.
I wouldn't like it if his system is approved, mine is graveyarded, and his system uses mine idea.

I also feel that Nestharus tries to remake systems in a better way oftenly (like new Timer-Systems). But well, there are users who do that worse (I did *grin*).

Let's just say, Nestharus had the same idea (I can imagine that well, too)
But I will keep trying to get my system approved (maybe even as hardly as cohadar does. But well.. no. Cohadar flames too much when there is a system that could be better than his ones :D (well, I flamed, too, but not as much))
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Sadly that's the only way you can do it unless you hard code everything... there is something being created to import all the data into wc3 globals, but it's not done yet. You could do an interpretive script and go through Object Merger to generate a JASS file and retrieve the data, lol : ), but anyways.... this is another script that needs updating, heh... needs to be modularized.
 
Top