• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] [Legacy] Add Base Attack

Level 8
Joined
Jan 23, 2015
Messages
121
Well, it should be better anyway than previous version, even if it requires more things. Tested and so it should work flawlessly. Any bug reports or improvement suggestions are welcome!

You use this Bonus as any other Bonus you have; but this one will adjust unit's base attack by bonus' value just like upgrades do (but not through dice system). Algorithm is similar to SetUnitMaxState, but through 'AIaa' item ability.

JASS:
library BaseDamageBonus initializer OnInit requires BonusMod
////////////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@ BaseDamageBonus for BonusMod, v1.1
//@=============================================================================
//@ Credits:
//@-----------------------------------------------------------------------------
//@    Written by:
//@        Trokkin
//@    Basic mod by:
//@        Earth-Fury ( http://www.wc3c.net/showthread.php?t=107940 )
//@    Textmacros for abilities taken from:
//@        Jesus4Lyf's Status. ( https://www.thehelper.net/threads/status.121686/ )
//@=============================================================================
//@ Requirements:
//@-----------------------------------------------------------------------------
//@ This library requires the BonusMod library and any unit indexer
//@ which uses GetUnitUserData().
//@ And if you're not going to change pow2 function, then make powersOf2 & *Count in BonusMod not private.
//@=============================================================================
//@ Readme:
//@-----------------------------------------------------------------------------
//@ This library provides one new bonus type:
//@
//@   - BONUS_BASE_DAMAGE
//@        Raises a unit's attack base damage.
//@
//@ There is no minimum bonus, but unit's base damage won't go lower than 0.
//@ There is no maximum bonus.
//@
//@ If unit have actual damage lower than 0 (shows 0) any +% damage buff will
//@ work as if the unit would have same positive amount as he has negative.
//@ (but that effect still won't add any damage to unit despite how big it is)
//@
//@ There is nothing to configure aside from levels of abilities generated.
//@ This will only affect amount of abilities and items and stabilize perfomance
//@ for numbers <2^levels.
//@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
////////////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ CONFIGURATION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//------------------------------------------------------------------------------
// Note that if you remove this bonus, the abilities and items it had created
// will not be automatically removed. This is also true of reducing the number
// of abilities and items this bonus uses.
//
// After you generate abilities and items, you must close your map and reopen it
// in the editor. You can then disable ability generation until the next time
// you modify this bonus parameters.
//
// Also, the ability 'Iat@', which stands for negative bonus, should be manually
// fixed to -2x the greatest positive ability value because of ObjectMerger bugs.
//
// Can create up to 26 levels. That is more than enough for wc3 engine.
//------------------------------------------------------------------------------
//! runtextmacro BaseDamageBonus_GenerateObjects("10")

private function GetUnitIndex takes unit u returns integer
    return GetUnitUserData(u)
endfunction

function pow2 takes integer p returns integer
    local integer i
    if powersOf2Count < p then
        set i = powersOf2Count
        loop
           exitwhen i > p

           set powersOf2[i] = 2 * powersOf2[i - 1]

           set i = i + 1
        endloop
        set powersOf2Count = p
    endif
    return powersOf2
endfunction

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
////////////////////////////////////////////////////////////////////////////////

globals
    Bonus BONUS_BASE_DAMAGE
    private unit array pui_unit
    private integer array pui_data
endglobals

private struct BaseDamageBonus extends Bonus

    method setBonus takes unit u, integer amount returns integer
        local integer pui = GetUnitIndex(u)
        local boolean sleep
        local integer level


        set level = amount - this.getBonus(u)
        set pui_unit[pui] = u
        set pui_data[pui] = amount
        set amount = level

        set sleep = UnitIsSleeping(u)
        loop
            exitwhen amount >= 0
            call UnitAddAbility(u,'Aat@')
            call IssueImmediateOrderById(u,852259)
            call UnitRemoveAbility(u,'Aat@')
            set amount = amount - pow2(levels)
        endloop

        set level = 'Aat@' + levels
        loop
            if amount >= pow2(level - 'AatA') then
                call UnitAddAbility(u,level)
                call IssueImmediateOrderById(u,852259)
                call UnitRemoveAbility(u,level)
                set amount = amount - pow2(level - 'AatA')
            else
                set level = level - 1
            endif
            exitwhen level == 'Aat@' or amount == 0
        endloop
        call UnitAddSleep(u, sleep)
        return this.getBonus(u)
    endmethod

    method getBonus takes unit u returns integer
        local integer pui = GetUnitIndex(u)
        if pui_unit[pui] != u then
            set pui_unit[pui] = u
            set pui_data[pui] = 0
        endif
        return pui_data[pui]
    endmethod

    method removeBonus takes unit u returns nothing
        call this.setBonus(u, 0)
    endmethod

    method isValidBonus takes unit u, integer value returns boolean
        return true
    endmethod
endstruct

private function OnInit takes nothing returns nothing
    set BONUS_BASE_DAMAGE = BaseDamageBonus.create()
endfunction

//! textmacro BaseDamageBonus_GenerateObjects takes LEVELS
globals
    private constant integer levels = $LEVELS$
endglobals
// ! externalblock extension=lua ObjectMerger $FILENAME$
    //! i myChar={}
    //! i myChar[1]="A"
    //! i myChar[2]="B"
    //! i myChar[3]="C"
    //! i myChar[4]="D"
    //! i myChar[5]="E"
    //! i myChar[6]="F"
    //! i myChar[7]="G"
    //! i myChar[8]="H"
    //! i myChar[9]="I"
    //! i myChar[10]="J"
    //! i myChar[11]="K"
    //! i myChar[12]="L"
    //! i myChar[13]="M"
    //! i myChar[14]="N"
    //! i myChar[15]="O"
    //! i myChar[16]="P"
    //! i myChar[17]="Q"
    //! i myChar[18]="R"
    //! i myChar[19]="S"
    //! i myChar[20]="T"
    //! i myChar[21]="U"
    //! i myChar[22]="V"
    //! i myChar[23]="W"
    //! i myChar[24]="X"
    //! i myChar[25]="Y"
    //! i myChar[26]="Z"
    //! i myBin={}
    //! i myBin[1]=1
    //! i myBin[2]=2
    //! i myBin[3]=4
    //! i myBin[4]=8
    //! i myBin[5]=16
    //! i myBin[6]=32
    //! i myBin[7]=64
    //! i myBin[8]=128
    //! i myBin[9]=256
    //! i myBin[10]=512
    //! i myBin[11]=1024
    //! i myBin[12]=2048
    //! i myBin[13]=4096
    //! i myBin[14]=8192
    //! i myBin[15]=16384
    //! i myBin[16]=32768
    //! i myBin[17]=65536
    //! i myBin[18]=131072
    //! i myBin[19]=262144
    //! i myBin[20]=524288
    //! i myBin[21]=1048576
    //! i myBin[22]=2097152
    //! i myBin[23]=4194304
    //! i myBin[24]=8388608
    //! i myBin[25]=16777216
    //! i myBin[26]=33554432

    //! i setobjecttype("abilities")
    //! i for i=1,$LEVELS$ do
        //! i createobject("AIaa","Aat"..myChar[i])
        //! i makechange(current,"Iaa1",1,myBin[i])
        //! i makechange(current,"acat","")
        //! i makechange(current,"anam","Base Attack Inc")
    //! i end
    //! i createobject("AIaa","Aat@")
    //! i makechange(current,"Istr",1,-myBin[$LEVELS$+1])
    //! i makechange(current,"acat","")
    //! i makechange(current,"anam","Base Attack Dec")
// ! endexternalblock
//! endtextmacro
endlibrary
 
Last edited:
Level 8
Joined
Jan 23, 2015
Messages
121
I assume you didnt test it on a hero with 6 items...
And shouldnt you make the item visible before adding it to the unit?
Huh, yeah, didn't thought about it.
It seems to work properly without hiding. When I didn't disable visibility again after use, the item started to appear near last unit applied to, so anyone can take and use it.
I understand that it is unsafe and buggy way, but is the only way I believe, since I couldn't imagine a way to catch the AIaa order to further use through add ability/use ability. If anyone could help me with it, I'd be happy to get rid of items.
Else I have to make it safe and clear through dozens of kludges, which I really don't want to do.
 
