• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Is this efficient?

Status
Not open for further replies.
Level 20
Joined
Jul 14, 2011
Messages
3,213
HI! I found someone else problem really interesing while wandering around the Hive forums.

What this does (so far) is modify the Attack Speed of the unit between 0 and 504 with only 6 abilities with 5 levels each. It works the same way for almost any other stuff (damage, evasion, critical, armor, etc.)

I know there are mods that does something like this, but not this way. I'd like to know if this is good enough as to share with others.

I found that in the worst case, (where the modification is the max number: 504) it only does 24 iterations (for each modified stat with a 504 value). Doesn't seem that much to me, since picking/dropping items isn't something like a 0.03 loop.

EDIT: I improved the code. Now the data isn't stored in a Hashtable. The item data is stored in an array (SpartBonus_ItemAS, SpartBonus_ItemMS, SpartBonus_ItemDmg, and so on). The only thing stored in the Hashtable is the item index which is retrieved to use the arrays instead (a lot faster to save/load so many data))


JASS:
globals
    hashtable = SpartBonus_Hash = InitHashtable()
    integer array SpartBonus_Speed
    //integer array SpartBonus_Evasion Yet to be implemented
    //integer array SpartBonus_Critical Yet to be implemented
    //integer array SpartBonus_Armor Yet to be implemented
    //integer array SpartBonus_Damage Yet to be implemented
    // The other stuff...
endglobals

// Adds the abilities to the desired unit (Probably just heroes when enters the map).
function SpartBonus_SpeedUnit takes unit u returns nothing
    local integer looper = 0
    loop
        exitwhen looper == 6
        call UnitAddAbility(u, SpartBonus_Speed[looper])
        set looper = looper+1
    endloop
endfunction

// Just for testing with a Paladin in a blank map.
function SomeAction takes nothing returns nothing    
    call SpartBonus_SpeedUnit(gg_unit_Hpal_0005)
endfunction

// The Item Data. Just speed so far
function SpartBonus_ItemInit takes nothing returns nothing
    call SaveInteger(SpartBonus_Hash, 'bspd', 0, 50) // 50 speed provided by Boots of Speed
    call SaveInteger(SpartBonus_Hash, 'cnob', 0, 150) // 150 speed provided by Circlet of Noblity
endfunction


// The Bonus Abilities. Speed is the only one implemented so far
function SpartBonus_AbilityInit takes nothing returns nothing
    // Speed Bonus
    set SpartBonus_Speed[0] = 'A001' // Your 2% Bonus AttackSpeed Ability
    set SpartBonus_Speed[1] = 'A002' // Your 4% Bonus AttackSpeed Ability
    set SpartBonus_Speed[2] = 'A003' // Your 8% Bonus AttackSpeed Ability
    set SpartBonus_Speed[3] = 'A000' // Your 16% Bonus AttackSpeed Ability
    set SpartBonus_Speed[4] = 'A004' // Your 32% Bonus AttackSpeed Ability
    set SpartBonus_Speed[5] = 'A005' // Your 64% Bonus AttackSpeed Ability
endfunction

// This allows setting the desired speed (with -1 or +1 difference)
function Spart_SetSpeed takes unit u, integer speed returns nothing
    local integer i = 0
    local integer lvl
    local integer a = 128
    local integer looper = 5
    local integer id = GetHandleId(u)
    set speed = speed + LoadInteger(SpartBonus_Hash, id, 0)
    
    if speed > 504 then
        set speed = 504
    elseif speed < 0 then
        set speed = 0
    endif
    
    set i = speed
    
    loop                                                                        // Loop through 6 array index
        exitwhen looper < 0                                                     // Loop limit
        set a = a/2                                                             // a/2 = the max value divisor
        if speed >=a then                                                       // Cond. If input value corresponds to divisor group 
            set lvl = 2                                                         // Level reset 
            loop                                                                // Loop throgh the distance and ability level
            exitwhen lvl == 6 or speed < a                                      // Loop limit
                set lvl = lvl+1                                                 // Level increase
                set speed = speed-a                                             // Speed reduce check
                if lvl == 6 or speed < a then                                   // Cond. Determines ability level to be set
                    call SetUnitAbilityLevel(u, SpartBonus_Speed[looper], lvl)  // Set ability level
                endif                                                           // End Cond.
            endloop                                                             // End lvl/distance loop
        else                                                                    // Nulls ability effect if new imput value is lower than current.
            call SetUnitAbilityLevel(u, SpartBonus_Speed[looper], 1)            // ^^ What says above ^^
        endif                                                                   // End Divisor Group Cond.
        set looper = looper-1                                                   // Looper reduce
    endloop                                                                     // End loop through 6 array index.
    call SaveInteger(SpartBonus_Hash, id, 0, i)                                 // Stores the speed
    
    /* The Hash allows you to pick a Sword that increases speed by 20% by just
    calling this function (Spart_SetSpeed, u, 20) and then, picking a glove that
    incrases speed by 15% more (Spart_SetSpeed, u, 15). Both will sum */
