- Joined
- Jan 21, 2006
- Messages
- 2,552
In that case you'll need a function to determine what bonus should be applied to an enumerated unit.
I just read your post about quitting... I can keep helping you if you like I'm not trying to get you to quit, I'm trying to get you to do something more on your level. If you're just giving up because it's too complicated, then don't, but if it's because you're not learning anything then you should. So far it doesn't sound like you're really understanding what's going on here.
Anyways, once you determine what a unit's aura-bonus will be then you can apply the integer bonus and save it in a hash-table using the unit's
So each time you use
Now the hard part is ensuring that all necessary units are constantly having bonuses applied so that it refreshes the value of the bonus. This part requires the use of a unit-group (preferably a global/static one).
Going through this, it won't work. You're creating the unit-group in the
Anyways, using this same group you can do what I was talking about before. Just look.
Now, it's not that complicated.
The result is something like this. I just typed it up quick in the World Editor. It should compile fine (not sure if it functions 100% though). I figured I would post it since in the code above I do not have all the right parameters, such as the second boolean parameter in
JASS:
function GetUnitAuraBonus takes unit onSubject returns integer
// Returns the integer value of the bonus that should be
// applied to the "onSubject" unit using the hero array.
local integer i = 0
local integer m = 0
loop
exitwhen i == HeroWithAuraCount
if IsUnitInRange(HeroWithAura[i], onSubject, LONG_RANGE) then
// In order to optimize things a bit, the following code should
// only be executed if the enumerated unit is within range of
// a hero's aura. If it isn't, then immediately progress to
// the next without determining the bonus.
if IsUnitInRange(HeroWithAura[i], onSubject, CLOSE_RANGE) then
if CLOSE_RANGE_BONUS > m then
set m = CLOSE_RANGE_BONUS
endif
elseif IsUnitInRange(HeroWithAura[i], onSubject, MEDIUM_RANGE) then
if MEDIUM_RANGE_BONUS > m then
set m = MEDIUM_RANGE_BONUS
endif
else
if LONG_RANGE_BONUS > m then
set m = LONG_RANGE_BONUS
endif
endif
endif
set i = i + 1
endloop
return m
endfunction
I just read your post about quitting... I can keep helping you if you like I'm not trying to get you to quit, I'm trying to get you to do something more on your level. If you're just giving up because it's too complicated, then don't, but if it's because you're not learning anything then you should. So far it doesn't sound like you're really understanding what's going on here.
Anyways, once you determine what a unit's aura-bonus will be then you can apply the integer bonus and save it in a hash-table using the unit's
GetHandleId()
value. From here you'll have to add the unit to a group that is iterated through on a periodic interval, that removes the previously attached buff and applies a new one.
JASS:
globals
hashtable storeTable = InitHashtable()
endglobals
function ApplyBonus takes unit whichUnit, integer bonus returns nothing
if HaveSavedInteger(storeTable, GetHandleId(whichUnit), 1) then
call SetHeroStr(whichUnit, GetHeroStr(whichUnit)-LoadInteger(storeTable, GetHandleId(whichUnit), 1))
if bonus == 0 then
call RemoveSavedInteger(storeTable, GetHandleId(whichUnit), 1)
else
call SaveInteger(storeTable, GetHandleId(whichUnit), bonus)
endif
else
if bonus != 0 then
call SaveInteger(storeTable, GetHandleId(whichUnit), 1, bonus)
endif
endif
call SetHeroStr(whichUnit, GetHeroStr(whichUnit) + bonus)
endfunction
So each time you use
ApplyBonus
in this case it will check to see if the unit is under the effects of a bonus already. If it is not under the effects of a bonus, then it will assign it to a hash-table value and then increase it's strength. If it is already under the effects of the aura, then it will need to refer to the assigned hash-table value and remove that saved amount of strength. Once this is done it will be able to apply the new buff. By the way, notice that if the unit does not have any bonuses and a 0 bonus is applied it won't do anything.Now the hard part is ensuring that all necessary units are constantly having bonuses applied so that it refreshes the value of the bonus. This part requires the use of a unit-group (preferably a global/static one).
JASS:
private function doLoop takes nothing returns nothing
set tempGrp = CreateGroup()
call GroupEnumUnitsInRect(tempGrp, GetWorldBounds(), Filter(function hasBuff))
// Enumerates all units after the conditions
call ForGroup(tempGrp, function Data.ForGroupFuncs)
// Picks all units in the Group, and does these actions.
endfunction
Going through this, it won't work. You're creating the unit-group in the
doLoop
iteration, which is not what I showed you to do. In my example I was only creating it once, when it was declared. The way you have it set up it will leak a unit-group each timer iteration, which is very bad, so avoid that. All you have to do is move set tempGrp = CreateGroup()
to the global declarations or to an initialization function/method.Anyways, using this same group you can do what I was talking about before. Just look.
JASS:
private function doLoopPre takes nothing returns nothing
call ApplyBonus(GetEnumUnit(), GetUnitAuraBonus(GetEnumUnit()))
endfunction
private function doLoop takes nothing returns nothing
call ForGroup(tempGrp, function doLoopPre)
call GroupEnumUnitsInRect(tempGrp, GetWorldBounds(), Filter(function hasBuff))
call ForGroup(tempGrp, function Data.ForGroupFuncs)
// The "tempGrp" unit-group will not be empty, it will have every unit in the
// map with the aura buff. This is useful because we can use this group upon
// the next timer iteration to apply the bonus function.
endfunction
Now, it's not that complicated.
The result is something like this. I just typed it up quick in the World Editor. It should compile fine (not sure if it functions 100% though). I figured I would post it since in the code above I do not have all the right parameters, such as the second boolean parameter in
GetHeroStr
.
JASS:
scope StrengthAura initializer init
globals
public constant integer AURA_ABIL_ID = 'A000'
public constant integer AURA_BUFF_ID = 'B000'
public constant real LONG_RANGE = 600
public constant integer LONG_RANGE_BONUS = 3
public constant real MEDIUM_RANGE = 400
public constant integer MEDIUM_RANGE_BONUS = 6
public constant real CLOSE_RANGE = 200
public constant integer CLOSE_RANGE_BONUS = 9
private hashtable table = InitHashtable()
private unit array heroes
private integer count = 0
private group tmpGrp = CreateGroup()
endglobals
private function ApplyBonus takes unit u, integer bonus returns nothing
if HaveSavedInteger(table, GetHandleId(u), 1) then
call SetHeroStr(u, GetHeroStr(u, true)-LoadInteger(table, GetHandleId(u), 1), false)
if bonus == 0 then
call RemoveSavedInteger(table, GetHandleId(u), 1)
else
call SaveInteger(table, GetHandleId(u), 1, bonus)
endif
else
if bonus != 0 then
call SaveInteger(table, GetHandleId(u), 1, bonus)
endif
endif
call SetHeroStr(u, GetHeroStr(u, true)+bonus, false)
endfunction
private function GetUnitAuraBonus takes unit u returns integer
local integer i = 0
local integer m = 0
loop
exitwhen i == count
if IsUnitInRange(u, heroes[i], LONG_RANGE) then
if IsUnitInRange(u, heroes[i], CLOSE_RANGE) then
if CLOSE_RANGE_BONUS > m then
set m = CLOSE_RANGE_BONUS
endif
elseif IsUnitInRange(u, heroes[i], MEDIUM_RANGE) then
if MEDIUM_RANGE_BONUS > m then
set m = MEDIUM_RANGE_BONUS
endif
else
if LONG_RANGE_BONUS > m then
set m = LONG_RANGE_BONUS
endif
endif
endif
set i = i + 1
endloop
return 0
endfunction
public function hasBuff takes nothing returns boolean
return GetUnitAbilityLevel(GetFilterUnit(), AURA_BUFF_ID) > 0
endfunction
public function loopFuncEnum takes nothing returns nothing
call ApplyBonus(GetEnumUnit(), GetUnitAuraBonus(GetEnumUnit()))
endfunction
public function loopFunc takes nothing returns nothing
call ForGroup(tmpGrp, function loopFuncEnum)
call GroupEnumUnitsInRect(tmpGrp, GetWorldBounds(), Filter(function hasBuff))
call ForGroup(tmpGrp, function loopFuncEnum)
endfunction
public function compare takes nothing returns boolean
return GetLearnedSkill() == AURA_ABIL_ID and GetLearnedSkillLevel() == 1
endfunction
public function onLearn takes nothing returns nothing
set heroes[count] = GetTriggerUnit()
set count = count + 1
endfunction
public function init takes nothing returns nothing
local trigger learn = CreateTrigger()
local integer i = 0
call TimerStart(CreateTimer(), 0.5, true, function loopFunc)
loop
exitwhen i == 16
call TriggerRegisterPlayerUnitEvent(learn, Player(i), EVENT_PLAYER_HERO_SKILL, null)
set i = i + 1
endloop
call TriggerAddCondition(learn, Filter(function compare))
call TriggerAddAction(learn, function onLearn)
endfunction
endscope
Last edited: