[JASS] Undeclared function error

Level 3
Joined
Apr 7, 2012
Messages
29
I tried to initiate the Jass but it says the function was undeclared. How do I format this properly again?

JASS:
library RagingFireAura requires CooldownReduction, CooldownReductionUtils

globals
    real array RF_COOLDOWN_REDUCTION // Store cooldown reduction values for each level
    real DURATION = 1.00 // The effect duration, reapplied every second
endglobals

// Declare the function at the top so GUI can call it
public function RagingFireAura_Init takes nothing returns nothing

// Initialize cooldown reduction values for each aura level
private function InitRagingFireCooldownReduction takes nothing returns nothing
    set RF_COOLDOWN_REDUCTION[1] = 0.06 // 6% for level 1
    set RF_COOLDOWN_REDUCTION[2] = 0.12 // 12% for level 2
    set RF_COOLDOWN_REDUCTION[3] = 0.18 // 18% for level 3
    set RF_COOLDOWN_REDUCTION[4] = 0.24 // 24% for level 4
endfunction

// Apply cooldown reduction to heroes within 1200 AoE
private function ApplyRagingFireAura takes unit caster returns nothing
    local integer auraLevel = GetUnitAbilityLevel(caster, 'A001') // Replace 'A001' with your Raging Fire ability raw ID
    local group allies = CreateGroup()
    local unit ally

    if auraLevel > 0 and GetWidgetLife(caster) > 0.405 then
        // Pick all units in range of the hero with the aura
        call GroupEnumUnitsInRange(allies, GetUnitX(caster), GetUnitY(caster), 1200.00, null)
        loop
            set ally = FirstOfGroup(allies)
            exitwhen ally == null

            if IsUnitAlly(ally, GetOwningPlayer(caster)) and IsUnitType(ally, UNIT_TYPE_HERO) and GetWidgetLife(ally) > 0.405 then
                // Apply cooldown reduction for 1 second (reapplies every second)
                call UnitAddCooldownReductionTimed(ally, RF_COOLDOWN_REDUCTION[auraLevel], DURATION)
            else
                // Remove cooldown reduction if unit is dead or out of range
                call UnitRemoveCooldownReduction(ally, RF_COOLDOWN_REDUCTION[auraLevel])
            endif

            call GroupRemoveUnit(allies, ally)
        endloop
    endif

    call DestroyGroup(allies)
endfunction

// Periodic trigger to check and apply aura effect
private function PeriodicAura takes nothing returns nothing
    local group heroes = CreateGroup()
    local unit hero

    // Check all heroes in the map
    call GroupEnumUnitsInRect(heroes, GetPlayableMapRect(), null)
    loop
        set hero = FirstOfGroup(heroes)
        exitwhen hero == null

        if GetUnitAbilityLevel(hero, 'A001') > 0 and GetWidgetLife(hero) > 0.405 then
            // Apply aura effect if the hero has learned the ability and is alive
            call ApplyRagingFireAura(hero)
        else
            // Remove cooldown reduction if the hero dies or the ability is unlearned
            call UnitRemoveCooldownReduction(hero, RF_COOLDOWN_REDUCTION[GetUnitAbilityLevel(hero, 'A001')])
        endif

        call GroupRemoveUnit(heroes, hero)
    endloop

    call DestroyGroup(heroes)
endfunction

// Function implementation
public function RagingFireAura_Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call InitRagingFireCooldownReduction() // Initialize cooldown values
    call TriggerRegisterTimerEvent(t, 1.00, true) // Runs every second
    call TriggerAddAction(t, function PeriodicAura)
endfunction

endlibrary

And here's my simple initialization trigger
  • Events
    • Map initialization
  • Conditions
  • Actions
    • Custom script: call RagingFireAura_Init()
 
The issue is that you added the prefix already yourself, so the compiled version of the function ends up being "RagingFireAura_RagingFireAura_Init":
JASS:
// because this is "public" and nested within the RagingFireAura scope,
// jasshelper will internally add the prefix "RagingFireAura_", so the final name
// will be "RagingFireAura_RagingFireAura_Init"
public function RagingFireAura_Init takes nothing returns nothing

// ... instead, change it to this ...

public function Init takes nothing returns nothing

If you change it to just "Init", then it will get compiled into "RagingFireAura_Init" and your GUI trigger should work just fine!
 
Level 44
Joined
Feb 27, 2007
Messages
5,474
vJASS does have the keyword keyword (yes I wrote that correctly) for things similar to this, but it's not applicable here. You simply don't need to do anything at all here. Since the function you want to call on init is defined in a library, JASSHelper should place that code above the map init function so that it can be called there without issue. The error is only because you gave the wrong name of the function as Purge said.

Really, the way you should do this is to actually define the Init function as an initializer of the library so that it is run on map init automatically and you don't need the GUI trigger at all.
JASS:
library RagingFireAura initializer Init requires CooldownReduction, CooldownReductionUtils
//note I used Init here, since as Purge showed the public keyword already gives it the RagingFireAura_ prefix outside of this library scope,
//but within the scope you can use its short 'local' name.
 
Level 3
Joined
Apr 7, 2012
Messages
29
The issue is that you added the prefix already yourself, so the compiled version of the function ends up being "RagingFireAura_RagingFireAura_Init":
JASS:
// because this is "public" and nested within the RagingFireAura scope,
// jasshelper will internally add the prefix "RagingFireAura_", so the final name
// will be "RagingFireAura_RagingFireAura_Init"
public function RagingFireAura_Init takes nothing returns nothing

// ... instead, change it to this ...

public function Init takes nothing returns nothing

If you change it to just "Init", then it will get compiled into "RagingFireAura_Init" and your GUI trigger should work just fine!
vJASS does have the keyword keyword (yes I wrote that correctly) for things similar to this, but it's not applicable here. You simply don't need to do anything at all here. Since the function you want to call on init is defined in a library, JASSHelper should place that code above the map init function so that it can be called there without issue. The error is only because you gave the wrong name of the function as Purge said.

Really, the way you should do this is to actually define the Init function as an initializer of the library so that it is run on map init automatically and you don't need the GUI trigger at all.
JASS:
library RagingFireAura initializer Init requires CooldownReduction, CooldownReductionUtils
//note I used Init here, since as Purge showed the public keyword already gives it the RagingFireAura_ prefix outside of this library scope,
//but within the scope you can use its short 'local' name.
Thanks, both of your methods work just fine! I really appreciate that.
 
Top