- Joined
- Jul 15, 2023
- Messages
- 4
I came across this specific thread
An issue 6 years ago. I wanted to clarify for those looking for help since that forum is closed. Using a Dummy Unit is extremely versatile when interacting with requirements inside the game. If you are smart enough you can use it for all tech tree requirements fake tier upgrades and even hero level ability requirements.
by SerenityInFireHey all, so I've run into a little problem with my map. Instead of the townhall upgrading to keep upgrading to a castle and whatnot to advance to the next tech level in my map, I have a research that advances the tech level. It goes Age of Enlightenment, Age of Magic and Age of Wonders. Now that that's out of the way, my problem is this: The armor and damage upgrades for my units also have multiple levels, which each level requiring an advancement to the next age. The problem is, it works for the level that requires Age of Enlightenment, but I'm able to advance to the next levels of my armor and damage upgrades without advancing to the Age of Magic and the Age of Wonders. I've added values to the level requirements for each level of my armor and damage upgrades, but it doesn't seem to work. Is it bugged, or am I missing something? It works fine for a tech that's only one level that requires the Age of Wonders or something, but it just doesn't work with these techs that have multiple levels.
An issue 6 years ago. I wanted to clarify for those looking for help since that forum is closed. Using a Dummy Unit is extremely versatile when interacting with requirements inside the game. If you are smart enough you can use it for all tech tree requirements fake tier upgrades and even hero level ability requirements.
JASS:
library AbilityLevelRequirements initializer Init requires Table, BeastmasterAura
globals
private constant integer UNLOCK_COUNT = 3
private constant integer array UNLOCK_HERO_ID
private constant integer array UNLOCK_LEVEL
private constant integer array UNLOCK_DUMMY_ABIL
private constant integer array UNLOCK_REAL_ABIL
// Global array for accessing the dummy unlock unit: indexed by player id
unit array StampedeDummy
private constant integer STAMPEDE_UNIT_ID = 'e00P' // Dummy unit rawcode for Stampede unlock
endglobals
private function SetupRequirements takes nothing returns nothing
set UNLOCK_HERO_ID[0] = 'N015'
set UNLOCK_LEVEL[0] = 5
set UNLOCK_DUMMY_ABIL[0] = 'A06N'
set UNLOCK_REAL_ABIL[0] = 'A06L'
set UNLOCK_HERO_ID[1] = 'N015'
set UNLOCK_LEVEL[1] = 2
set UNLOCK_DUMMY_ABIL[1] = 'A06O'
set UNLOCK_REAL_ABIL[1] = 'A063'
set UNLOCK_HERO_ID[2] = 'N015'
set UNLOCK_LEVEL[2] = 6
set UNLOCK_DUMMY_ABIL[2] = 'A06R'
set UNLOCK_REAL_ABIL[2] = 'A06Q'
endfunction
// === Dummy Creation Helper ===
function StampedeDummy_CreateForPlayer takes player p returns nothing
local integer pid = GetPlayerId(p)
if StampedeDummy[pid] == null or not UnitAlive(StampedeDummy[pid]) then
set StampedeDummy[pid] = CreateUnit(p, STAMPEDE_UNIT_ID, 0., 0., 0.)
call ShowUnit(StampedeDummy[pid], false)
call SetUnitInvulnerable(StampedeDummy[pid], true)
call UnitAddAbility(StampedeDummy[pid], 'Aloc') // Locust to make untargetable
endif
endfunction
function AbilityUnlock_CheckAllForUnit takes unit u returns nothing
local integer i = 0
local integer utype = GetUnitTypeId(u)
local integer level
loop
exitwhen i >= UNLOCK_COUNT
if utype == UNLOCK_HERO_ID[i] then
set level = GetHeroLevel(u)
if level >= UNLOCK_LEVEL[i] then
// Remove dummy if present
if GetUnitAbilityLevel(u, UNLOCK_DUMMY_ABIL[i]) > 0 then
call UnitRemoveAbility(u, UNLOCK_DUMMY_ABIL[i])
endif
// Add real ability if not present
if GetUnitAbilityLevel(u, UNLOCK_REAL_ABIL[i]) == 0 then
call UnitAddAbility(u, UNLOCK_REAL_ABIL[i])
if UNLOCK_REAL_ABIL[i] == 'A06L' then
call BeastmasterAura_RegisterRexxar(u)
endif
endif
else
// If below unlock level, ensure dummy present and real gone
if GetUnitAbilityLevel(u, UNLOCK_REAL_ABIL[i]) > 0 then
call UnitRemoveAbility(u, UNLOCK_REAL_ABIL[i])
endif
if GetUnitAbilityLevel(u, UNLOCK_DUMMY_ABIL[i]) == 0 then
call UnitAddAbility(u, UNLOCK_DUMMY_ABIL[i])
endif
endif
endif
set i = i + 1
endloop
endfunction
private function OnHeroLevel takes nothing returns nothing
call AbilityUnlock_CheckAllForUnit(GetTriggerUnit())
endfunction
private function OnUnitEnter takes nothing returns nothing
local unit u = GetEnteringUnit()
if IsUnitType(u, UNIT_TYPE_HERO) then
call AbilityUnlock_CheckAllForUnit(u)
if GetUnitTypeId(u) == 'N015' then // Beastmaster/Rexxar
call StampedeDummy_CreateForPlayer(GetOwningPlayer(u))
endif
endif
set u = null
endfunction
private function OnStart takes nothing returns nothing
local integer i = 0
local group g
local unit u
loop
exitwhen i >= bj_MAX_PLAYER_SLOTS
set g = CreateGroup()
call GroupEnumUnitsOfPlayer(g, Player(i), null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
if IsUnitType(u, UNIT_TYPE_HERO) then
call AbilityUnlock_CheckAllForUnit(u)
if GetUnitTypeId(u) == 'N015' then
call StampedeDummy_CreateForPlayer(Player(i))
endif
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set i = i + 1
endloop
endfunction
private function Init takes nothing returns nothing
local trigger trgLevel = CreateTrigger()
local trigger trgEnter = CreateTrigger()
local trigger trgStart = CreateTrigger()
call SetupRequirements()
call TriggerRegisterAnyUnitEventBJ(trgLevel, EVENT_PLAYER_HERO_LEVEL)
call TriggerAddAction(trgLevel, function OnHeroLevel)
call TriggerRegisterEnterRectSimple(trgEnter, GetPlayableMapRect())
call TriggerAddAction(trgEnter, function OnUnitEnter)
call TriggerRegisterTimerEventSingle(trgStart, 0.01)
call TriggerAddAction(trgStart, function OnStart)
endfunction
endlibrary