endfunction
//===========================================================================
function InitTrig_SpartBonus_Data takes nothing returns nothing
    set gg_trg_SpartBonus_Data = CreateTrigger(  )
    call SpartBonus_AbilityInit()
    call SpartBonus_ItemInit()
    call SomeAction()
endfunction



JASS:
function SpartBonus_Item_Acquire_Actions takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local integer id
    local integer speed
    
    if IsUnitType(u, UNIT_TYPE_HERO) == true then
        set id = GetItemTypeId(GetManipulatedItem())
        set speed = LoadInteger(SpartBonus_Hash, id, 0)
        call Spart_SetSpeed(u, speed)
    endif
    set u = null
    return false
endfunction

//===========================================================================
function InitTrig_SpartBonus_Item_Acquire takes nothing returns nothing
    set gg_trg_SpartBonus_Item_Acquire = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_SpartBonus_Item_Acquire, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( gg_trg_SpartBonus_Item_Acquire, function SpartBonus_Item_Acquire_Actions)
endfunction
JASS:
function SpartBonus_Item_Loose_Actions takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local integer id
    local integer speed
    
    if IsUnitType(u, UNIT_TYPE_HERO) == true then
        set id = GetItemTypeId(GetManipulatedItem())
        set speed = LoadInteger(SpartBonus_Hash, id, 0) * -1
        call Spart_SetSpeed(u, speed)
    endif
    set u = null
    return false
endfunction

//===========================================================================
function InitTrig_SpartBonus_Item_Loose takes nothing returns nothing
    set gg_trg_SpartBonus_Item_Loose = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_SpartBonus_Item_Loose, EVENT_PLAYER_UNIT_DROP_ITEM )
    call TriggerAddAction( gg_trg_SpartBonus_Item_Loose, function SpartBonus_Item_Loose_Actions)
endfunction
 

Attachments

  • SpartBonus.w3x
    20.1 KB · Views: 40
Last edited:
Level 20
Joined
Jul 6, 2009
Messages
1,885
It would add 190 abilities to a unit if you used max bonus of each stat.
That system generates ~190 abilities because it uses 11 stats and up to 130k bonus.

I guess it depends on whether you find 6 abilities with 5 levels each better than 9 abilities with 1 level each for applying a 504 bonus.

You'd have fewer iterations using 9 abilities to apply a 504 bonus, iterations would equal log2(x)+1 where x is bonus, 9 in this case and each iteration would have a few lines only.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
You're right :/ I'm having some flaws around... anyway:

Using 9 abilities would require adding/removing abilities to reach the desired value. I just change the ability level. I'm not sure which is "heavier" to run.

In the worst case you would have to add/remove 9 abilities after the iterations to determine the correct ability combination to add/remove. I'm doing almost the same.

That system requires LUA Script macro (Disabled on Win 64). There should be a system that works on any OS (which i'm trying to)

That system is mostly based on Hashtable, which is slower than arrays, that's why i'm trying to work with arrays.

How can I improve this?
 
Level 20
Joined
Jul 6, 2009
Messages
1,885
I'm not sure if abilities with levels is really easier, you have abilities*levels work here, which will end up even more time consuming as that number will always be greater than using abilities alone.
Wouldn't your way require Lua as well for many stats and large numbers?
 
You don't necessarily need Lua. You can also just use the object merger tool that is part of grim extensions. You just export the objects from the test map, then you open your map and go to -> Extensions and choose one of the options for importing the objects.

There are 3 options that determine how it handles collisions:
  • m merge changes for objects with the same rawcode, this is the default (Extensions\Merge Object Editor Data)
  • r replace existing objects with the imported objects in case of equal rawcodes (Extensions\Replace Object Editor Data)
  • i a clean import, that generates new ids for imported objects if their id is already used (Extensions\Import Object Editor Data)
(the above info is taken from GrimexManual, by PitzerMike)

If you take advantage of those features then implementation is relatively easy. It is much better than the WE import function which replaces the current w3o with the imported one. For more information, go to your JNGP folder, and look at grimext/GrimexManual.html. There is a lot of nice info.
 
Status
Not open for further replies.
Top