• 🏆 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!

Stacking indexing systems

Status
Not open for further replies.
Yeah, the two will collide with one another. You can always write a conversion wrapper to make it easier to port AutoIndex systems to use Bribe's indexer:
JASS:
library AutoIndex
    function GetUnitId takes unit u returns integer
        return GetUnitUserData(u)
    endfunction

    function IsUnitIndexed takes unit u returns boolean
        return GetUnitUserData(u) != 0
    endfunction
  
    function RegisterDeindex takes code c returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 2.00)
        call TriggerAddCondition(t, Condition(c))
    endfunction
endlibrary

The only one that doesn't work so seamlessly is OnUnitDeindexed(). In the case of BonusMod, you would do something like this:
JASS:
// OLD: private function OnLeaveMap takes unit u returns nothing
private function OnLeaveMap takes nothing returns nothing
    local unit u = udg_UDexUnits[udg_UDex]
    if BonusValues[u] != 0 then
        call BonusValues[u].destroy()
    endif
    set u = null
endfunction

private function OnInit takes nothing returns nothing
    // OLD: call OnUnitDeindexed(OnLeaveMap)
    call RegisterDeindex(function OnLeaveMap)
    
    set BONUS_LIFE = MaxStateBonus_life.create()
    set BONUS_MANA = MaxStateBonus_mana.create()
endfunction

Not the best solution but w/e. It should work. For systems that use the struct part of AutoIndex, you'll have to make more changes. But for BonusMod's extension, this should be fine.
 
Level 7
Joined
Nov 19, 2015
Messages
283
Sorry, I only just learnt Jass and I have no idea what conversion wrapper port .... means. Which indexing system is the better of the two or is there a better one out there.

The solution looks messy and I'm not sure I want to do that unless its a last resort. What would you say is the best solution. I'm thinking of recreating some of the easier to make systems. I assume BonusMods just adds itemstatbonus to units. Which doesn't sound too hard to make (hopefully). I use bribe's indexing thing for DDS and isUnitMoving. I don't think I understand enough to remake those.
 
I can't really say which is better. Most systems that require indexing just require units to have a unique index. Others are more demanding. But unless you really need to use a bunch of systems that use AutoIndex, I would recommend just changing BonusMod to use Bribe's GUI Indexer--especially if you're already comfortable with his indexing system.

If you are looking for alternatives for BonusMod, you can use something like DoomLord's Custom Stat System:
http://www.hiveworkshop.com/forums/spells-569/jass-custom-stat-system-css-v1-5g-229885/

If you'd like, you can use this Bonus Max Life/Mana instead--I modified it to use Bribe's indexer directly. I can't guarantee that it works or even compiles, but it is an option:
JASS:
library UnitMaxStateBonuses initializer OnInit requires BonusMod, UnitMaxState
////////////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@ UnitMaxStateBonuses for BonusMod
//@=============================================================================
//@ Credits:
//@-----------------------------------------------------------------------------
//@    Written by:
//@        Earth-Fury
//@=============================================================================
//@ Requirements:
//@-----------------------------------------------------------------------------
//@ This library requires the BonusMod library, the UnitMaxState library by
//@ Earth-Fury, and the AutoIndex library by grim001.
//@
//@=============================================================================
//@ Readme:
//@-----------------------------------------------------------------------------
//@ This library provides two new bonus types:
//@
//@   - BONUS_LIFE
//@   - BONUS_MANA
//@ 
//@ These bonuses, of course, raise a unit's maximum life and mana.
//@ 
//@ Note that if you simply wish to permanently increase or decrease the maximum
//@ life or mana of a unit, you are likely best off using UnitMaxState directly.
//@
//@ The minimum life and mana bonuses are 1 more than -(unit's max state).
//@ That is to say, these bonuses can not fully remove a unit's life or mana.
//@
//@ There is no maximum bonus.
//@
//@ There is nothing to configure.
//@ 
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
////////////////////////////////////////////////////////////////////////////////

globals
    Bonus BONUS_LIFE
    Bonus BONUS_MANA
endglobals

private function ErrorMsg takes string func, string s returns nothing
    call BJDebugMsg("|cffFF0000UnitMaxStateBonus Error|r|cffFFFF00:|r |cff8080FF" + func + "|r|cffFFFF00:|r " + s)
endfunction

private struct BonusValues
    public integer mana = 0
    public integer life = 0
    
    public unit owner
    
    private static thistype array owners
    
    private static method create takes unit u returns thistype
        local thistype this = thistype.allocate()
        
        set this.owner = u
        
        set thistype.owners[GetUnitUserData(u)] = this
        
        return this
    endmethod
    
    private method onDestroy takes nothing returns nothing
        set thistype.owners[GetUnitUserData(this.owner)] = thistype(0)
        set this.owner = null
    endmethod
    
    public static method getInstance takes unit u returns thistype
        if thistype.owners[GetUnitUserData(u)] == 0 then
            return thistype.create(u)
        else
            return thistype.owners[GetUnitUserData(u)]
        endif
    endmethod
    
    public static method operator[] takes unit u returns thistype
        return thistype.owners[GetUnitUserData(u)]
    endmethod
    
    public static method operator[]= takes unit u, thistype i returns nothing
        set thistype.owners[GetUnitUserData(u)] = i
    endmethod
endstruct

//! textmacro UnitMaxStateBonus_DefineBonus takes NAME, STATE, MIN
private struct MaxStateBonus_$NAME$ extends Bonus
    integer minBonus = -2147483648
    integer maxBonus =  2147483647
    
    method setBonus takes unit u, integer amount returns integer
        local BonusValues values
        local integer actual
        local integer new
        local real factor
        
        if GetUnitUserData(u) == 0 then
            debug call ErrorMsg("MaxStateBonus_$NAME$.setBonus()", "Unit that is not indexed by AutoIndex given")
            return 0
        endif
        
        set values = BonusValues.getInstance(u)
        
        set actual = R2I(GetUnitState(u, UNIT_STATE_MAX_$STATE$)) - values.$NAME$
        set new = actual + amount
        
        set factor = GetUnitState(u, UNIT_STATE_$STATE$) / GetUnitState(u, UNIT_STATE_MAX_$STATE$)
        
        if new < $MIN$ then
            if actual < $MIN$ then
                set values.$NAME$ = 0
            else
                set values.$NAME$ = -actual + $MIN$
            endif
            
            call SetUnitState(u, UNIT_STATE_$STATE$, $MIN$)
            call SetUnitMaxState(u, UNIT_STATE_MAX_$STATE$, $MIN$)
            return values.$NAME$
        else
            set values.$NAME$ = amount
            
            call SetUnitMaxState(u, UNIT_STATE_MAX_$STATE$, new)
            call SetUnitState(u, UNIT_STATE_$STATE$, new * factor)
            
            return values.$NAME$
        endif
    endmethod
    
    method getBonus takes unit u returns integer
        local BonusValues values
        local integer actual
        local integer new
        local real factor
        
        if GetUnitUserData(u) == 0 then
            debug call ErrorMsg("MaxStateBonus_$NAME$.getBonus()", "Unit that is not indexed by AutoIndex given")
            return 0
        endif
        
        set values = BonusValues[u]
        
        if values == 0 then
            return 0
        endif
        
        set values.$NAME$ = R2I(GetUnitState(u, UNIT_STATE_MAX_$STATE$)) - (R2I(GetUnitState(u, UNIT_STATE_MAX_$STATE$)) - values.$NAME$)
        
        return values.$NAME$
    endmethod
    
    method removeBonus takes unit u returns nothing
        call this.setBonus(u, 0)
    endmethod
    
    method isValidBonus takes unit u, integer value returns boolean
        local integer currentBonus
        
        if GetUnitUserData(u) == 0 then
            return false
        endif
        
        set currentBonus = this.getBonus(u)
        
        return R2I(GetUnitState(u, UNIT_STATE_MAX_$STATE$)) - currentBonus + value >= $MIN$
    endmethod
endstruct
//! endtextmacro

//! runtextmacro UnitMaxStateBonus_DefineBonus("life", "LIFE", "1")
//! runtextmacro UnitMaxStateBonus_DefineBonus("mana", "MANA", "1")

private function OnLeaveMap takes unit u returns nothing
    if BonusValues[u] != 0 then
        call BonusValues[u].destroy()
    endif
endfunction

private function DeindexEvent takes nothing returns boolean
    call OnLeaveMap(udg_UDexUnits[udg_UDex])
    return false
endfunction

private function OnInit takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 2.00)
    call TriggerAddCondition(t, Condition(function DeindexEvent))
    
    set BONUS_LIFE = MaxStateBonus_life.create()
    set BONUS_MANA = MaxStateBonus_mana.create()
endfunction
endlibrary
 
Level 7
Joined
Nov 19, 2015
Messages
283
Wow thanks.

Just a personal question. I see that you have made quite a few systems and seem to be able to understand other systems that other people have made and can make modification. How long does it take to get to that point? I've taken a basic java course before and played around with GUI on world editor. Only recently have I tried learning jass.

I don't really like using systems because I like to make them myself so I can understand everything that is going on in my game however some things I have no choice. Are people who make systems here professional programmers or can someone do this as a hobby?
 
Level 7
Joined
Nov 19, 2015
Messages
283
I do this as a hobby. How "good" you are is subjective as we are all computer scientists here (usually by hobby and not profession) and will accept new ideas and approaches if they are groundbreaking or more efficient/compatible.

Thanks for the info. All the smart people making systems and stuff, where I couldn't even understand a thing. I was starting to think that all these people must do it as a profession to know so much about programming.
 
Status
Not open for further replies.
Top