Last edited:

AGD

AGD

Level 16
Joined
Mar 29, 2016
Messages
688
It seems to work properly without hiding
It seems to me that UnitAddItem() also sets the item to be visible. Haven't tested it thoroughly though.

Btw,
JASS:
        local boolean inv = GetUnitAbilityLevel(u, 'Ainv') == 0
        local item i
        if(inv) then // Add inventory if unit has none.
            call UnitAddAbility(u, 'Ainv')
        endif
==>
JASS:
        local boolean inv = UnitAddAbility(u, 'Ainv') // Add inventory if unit has none.

and

JASS:
        if (inv) then // Remove inventory if unit had none.
            call UnitRemoveAbility(u, 'Ainv')
        endif
==>
JASS:
        if (inv and UnitRemoveAbility(u, 'Ainv')) then // Remove inventory if unit had none.
        endif
 
Level 8
Joined
Jan 23, 2015
Messages
121
It seems to me that UnitAddItem() also sets the item to be visible. Haven't tested it thoroughly though.
That's why I kept SetItemVisible(item,false) - it would show up otherwise right to last unit that it has been used to.
Btw,
JASS:
        local boolean inv = GetUnitAbilityLevel(u, 'Ainv') == 0
        local item i
        if(inv) then // Add inventory if unit has none.
            call UnitAddAbility(u, 'Ainv')
        endif
==>
JASS:
        local boolean inv = UnitAddAbility(u, 'Ainv') // Add inventory if unit has none.
Thanks for that, though I'm to implement a possibility to check each type of inventory that user would define - and the boolean will become integer for id of that inv... but until I actually made it, updated.

and
JASS:
        if (inv) then // Remove inventory if unit had none.
            call UnitRemoveAbility(u, 'Ainv')
        endif
==>
JASS:
        if (inv and UnitRemoveAbility(u, 'Ainv')) then // Remove inventory if unit had none.
        endif
Um... beautiful, but since I have nothing else to do with removal, I find empty If-statement a bit confusing.

I was looking through Memory Hack thread last week and discovered my snippet is rather bad in comparison to SetUnitBaseAttack() from that library - still that is straight but unsafe method so if Blizzard are going to fix the bug, we still would have this workaround; but I actually don't have any motivation to update this further because of that great work of Dracol1ch & Co.
 
Can you provide a small demo?
Also you should definitly consider to use numbers of power by 2, what Almia suggested.
The full inventory thing is also a relevant possible issue, what Wietlol mentioned.

Erm, Trokkin, I find it good moving it to The Lab, in the current version. And once it's a stable version you can ping us to move it back. : )
 
Level 8
Joined
Jan 23, 2015
Messages
121
Can you provide a small demo?
Also you should definitly consider to use numbers of power by 2, what Almia suggested.
The full inventory thing is also a relevant possible issue, what Wietlol mentioned.

Erm, Trokkin, I find it good moving it to The Lab, in the current version. And once it's a stable version you can ping us to move it back. : )
Urr... Yeah, I guess so.
Well, I have already done every thing mentioned so the snippet seems to work perfectly, but I did it as a part of a bigger system I'm working on now. Idk when I'll release that, however I don't want to spend time for this little snippet.
And the system is a part of core for my map I'm working on, and while I'm in hurry to create every idea for another core system I have in mind, I don't write them understandable, nice and clear from bugs.
 
Level 8
Joined
Jan 23, 2015
Messages
121
why not? :(
Anyways, it's still something interesting, and in case you have a demo by hand you could just attach it in first post.
I'll debug and actually rewrite them right after every thing is a completed thought came true, and probably even attach a description, though it has least priority in comparison to writing their first raw versions.
Well I used ABA to create a system that manages every single parameter of unit instead of game engine, from max HP to critical chance and modificator (which is a thing used by custom script using also my own version of Bribe's Damage Engine), so I can get raw attack damage for example, or to multiply it by 1.5 and still have a possibility to get unmultiplied value easily.
If a unit in object editor has 0 attack damage (and make sure nothing else would change that like upgrades or hero main attribute), then I can control his attack the most precious way.
 
Level 8
Joined
Jan 23, 2015
Messages
121
...I'm learing how to use ppl's systems instead of rewriting that wheels again. With that fact that I only invented this with my own Bonus, I thought that this better be an addon to famous Earth-Fury BonusMod system.
Updated.
I did not test it in any way because I currently have no access to editor, so it is a scratch from Notepad. After any found compilation errors will be fixed, I guess this snippet can be moved straight into Jass section.
 
Last edited:
Level 8
Joined
Jan 23, 2015
Messages
121
Updated again. Now I tested what I've done and fixed all the bugs I could find. At least for me it worked perfectly.
Now I want someone to say whether it is a complete snippet and approve it, or to say how I should change it to be approved.
 
Level 14
Joined
Jan 16, 2009
Messages
716
Clever idea to use an order instead of items. Though I am not sure it's a good idea as it could mess with an unit's orders.

Also, this system isn't working properly.
- It causes huge fps drop when trying to remove some base damage and the removal itself doesn't work as intended. It just null the damage completely (0-0) and then the system stop working for this unit.
- The code isn't even compiling right (you need to modify Bonus Mod yourself).
- The created decrease ability isn't created properly (it doesn't have the proper value) as you modify "Istr" and not "Iaa1"
- There is a forced evaluate : setBonus should be lower than getBonus.
 
Level 8
Joined
Jan 23, 2015
Messages
121
Clever idea to use an order instead of items. Though I am not sure it's a good idea as it could mess with an unit's orders.

Also, this system isn't working properly.
- It causes huge fps drop when trying to remove some base damage and the removal itself doesn't work as intended. It just null the damage completely (0-0) and then the system stop working for this unit.
- The code isn't even compiling right (you need to modify Bonus Mod yourself).
- The created decrease ability isn't created properly (it doesn't have the proper value) as you modify "Istr" and not "Iaa1"
- There is a forced evaluate : setBonus should be lower than getBonus.
Huh, thanks a lot for review. I felt like nobody is interested in this anymore.
Yep, I was writing some changes from my phone, so I could broke it eventually. Thanks for the iaa1.
Yeah, it does mess with orders, though it seems to be the only way to modify base value of a unit without upgrades or attributes. Btw, when it was items, it still messed orders, I checked that. Someone would want to hook an order system that would restore messed order...
And I was experiencing lags too with this system; I guess that's because of the orders and big amount of add/remove calls. I don't know if it is a good idea, but I can rewrite it so it will be only one spell with much levels.
I will update this eventually, but I switched to wurst and thus I'm not really interested in going back to vJass, still I can't leave it undone.
 
Level 14
Joined
Jan 16, 2009
Messages
716
Well actually I was looking for such a system but couldn't find one using hive or google so I made my own. Then @IcemanBo linked me to this.

One way to diminish fps drop is to preload abilities like BonusMod does.

Btw, when it was items, it still messed orders, I checked that.

Could you elaborate on that ? I am really interested in what situations does the items affect orders.
I am using items in my system and so far I haven't noticed any issue. I haven't really tried it in complex situation though.
 
Level 8
Joined
Jan 23, 2015
Messages
121
Could you elaborate on that ? I am really interested in what situations does the items affect orders.
I am using items in my system and so far I haven't noticed any issue. I haven't really tried it in complex situation though.
Well, I'm not absolute sure, but it seems that "use item" does issue an order. At least it was so in collaboration with a bunch of my very own systems: I did mimic original wc3 attribute mechanics, and set that hero gets exp from dealing damage, then in test ordered him to attack, and whenever base damage was changed, he did stop attacking (target was friendly).
The ultimate way to prove that will be to set up order catching system and call useitem after an order is issued.
Oh and actually, the effect could be different based on what ability you'll use, where AIaa is absolutely sure not an instant ability like berserk.
... sometimes I hate blizzard a bit for lack of natives that control unit's stats.
 
Yep. This shouldn't be used in any modern maps, though in legacy-supporting maps it can still be useful as a way to implement 1.29 feature with some limitations.

Then maybe this should be moved to The Lab instead of Graveyard?

I mean, it might be approve-able since it should work on most old patches, although it might confuse people especially after some time.
 
Top