- Joined
- Nov 20, 2005
- Messages
- 1,156
Ever made a TD, and wanted to have a sell tower option, but wanted it to be low maintainance? Wanted to have an easy way to get the cost of the tower? Now you can, with this system.
GetUpgradeGoldCost returns the cost of the last upgrade, GetPreviousGoldCost is that of all previous expenditure APART from the last one, and GetTotalGoldCost is all gold spent. It only works for buildings that have been built at least once in game - not those that are created by triggers.
Does NOT work with lumber costing towers. As in, it might break. If you want me to change it to work with lumber as well, then drop me a PM.
Includes insta-build. If you don't want that, then just set the constant to false.
Anyway, it's easy to use, and requires NO setup - just plug and play! No need for any more laborious working. The only exception is if you are using food in your map for towers. If you are, then add into the IncrementFood function a create unit which creates a dummy unit that provides more food than any tower uses. You can then remove it in the DecrementFood function. Since they take place instantaneously, you can use a global to carry the unit across (or just imbed it straight into the code, if you know JASS; that would be more efficient).
NB: If you are using another gamecache, then you may as well merge them. If it is called gc, then great, simple remove the global for it from this library, and also the init call for it at the bottom. If not, remove the global and init call, and then do a fine and replay for gc with whatever your game cache variable is.
If you feel this is beyond you, then adding 'private' to the line 'gamecache gc', to give 'private gamecache gc', will solve the problem, but won't be quite so memory efficient.
NB2: You may encounter problems with some pathing problems, I'm not sure. You SHOULDN'T with this version, but then again, WC3 can work in strange and wonderful ways.
Updated. Now fully supports lumber and food, includes functions to get them. Fixed possible bugs in the original release, some that could cause critical errors due to Blizzard bugs (I've run into so many of them on this script it is rediculous).
Updated again. Should fix bug with refunding first building cost (unless of course that was brought about by a patch, in which case it won't). Also adds support for getting unit costs.
GetUpgradeGoldCost returns the cost of the last upgrade, GetPreviousGoldCost is that of all previous expenditure APART from the last one, and GetTotalGoldCost is all gold spent. It only works for buildings that have been built at least once in game - not those that are created by triggers.
Includes insta-build. If you don't want that, then just set the constant to false.
Anyway, it's easy to use, and requires NO setup - just plug and play! No need for any more laborious working. The only exception is if you are using food in your map for towers. If you are, then add into the IncrementFood function a create unit which creates a dummy unit that provides more food than any tower uses. You can then remove it in the DecrementFood function. Since they take place instantaneously, you can use a global to carry the unit across (or just imbed it straight into the code, if you know JASS; that would be more efficient).
NB: If you are using another gamecache, then you may as well merge them. If it is called gc, then great, simple remove the global for it from this library, and also the init call for it at the bottom. If not, remove the global and init call, and then do a fine and replay for gc with whatever your game cache variable is.
If you feel this is beyond you, then adding 'private' to the line 'gamecache gc', to give 'private gamecache gc', will solve the problem, but won't be quite so memory efficient.
NB2: You may encounter problems with some pathing problems, I'm not sure. You SHOULDN'T with this version, but then again, WC3 can work in strange and wonderful ways.
Updated. Now fully supports lumber and food, includes functions to get them. Fixed possible bugs in the original release, some that could cause critical errors due to Blizzard bugs (I've run into so many of them on this script it is rediculous).
Updated again. Should fix bug with refunding first building cost (unless of course that was brought about by a patch, in which case it won't). Also adds support for getting unit costs.
JASS:
library CGUnitCost initializer Init
globals // This is the only code you should touch. Touch anything else and it's at your own risk.
private constant boolean INSTA_BUILD = true //if you want it to instabuild and upgrade; note that upgrades will keep the same scaling size, regardless of object editor settings (native bug)
private constant string GAME_CACHE_STRING = "cgbuildingblargh" // just make sure this doesn't collide with anything
private constant real DISTANCE_CHECK_RANGE = 150. // max distance a worker might be able to move and start building in 0.05 seconds.
// Also max distance where a worker may get in the way of the building, and thus have to move out of its own way; bigger buildings than a castle may need a higher value
// Designed to stop unnecessary pausing (which can interrupt UI stuff) while maintaining safety. 100 should be fine.
private gamecache gc // don't touch this.
endglobals
// These can be used to get the values. NB: ONLY use on buildings that have been built in game.
function GetUpgradeGoldCost takes integer id returns integer // returns the cost of the last upgrade, OR the cost of building (if not upgraded)
return GetStoredInteger(gc, "CGupgradeGold", I2S(id))
endfunction
function GetTotalGoldCost takes integer id returns integer // Cost of last and all previous
return GetStoredInteger(gc, "CGtotalGold", I2S(id))
endfunction
function GetPreviousGoldCost takes integer id returns integer // Cost of gold/lumber/food spent not counting the last one (bit misleading name)
return GetStoredInteger(gc, "CGpreviousGold", I2S(id))
endfunction
function GetUpgradeLumberCost takes integer id returns integer // returns the cost of the last upgrade, OR the cost of building (if not upgraded)
return GetStoredInteger(gc, "CGupgradeLumber", I2S(id))
endfunction
function GetTotalLumberCost takes integer id returns integer // Cost of last and all previous
return GetStoredInteger(gc, "CGtotalLumber", I2S(id))
endfunction
function GetPreviousLumberCost takes integer id returns integer // Cost of gold/lumber/food spent not counting the last one (bit misleading name)
return GetStoredInteger(gc, "CGpreviousLumber", I2S(id))
endfunction
function GetUpgradeFoodCost takes integer id returns integer // returns the cost of the last upgrade, OR the cost of building (if not upgraded)
return GetStoredInteger(gc, "CGupgradeFood", I2S(id))
endfunction
function GetTotalFoodCost takes integer id returns integer // Cost of last and all previous
return GetFoodUsed(id)
endfunction
function GetPreviousFoodCost takes integer id returns integer // Cost of gold/lumber/food spent not counting the last one (bit misleading name)
return GetStoredInteger(gc, "CGpreviousFood", I2S(id))
endfunction
// Don't mess with this stuff unless you want to spend hours painstakingly debugging. WC3 is full of bugs.
private function TimerAttach takes timer t, real dur, real val, code func returns nothing
call TimerStart(t, val, false, null)
call PauseTimer(t)
call TimerStart(t, dur, false, func)
endfunction
globals
private unit array built
private unit array ordered
private integer array orderedID
private real array orderedX
private real array orderedY
private integer c = 1
private integer o = 1
private trigger trg_order
private trigger trg_upgrade
private trigger trg_train
private integer q = 1
private unit array qUnit
private integer array qId
private real array qX
private real array qY
private group g
private real distanceCheck
private integer loopInt
private unit array listU
private boolean array listSelected
endglobals
private function UpgradeEx takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local integer id = GetUnitTypeId(u)
local integer gold = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
local integer lumber = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
local integer iG
local integer iL
local integer iF
local integer costPrevious
local string s = I2S(id)
local integer idOld
call DisableTrigger(trg_upgrade)
call IssueImmediateOrderById(u, 851976)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, 99999999)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, 99999999)
set iG = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD) // incase a limit exists
set iL = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
set idOld = GetUnitTypeId(u)
call IssueImmediateOrderById(u, id)
set iG = iG - GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
set iL = iL - GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
call StoreInteger(gc, "CGupgradeGold", s, iG)
set costPrevious = GetTotalGoldCost(idOld)
call StoreInteger(gc, "CGpreviousGold", s, costPrevious)
call StoreInteger(gc, "CGtotalGold", s, iG+costPrevious)
call StoreInteger(gc, "CGupgradeLumber", s, iL)
set costPrevious = GetTotalLumberCost(idOld)
call StoreInteger(gc, "CGpreviousLumber", s, costPrevious)
call StoreInteger(gc, "CGtotalLumber", s, iL+costPrevious)
set iF = GetFoodUsed(id)
set costPrevious = GetFoodUsed(idOld)
call StoreInteger(gc, "CGpreviousFood", s, costPrevious)
call StoreInteger(gc, "CGupgradeFood", s, iF-costPrevious)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, gold)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, lumber)
call EnableTrigger(trg_upgrade)
set u = null
endfunction
private function Upgrade takes nothing returns boolean
if not(HaveStoredInteger(gc, "CGtotalGold", I2S(GetUnitTypeId(GetTriggerUnit())))) then
call UpgradeEx()
endif
if INSTA_BUILD then
call UnitSetUpgradeProgress(GetTriggerUnit(), 100)
endif
return false
endfunction
private function BuildEx2 takes nothing returns nothing
local unit u = built[R2I(TimerGetRemaining(GetExpiredTimer())+0.9)]
local integer i = GetPlayerState(GetOwningPlayer(u), PLAYER_STATE_RESOURCE_FOOD_CAP)
call UnitSetConstructionProgress(u, 100)
call SetPlayerState(GetOwningPlayer(u), PLAYER_STATE_RESOURCE_FOOD_CAP, i + GetUnitFoodMade(u)) //did I mention WC3 sucks? Bug with double food sometimes.
set u = null
call DestroyTimer(GetExpiredTimer())
endfunction
private function Build takes nothing returns boolean
//if INSTA_BUILD then // this isn't needed, but I left it as a reminder this code ONLY runs if INSTA_BUILD is set to true.
set built[c] = GetConstructingStructure()
call TimerAttach(CreateTimer(), 0.1, c, function BuildEx2)
if c >= 254 then
set c = 1
else
set c = c + 1
endif
//endif
return false
endfunction
private function OrderEx4 takes nothing returns nothing
call RemoveUnit(ordered[R2I(TimerGetRemaining(GetExpiredTimer())+0.9)])
call DestroyTimer(GetExpiredTimer())
endfunction
private function OrderEx3 takes nothing returns nothing
local integer i = R2I(TimerGetRemaining(GetExpiredTimer())+0.9)
local player p = GetOwningPlayer(ordered[i])
call DisableTrigger(trg_order)
call PauseUnit(ordered[i], true)
call IssueImmediateOrder(ordered[i], "stop")
call PauseUnit(ordered[i], false)
call TimerAttach(GetExpiredTimer(), 0.1, i, function OrderEx4)
call EnableTrigger(trg_order)
endfunction
private function EnumEx takes nothing returns boolean
local unit u = GetFilterUnit()
set listU[loopInt] = u
set listSelected[loopInt] = IsUnitSelected(u, GetLocalPlayer())
call ShowUnit(u, false)
set loopInt = loopInt + 1
set u = null
return false
endfunction
private function OrderEx2 takes unit t, integer id, real x, real y returns nothing
local player p = GetOwningPlayer(t)
local integer uid = GetUnitTypeId(t)
local unit u
local string s = I2S(id)
local integer gold = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
local integer lumber = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
local integer cap = GetPlayerState(p, PLAYER_STATE_RESOURCE_FOOD_CAP)
local integer ceiling = GetPlayerState(p, PLAYER_STATE_FOOD_CAP_CEILING)
local integer food = GetFoodUsed(id)
local integer iG
local integer iL
local integer max
call DisableTrigger(trg_order)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, 99999999)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, 99999999)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_FOOD_CAP, 10000)
call SetPlayerState(p, PLAYER_STATE_FOOD_CAP_CEILING, 10000)
set iG = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD) // incase a limit exists
set iL = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
set u = CreateUnit(p, uid, 0., 0., 0.)
call SetUnitUseFood(u, false)
call SetUnitVertexColor(u, 0, 0, 0, 0)
call UnitAddAbility(u, 'Aloc')
call IssueBuildOrderById(u, id, x, y)
set iG = iG - GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
set iL = iL - GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_FOOD_CAP, cap)
call SetPlayerState(p, PLAYER_STATE_FOOD_CAP_CEILING, ceiling)
call StoreInteger(gc, "CGupgradeFood", s, food)
call StoreInteger(gc, "CGtotalGold", s, iG)
call StoreInteger(gc, "CGupgradeGold", s, iG)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, gold - iG)
call StoreInteger(gc, "CGtotalLumber", s, iL)
call StoreInteger(gc, "CGupgradeLumber", s, iL)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, lumber - iL)
set ordered[o] = u
call TimerAttach(CreateTimer(), 0.05, o, function OrderEx3)
if o >= 254 then
set o = 1
else
set o = o + 1
endif
call PauseUnit(u, true)
call ShowUnit(u, false)
call PauseUnit(t, false)
call EnableTrigger(trg_order)
set u = null
endfunction
private function OrderEx takes nothing returns nothing
local integer i = R2I(TimerGetRemaining(GetExpiredTimer())+0.9)
call OrderEx2(ordered[i],orderedID[i], orderedX[i], orderedY[i])
call DestroyTimer(GetExpiredTimer())
endfunction
private function DistanceShort takes real x1, real x2, real y1, real y2 returns boolean
local real dx = x1 - x2
local real dy = y1 - y2
return dx*dx + dy * dy < distanceCheck
endfunction
private function Order takes nothing returns boolean
local integer id = GetIssuedOrderId()
if IsUnitIdType(id, UNIT_TYPE_STRUCTURE) == true and not(HaveStoredInteger(gc, "CGtotalGold", I2S(id))) then
set ordered[o] = GetTriggerUnit()
set orderedID[o] = id
set orderedX[o] = GetOrderPointX()
set orderedY[o] = GetOrderPointY()
if DistanceShort(GetOrderPointX(), GetUnitX(GetTriggerUnit()), GetOrderPointY(), GetUnitY(GetTriggerUnit())) then
call PauseUnit(GetTriggerUnit(), true)
endif
call TimerAttach(CreateTimer(), 0.01, o, function OrderEx)
if o >= 254 then
set o = 1
else
set o = o + 1
endif
endif
return false
endfunction
private function TrainEx takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local integer id = GetTrainedUnitType()
local integer gold = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
local integer lumber = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
local integer iG
local integer iL
local string s = I2S(id)
call DisableTrigger(trg_train)
call IssueImmediateOrderById(u, 851976)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, 99999999)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, 99999999)
set iG = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD) // incase a limit exists
set iL = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
call IssueImmediateOrderById(u, id)
set iG = iG - GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
set iL = iL - GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
call StoreInteger(gc, "CGupgradeGold", s, iG)
call StoreInteger(gc, "CGtotalGold", s, iG)
call StoreInteger(gc, "CGupgradeLumber", s, iL)
call StoreInteger(gc, "CGtotalLumber", s, iL)
call StoreInteger(gc, "CGupgradeFood", s, GetFoodUsed(id))
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, gold)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, lumber)
call EnableTrigger(trg_train)
set u = null
endfunction
private function Train takes nothing returns boolean
if not(HaveStoredInteger(gc, "CGtotalGold", I2S(GetTrainedUnitType()))) then
call TrainEx()
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t1 = CreateTrigger()
local trigger t2 = CreateTrigger()
local trigger t3 = CreateTrigger()
local trigger t4 = CreateTrigger()
local boolexpr bx1 = Condition(function Upgrade)
local boolexpr bx2 = Condition(function Build)
local boolexpr bx3 = Condition(function Order)
local boolexpr bx4 = Condition(function Train)
local integer i = 0
loop
exitwhen i >= 16
call TriggerRegisterPlayerUnitEvent(t1, Player(i), EVENT_PLAYER_UNIT_UPGRADE_START, null)
if INSTA_BUILD then
call TriggerRegisterPlayerUnitEvent(t2, Player(i), EVENT_PLAYER_UNIT_CONSTRUCT_START, null)
endif
call TriggerRegisterPlayerUnitEvent(t3, Player(i), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
call TriggerRegisterPlayerUnitEvent(t4, Player(i), EVENT_PLAYER_UNIT_TRAIN_START, null)
set i = i + 1
endloop
call TriggerAddCondition(t1, bx1)
if INSTA_BUILD then
call TriggerAddCondition(t2, bx2)
endif
call TriggerAddCondition(t3, bx3)
call TriggerAddCondition(t4, bx4)
set trg_order = t3
set trg_upgrade = t1
set trg_train = t4
set g = CreateGroup()
set distanceCheck = DISTANCE_CHECK_RANGE * DISTANCE_CHECK_RANGE
call FlushGameCache(InitGameCache(GAME_CACHE_STRING))
set gc = InitGameCache(GAME_CACHE_STRING)
endfunction
endlibrary
JASS:
library BuildingCost initializer Init
globals // This is the only code you should touch. Touch anything else and it's at your own risk.
private constant boolean INSTA_BUILD = true //if you want it to instabuild
private constant string GAME_CACHE_STRING = "cgbuildingblargh" // just make sure this doesn't collide with anything
private constant real DUMMY_X = 0. // doesn't really matter what this, it'll work anywhere, BUT
private constant real DUMMY_Y = 0. // There will be a flicker of a shadow here every first instance of a building; suggest you put it in some trees.
private constant real DISTANCE_CHECK_RANGE = 100. // max distance a worker might be able to move and start building in 0.05 seconds.
// Designed to stop unnecessary pausing (which can interrupt UI stuff) while maintaining safety. 100 should be fine.
private gamecache gc = null // don't touch this.
endglobals
// These can be used to get the values. NB: ONLY use on buildings that have been built in game.
function GetUpgradeGoldCost takes integer id returns integer // returns the cost of the last upgrade, OR the cost of building (if not upgraded)
return GetStoredInteger(gc, "CGupgradeGold", I2S(id))
endfunction
function GetTotalGoldCost takes integer id returns integer // Cost of last and all previous
return GetStoredInteger(gc, "CGtotalGold", I2S(id))
endfunction
function GetPreviousGoldCost takes integer id returns integer // Cost of gold/lumber/food spent not counting the last one (bit misleading name)
return GetStoredInteger(gc, "CGpreviousGold", I2S(id))
endfunction
function GetUpgradeLumberCost takes integer id returns integer // returns the cost of the last upgrade, OR the cost of building (if not upgraded)
return GetStoredInteger(gc, "CGupgradeLumber", I2S(id))
endfunction
function GetTotalLumberCost takes integer id returns integer // Cost of last and all previous
return GetStoredInteger(gc, "CGtotalLumber", I2S(id))
endfunction
function GetPreviousLumberCost takes integer id returns integer // Cost of gold/lumber/food spent not counting the last one (bit misleading name)
return GetStoredInteger(gc, "CGpreviousLumber", I2S(id))
endfunction
function GetUpgradeFoodCost takes integer id returns integer // returns the cost of the last upgrade, OR the cost of building (if not upgraded)
return GetStoredInteger(gc, "CGupgradeFood", I2S(id))
endfunction
function GetTotalFoodCost takes integer id returns integer // Cost of last and all previous
return GetFoodUsed(id)
endfunction
function GetPreviousFoodCost takes integer id returns integer // Cost of gold/lumber/food spent not counting the last one (bit misleading name)
return GetStoredInteger(gc, "CGpreviousFood", I2S(id))
endfunction
// Don't mess with this stuff unless you want to spend hours painstakingly debugging. WC3 is full of bugs.
private function TimerAttach takes timer t, real dur, real val, code func returns nothing
call TimerStart(t, val, false, null)
call PauseTimer(t)
call TimerStart(t, dur, false, func)
endfunction
globals
private unit array built
private unit array ordered
private integer array orderedID
private real array orderedX
private real array orderedY
private integer c = 1
private integer o = 1
private trigger trg_order
private trigger trg_upgrade
private integer q = 1
private unit array qUnit
private integer array qId
private real array qX
private real array qY
private group g
private real distanceCheck
private integer loopInt
private unit array listU
private boolean array listSelected
endglobals
private function UpgradeEx takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local integer id = GetUnitTypeId(u)
local integer gold = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
local integer lumber = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
local integer iG
local integer iL
local integer iF
local integer costPrevious
local string s = I2S(id)
local integer idOld
call DisableTrigger(trg_upgrade)
call IssueImmediateOrderById(u, 851976)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, 99999999)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, 99999999)
set iG = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD) // incase a limit exists
set iL = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
set idOld = GetUnitTypeId(u)
call IssueImmediateOrderById(u, id)
set iG = iG - GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
set iL = iL - GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
call StoreInteger(gc, "CGupgradeGold", s, iG)
set costPrevious = GetTotalGoldCost(idOld)
call StoreInteger(gc, "CGpreviousGold", s, costPrevious)
call StoreInteger(gc, "CGtotalGold", s, iG+costPrevious)
call StoreInteger(gc, "CGupgradeLumber", s, iL)
set costPrevious = GetTotalLumberCost(idOld)
call StoreInteger(gc, "CGpreviousLumber", s, costPrevious)
call StoreInteger(gc, "CGtotalLumber", s, iL+costPrevious)
set iF = GetFoodUsed(id)
set costPrevious = GetFoodUsed(idOld)
call StoreInteger(gc, "CGpreviousFood", s, costPrevious)
call StoreInteger(gc, "CGupgradeFood", s, iF-costPrevious)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, gold)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, lumber)
call EnableTrigger(trg_upgrade)
set u = null
endfunction
private function Upgrade takes nothing returns boolean
if not(HaveStoredInteger(gc, "CGtotalGold", I2S(GetUnitTypeId(GetTriggerUnit())))) then
call UpgradeEx()
endif
if INSTA_BUILD then
call UnitSetUpgradeProgress(GetTriggerUnit(), 100)
endif
return false
endfunction
private function BuildEx2 takes nothing returns nothing
local unit u = built[R2I(TimerGetRemaining(GetExpiredTimer())+0.9)]
local integer i = GetPlayerState(GetOwningPlayer(u), PLAYER_STATE_RESOURCE_FOOD_CAP)
call UnitSetConstructionProgress(u, 100)
call SetPlayerState(GetOwningPlayer(u), PLAYER_STATE_RESOURCE_FOOD_CAP, i + GetUnitFoodMade(u)) //did I mention WC3 sucks? Bug with double food sometimes.
set u = null
call DestroyTimer(GetExpiredTimer())
endfunction
private function Build takes nothing returns boolean
//if INSTA_BUILD then // this isn't needed, but I left it as a reminder this code ONLY runs if INSTA_BUILD is set to true.
set built[c] = GetConstructingStructure()
call TimerAttach(CreateTimer(), 0.1, c, function BuildEx2)
if c >= 254 then
set c = 1
else
set c = c + 1
endif
//endif
return false
endfunction
private function OrderEx4 takes nothing returns nothing
call RemoveUnit(ordered[R2I(TimerGetRemaining(GetExpiredTimer())+0.9)])
call DestroyTimer(GetExpiredTimer())
endfunction
private function OrderEx3 takes nothing returns nothing
local integer i = R2I(TimerGetRemaining(GetExpiredTimer())+0.9)
local player p = GetOwningPlayer(ordered[i])
local integer gold = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
local integer lumber = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
call DisableTrigger(trg_order)
call PauseUnit(ordered[i], true)
call IssueImmediateOrder(ordered[i], "stop")
call PauseUnit(ordered[i], false)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, gold)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, lumber)
call TimerAttach(GetExpiredTimer(), 0.1, i, function OrderEx4)
call EnableTrigger(trg_order)
endfunction
private function EnumEx takes nothing returns boolean
local unit u = GetFilterUnit()
set listU[loopInt] = u
set listSelected[loopInt] = IsUnitSelected(u, GetLocalPlayer())
call ShowUnit(u, false)
set loopInt = loopInt + 1
set u = null
return false
endfunction
private function OrderEx2 takes unit t, integer id, real x, real y returns nothing
local player p = GetOwningPlayer(t)
local integer uid = GetUnitTypeId(t)
local unit u
local string s = I2S(id)
local integer gold = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
local integer lumber = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
local integer cap = GetPlayerState(p, PLAYER_STATE_RESOURCE_FOOD_CAP)
local integer ceiling = GetPlayerState(p, PLAYER_STATE_FOOD_CAP_CEILING)
local integer food = GetFoodUsed(id)
local integer iG
local integer iL
local integer max
call DisableTrigger(trg_order)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, 99999999)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, 99999999)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_FOOD_CAP, 10000)
call SetPlayerState(p, PLAYER_STATE_FOOD_CAP_CEILING, 10000)
set iG = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD) // incase a limit exists
set iL = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
set u = CreateUnit(p, uid, DUMMY_X, DUMMY_Y, 0.)
call SetUnitVertexColor(u, 0, 0, 0, 0)
call UnitAddAbility(u, 'Aloc')
call IssueBuildOrderById(u, id, x, y)
set iG = iG - GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
set iL = iL - GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_FOOD_CAP, cap)
call SetPlayerState(p, PLAYER_STATE_FOOD_CAP_CEILING, ceiling)
call StoreInteger(gc, "CGupgradeFood", s, food)
call StoreInteger(gc, "CGtotalGold", s, iG)
call StoreInteger(gc, "CGupgradeGold", s, iG)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, gold)
call StoreInteger(gc, "CGtotalLumber", s, iL)
call StoreInteger(gc, "CGupgradeLumber", s, iL)
call SetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER, lumber)
set ordered[o] = u
call TimerAttach(CreateTimer(), 0.05, o, function OrderEx3)
if o >= 254 then
set o = 1
else
set o = o + 1
endif
call PauseUnit(u, true)
call PauseUnit(t, false)
call EnableTrigger(trg_order)
set u = null
endfunction
private function OrderEx takes nothing returns nothing
local integer i = R2I(TimerGetRemaining(GetExpiredTimer())+0.9)
call OrderEx2(ordered[i],orderedID[i], orderedX[i], orderedY[i])
call DestroyTimer(GetExpiredTimer())
endfunction
private function DistanceShort takes real x1, real x2, real y1, real y2 returns boolean
local real dx = x1 - x2
local real dy = y1 - y2
return dx*dx + dy * dy < distanceCheck
endfunction
private function Order takes nothing returns boolean
local integer id = GetIssuedOrderId()
if IsUnitIdType(id, UNIT_TYPE_STRUCTURE) == true and not(HaveStoredInteger(gc, "CGtotalGold", I2S(id))) then
set ordered[o] = GetTriggerUnit()
set orderedID[o] = id
set orderedX[o] = GetOrderPointX()
set orderedY[o] = GetOrderPointY()
if DistanceShort(GetOrderPointX(), GetUnitX(GetTriggerUnit()), GetOrderPointY(), GetUnitY(GetTriggerUnit())) then
call PauseUnit(GetTriggerUnit(), true)
endif
call TimerAttach(CreateTimer(), 0.01, o, function OrderEx)
if o >= 254 then
set o = 1
else
set o = o + 1
endif
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t1 = CreateTrigger()
local trigger t2 = CreateTrigger()
local trigger t3 = CreateTrigger()
local boolexpr bx1 = Condition(function Upgrade)
local boolexpr bx2 = Condition(function Build)
local boolexpr bx3 = Condition(function Order)
local integer i = 0
loop
exitwhen i >= 12
call TriggerRegisterPlayerUnitEvent(t1, Player(i), EVENT_PLAYER_UNIT_UPGRADE_START, null)
if INSTA_BUILD then
call TriggerRegisterPlayerUnitEvent(t2, Player(i), EVENT_PLAYER_UNIT_CONSTRUCT_START, null)
endif
call TriggerRegisterPlayerUnitEvent(t3, Player(i), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, null)
set i = i + 1
endloop
call TriggerAddCondition(t1, bx1)
if INSTA_BUILD then
call TriggerAddCondition(t2, bx2)
endif
call TriggerAddCondition(t3, bx3)
set trg_order = t3
set trg_upgrade = t1
set t1 = null
set t2 = null
set t3 = null
set g = CreateGroup()
set distanceCheck = DISTANCE_CHECK_RANGE * DISTANCE_CHECK_RANGE
call FlushGameCache(InitGameCache(GAME_CACHE_STRING))
set gc = InitGameCache(GAME_CACHE_STRING)
endfunction
endlibrary
Last edited: