- Joined
- Dec 12, 2008
- Messages
- 7,385
Ceday, creating a unit with a different unit type for a specific player will cause a desync at one point 
function CreateUnitWithDifferentModel takes player p, integer unitId1, integer unitId2, real x, real y, real facing returns /*Desync if there is another different object editor setting other than model :O*/ unit
if GetLocalPlayer() == p then
set unitId1 = unitId2
endif
return CreateUnit(p, unitId1, x, y, facing)
endfunction
There are 0 normal footmans in game.
There are 2 footman with captain model in game.
Id = custom_h002|nLife = 258.785
Id = custom_h002|nLife = 257.930
There are 2 normal footmans in game.
There are 0 footman wtih captain model in game.
Id = footman|nLife = 258.785
Id = footman|nLife = 257.930
function Trig_Test_3_If_Actions takes nothing returns nothing
local integer id = GetUnitTypeId(GetDyingUnit())
if id == 'hfoo' then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Normal footman dead")
elseif id == 'h002' then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Footman with captain model dead")
endif
endfunction
if (GetUnitTypeId(<asyncUnit>) == 'hfoo') then
call BJDebugMsg("bla")
endif
Disclaimer: make sure to check for both unit types when checking the unit type
If you have a boolean expression that checks if a unit is of a certain type, well.. you can predict the rest![]()
library SaveHeroStats /*
*************************************************************************************
*
* Saves hero strength, agility, and intelligence
*
*************************************************************************************
*
* */uses/*
*
* */ NumberStack /* hiveworkshop.com/forums/1993458-post521.html
*
************************************************************************************
*
*
* SETTINGS
*/
globals
/*************************************************************************************
*
* ALL_STATS_SPENT
*
* Every stat point is spent at every level
*
* If every stat point is spent at every level, the strength can be calculated from
* the remaining stat points. If the stat points are not spent, the strength has
* to be stored in the code.
*
* Stat points spent at every level means a smaller code.
*
*************************************************************************************/
private constant boolean ALL_STATS_SPENT = true
/*************************************************************************************
*
* SPLIT_BONUSES
*
* Makes bonus specific to each stat rather than shared among all stats.
*
* If SPLIT_BONUSES is true and 1024 is passed in as a max bonus, 1024 will be the cap
* for each individual stat.
*
* If SPLIT_BONUSES is false and 1024 is passed in as a max bonus, 1024 will be the cap
* for all three stats put together. If intelligence is 500, then 524 bonus stats
* will be left.
*
*************************************************************************************/
private constant boolean SPLIT_BONUSES = false
endglobals
/*
************************************************************************************
* function SaveHeroStats takes NumberStack stack, unit whichUnit, integer maxBonusForLevel returns nothing
* function LoadHeroStats takes NumberStack stack, unit whichUnit, integer maxBonusForLevel returns nothing
*
************************************************************************************/
function SaveHeroStats takes NumberStack stack, unit whichUnit, integer maxBonusForLevel returns nothing
local unit u
static if SPLIT_BONUSES then
local integer bonusStr
elseif not ALL_STATS_SPENT then
local integer bonusStr
endif
local integer bonusAgi
local integer bonusInt
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = false
endif
set u = CreateUnit(Player(15), GetUnitTypeId(whichUnit), GetRectMaxX(bj_mapInitialPlayableArea), GetRectMaxY(bj_mapInitialPlayableArea), 0)
call SetHeroLevel(u, GetHeroLevel(whichUnit), false)
static if SPLIT_BONUSES then
set bonusStr = GetHeroStr(whichUnit, false)-GetHeroStr(u, false)
elseif not ALL_STATS_SPENT then
set bonusStr = GetHeroStr(whichUnit, false)-GetHeroStr(u, false)
endif
set bonusAgi = GetHeroAgi(whichUnit, false)-GetHeroAgi(u, false)
set bonusInt = GetHeroInt(whichUnit, false)-GetHeroInt(u, false)
static if SPLIT_BONUSES then
call stack.push(bonusStr, maxBonusForLevel)
call stack.push(bonusAgi, maxBonusForLevel)
call stack.push(bonusInt, maxBonusForLevel)
else
static if not ALL_STATS_SPENT then
call stack.push(bonusStr, maxBonusForLevel-bonusAgi-bonusInt)
endif
//else
//bonus strength is the remaining bonus points
call stack.push(bonusAgi, maxBonusForLevel-bonusInt)
call stack.push(bonusInt, maxBonusForLevel)
endif
call RemoveUnit(u)
set u = null
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = true
endif
endfunction
function LoadHeroStats takes NumberStack stack, unit whichUnit, integer maxBonusForLevel returns nothing
local unit u
local integer bonusStr
local integer bonusAgi
local integer bonusInt
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = false
endif
set u = CreateUnit(Player(15), GetUnitTypeId(whichUnit), GetRectMaxX(bj_mapInitialPlayableArea), GetRectMaxY(bj_mapInitialPlayableArea), 0)
call SetHeroLevel(u, GetHeroLevel(whichUnit), false)
static if SPLIT_BONUSES then
set bonusInt = stack.pop(maxBonusForLevel)
set bonusAgi = stack.pop(maxBonusForLevel)
set bonusStr = stack.pop(maxBonusForLevel)
else
set bonusInt = stack.pop(maxBonusForLevel)
set bonusAgi = stack.pop(maxBonusForLevel-bonusInt)
static if ALL_STATS_SPENT then
set bonusStr = maxBonusForLevel-bonusAgi-bonusInt
else
set bonusStr = stack.pop(maxBonusForLevel-bonusAgi-bonusInt)
endif
endif
call SetHeroInt(whichUnit, bonusInt+GetHeroInt(u, false), true)
call SetHeroAgi(whichUnit, bonusAgi+GetHeroAgi(u, false), true)
call SetHeroStr(whichUnit, bonusStr+GetHeroStr(u, false), true)
call RemoveUnit(u)
set u = null
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = true
endif
endfunction
endlibrary
static if not ALL_STATS_SPENT then
call stack.push(GetHeroStr(whichUnit, false)-GetHeroStr(u, false), maxBonusForLevel-bonusAgi-bonusInt)
endif
library SaveHeroAbilities /*
*************************************************************************************
*
* Saves learnable hero abilities.
*
*************************************************************************************
*
* */uses/*
*
* */ NumberStack /* hiveworkshop.com/forums/1993458-post521.html
* */ Catalog /* hiveworkshop.com/forums/jass-functions-413/snippet-catalog-192452/
* */ Table /* hiveworkshop.com/forums/jass-functions-413/snippet-new-table-188084/
*
************************************************************************************
*
* function SaveHeroAbilities takes NumberStack stack, unit whichUnit, Catalog abilityCatalog returns nothing
* function LoadHeroAbilities takes NumberStack stack, unit whichUnit, Catalog abilityCatalog returns nothing
*
* abilityCatalog
* --------------------------------
*
* abilityCatalog should be specific to the hero and contain all of the hero's learnable abilities.
*
************************************************************************************/
private function GetMaxAbilityLevel takes unit whichUnit, integer abilityId returns integer
local integer maxLevel = 0
loop
call SelectHeroSkill(whichUnit, abilityId)
exitwhen maxLevel == GetUnitAbilityLevel(whichUnit, abilityId)
set maxLevel = GetUnitAbilityLevel(whichUnit, abilityId)
endloop
return maxLevel
endfunction
function SaveHeroAbilities takes NumberStack stack, unit whichUnit, Catalog abilityCatalog returns nothing
local unit u
local integer i
local integer abilityId
local integer maxLevel
local integer array levels
local integer array maxLevels
local integer abilCount = 0
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = false
endif
//create a dummy unit for retrieving maximum ability levels
set u = CreateUnit(Player(15), GetUnitTypeId(whichUnit), GetRectMaxX(bj_mapInitialPlayableArea), GetRectMaxY(bj_mapInitialPlayableArea), 0)
call SetHeroLevel(u, GetHeroLevel(whichUnit), false)
//for each learnable ability of unit
set i = abilityCatalog.count
loop
exitwhen 0 == i or 0 == GetHeroSkillPoints(u)
set abilityId = abilityCatalog.raw(i) //retrieve ability
set maxLevel = GetMaxAbilityLevel(u, abilityId) //retrieve max level
//if the max level isn't 0, store it for saving
if (0 < maxLevel) then
//store for saving so that loader can load in same order as the saver saved (save
//in reverse order so loader and load in normal order).
set maxLevels[abilCount] = maxLevel
set levels[abilCount] = GetUnitAbilityLevel(whichUnit, abilityId)
//give skill points not spent by actual unit back to dummy unit
call UnitModifySkillPoints(u, maxLevel-levels[abilCount])
set abilCount = abilCount + 1
endif
set i = i - 1
endloop
//loop through all stored abilities *backwards* so that the loader
//can loop in same order as first loop
loop
exitwhen 0 == abilCount
set abilCount = abilCount - 1
call stack.push(levels[abilCount], maxLevels[abilCount])
endloop
call RemoveUnit(u)
set u = null
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = true
endif
endfunction
function LoadHeroAbilities takes NumberStack stack, unit whichUnit, Catalog abilityCatalog returns nothing
local unit u
local integer i
local integer abilityId
local integer level
local integer maxLevel
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = false
endif
set u = CreateUnit(Player(15), GetUnitTypeId(whichUnit), GetRectMaxX(bj_mapInitialPlayableArea), GetRectMaxY(bj_mapInitialPlayableArea), 0)
call SetHeroLevel(u, GetHeroLevel(whichUnit), false)
set i = abilityCatalog.count
loop
exitwhen 0 == i or 0 == GetHeroSkillPoints(u)
set abilityId = abilityCatalog.raw(i)
set maxLevel = GetMaxAbilityLevel(u, abilityId)
if (0 < maxLevel) then
set level = stack.pop(maxLevel)
call UnitModifySkillPoints(u, maxLevel-level)
if (0 < level) then
call SelectHeroSkill(whichUnit, abilityId)
if (1 < level) then
call SetUnitAbilityLevel(whichUnit, abilityId, level)
call UnitModifySkillPoints(whichUnit, -level+1)
endif
endif
endif
set i = i - 1
endloop
call RemoveUnit(u)
set u = null
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = true
endif
endfunction
endlibrary
SquareRoot(x)
VS. Pow(x,0.5)
library TimerOne
private module Init
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(),1.0,true,function e)
endmethod
endmodule
struct TimerOne extends array
private static trigger t = CreateTrigger()
private static method e takes nothing returns nothing
call TriggerEvaluate(t)
endmethod
static method register takes boolexpr b returns nothing
call TriggerAddCondition(t,b)
endmethod
implement Init
endstruct
endlibrary
Let's do a benchmark then
4000 individual timers with 4000 callbacks VS 1 timer and 1 trigger evaluation-
Nevermind, I convinced myself the second should be faster![]()
Already benched and the 1 timer with 1 trigger evaluation and 4000 trigger conditions on it won by a long shot.
Still WaterKnight caught the big point, all will be fired at the same time. Be happy that you haven't registered unit orders...
I'm using it for lots of stuff:
- Multiboard Update
- Leaderboard Update
- Game Time Update
- Streak System Multikills Update
- Spawn System
- AI script Data Buffer
- AI script Core
etc..
Trust me, you'll have TONS of 1-second timeout timers in a map![]()
What (do you want to mean) ?!
TriggerRemoveCondition exists.
//Use Spinnakers (The one below doesn't work)
function SetBuildingFacing takes unit u, real a returns nothing
call UnitRemoveType(u, UNIT_TYPE_STRUCTURE)
call SetUnitTurnSpeed(u,9999.0)
call SetUnitFacing(u, a)
call UnitAddType(u, UNIT_TYPE_STRUCTURE)
endfunction