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

[JASS] SetUnitMaxState() o.o?

Status
Not open for further replies.
Level 7
Joined
Mar 22, 2010
Messages
228
JASS:
//////////////////////////////////////////////////////////////////////////////////////////
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@     SetUnitMaxState
//@=======================================================================================
//@ Credits:
//@---------------------------------------------------------------------------------------
//@     Written by:
//@         Earth-Fury
//@     Based on the work of:
//@         Blade.dk
//@
//@ If you use this system, please credit all of the people mentioned above in your map.
//@=======================================================================================
//@ SetUnitMaxState Readme
//@---------------------------------------------------------------------------------------
//@
//@ SetUnitMaxState() is a function origionally written by Blade.dk. It takes advantage of
//@ a bug which was introduced in one of the patches: Bonus life and mana abilitys will
//@ only ever add the bonus ammount for level 1. However, when removed, they will remove
//@ the ammount they should have added at their current level. This allows you to change a
//@ units maximum life and mana, without adding a perminent ability to the unit.
//@
//@---------------------------------------------------------------------------------------
//@ Adding SetUnitMaxState to your map:
//@
//@ Simply copy this library in to a trigger which has been converted to custom text.
//@ After that, you must copy over the abilitys. This is made easy by the ObjectMerger in
//@ JASS NewGen. Distributed with this system are //! external calls to the ObjectMerger.
//@ Simply copy both of them in to your map, save your map, close and reopen your map in
//@ the editor, and remove the external calls. (Or otherwise disable them. Removing the !
//@ after the // works.)
//@
//@---------------------------------------------------------------------------------------
//@ Using SetUnitMaxState:
//@
//@ nothing SetUnitMaxState(unit <target>, unitstate <state>, real <new value>)
//@
//@     This function changes <target>'s unitstate <state> to be eqal to <new value>. Note
//@ that the only valid unitstates this function will use are UNIT_STATE_MAX_MAN and
//@ UNIT_STATE_MAX_LIFE. Use SetUnitState() to change other unitstates.
//@
//@ nothing AddUnitMaxState(unit <target>, unitstate <state>, real <add value>)
//@
//@     This function adds <add value> to <target>'s <state> unitstate. <add value> can be
//@ less than 0, making this function reduce the specified unitstate. This function will
//@ only work with the unitstates UNIT_STATE_MAX_LIFE and UNIT_STATE_MAX_MANA.
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//////////////////////////////////////////////////////////////////////////////////////////
library SetUnitMaxState initializer Initialize
globals
//========================================================================================
// Configuration
//========================================================================================

    // The rawcode of the life ability:
    private constant integer MAX_STATE_LIFE_ABILITY = 'Zx01'
    
    // The rawcode of the mana ability:
    private constant integer MAX_STATE_MANA_ABILITY = 'Zx00'
    
    // The maximum power of two the abilitys use:
    private constant integer MAX_STATE_MAX_POWER = 8
endglobals

//========================================================================================
// System Code
//----------------------------------------------------------------------------------------
// Do not edit below this line unless you wish to change the way the system works.
//========================================================================================

globals
    private integer array PowersOf2
endglobals

function SetUnitMaxState takes unit u, unitstate state, real newValue returns nothing
    local integer stateAbility
    local integer newVal = R2I(newValue)
    local integer i = MAX_STATE_MAX_POWER
    local integer offset
    
    if state == UNIT_STATE_MAX_LIFE then
        set stateAbility = MAX_STATE_LIFE_ABILITY
    elseif state == UNIT_STATE_MAX_MANA then
        set stateAbility = MAX_STATE_MANA_ABILITY
    else
        debug call BJDebugMsg("SetUnitMaxState Error: Invalid unitstate")
        return
    endif
    
    set newVal = newVal - R2I(GetUnitState(u, state))
    
    if newVal > 0 then
        set offset = MAX_STATE_MAX_POWER + 3
    elseif newVal < 0 then
        set offset = 2
        set newVal = -newVal
    else
        return
    endif
    
    loop
        exitwhen newVal == 0 or i < 0
        if newVal >= PowersOf2[i] then
            call UnitAddAbility(u, stateAbility)
            call SetUnitAbilityLevel(u, stateAbility, offset + i)
            call UnitRemoveAbility(u, stateAbility)
            set newVal = newVal - PowersOf2[i]
        else
            set i = i - 1
        endif
    endloop
endfunction

function AddUnitMaxState takes unit u, unitstate state, real addValue returns nothing
    call SetUnitMaxState(u, state, GetUnitState(u, state) + addValue)
endfunction

private function Initialize takes nothing returns nothing
    local integer i = 1
    
    set PowersOf2[0] = 1
    loop
        set PowersOf2[i] = PowersOf2[i - 1] * 2
        set i = i + 1
        exitwhen i == MAX_STATE_MAX_POWER + 3
    endloop
endfunction
endlibrary

so anyone has an idea how to make this work?
 
JASS:
call SetUnitMaxState(unit,UNIT_STATE_MAX_LIFE,500)
call SetUnitMaxState(unit,UNIT_STATE_MAX_MANA,700)

There is documentation, it shows what it does. There should be an //! external function call to generate the object editor data, but otherwise just copy and paste it from whatever demo map there is.

EDIT: Use this updated library:
JASS:
library UnitMaxState initializer Initialize requires optional AbilityPreload, optional xepreload
//==============================================================================
// UnitMaxState v2.1
//==============================================================================
// Credits:
//------------------------------------------------------------------------------
// Written By:
//     Earth-Fury
// 
// Original System By:
//     Blade.dk
// 
// Intermittent Version By:
//     Deaod
//
// With Thanks To:
//     - weaaddar for BonusMod and thus inspiration
//     - PitzerMike for the ObjectMerger
//     - Vexorian for vJass and Jass Helper
//     - PipeDream for Grimoire
//     - SFilip for TESH
//     - MindWorX for maintaining NewGen
//------------------------------------------------------------------------------
// If you use this library in your map, please at least give credit to Blade.dk.
// Without him, this library would not exist.
//==============================================================================
// Introduction:
//------------------------------------------------------------------------------
// UnitMaxState is a library which allows you to modify a unit's maximum life,
// or maximum mana. To achieve this, the library abuses a bug with the AIlf and
// AImz abilities, which is too complex to explain here.
// 
// I do believe it was indeed Blade.dk who initially found this bug. If not,
// it's still his system I stole and rewrote. Further, let me thank Deaod for
// writing up his version of this system, which inspired both the reality of
// this rewrite, and the method abilities are handled within it.
// 
//==============================================================================
// Requirements:
//------------------------------------------------------------------------------
// UnitMaxState is written in vJass and requires the NewGen editor, or
// Jass Helper with PitzerMike's Object Merger configured for it.
// 
// UnitMaxState requires the latest version of Jass Helper.
// 
// Preloading of abilities requires either AbilityPreload or xepreload. Neither
// are required for the library to function; however, having one or the other
// will remove the slight delay the first time a unit's max state is changed.
// 
//==============================================================================
// Using UnitMaxState:
//------------------------------------------------------------------------------
// UnitMaxState comes with two useful functions:
// 
// nothing SetUnitMaxState(unit <target>, unitstate <state>, real <value>)
//     Changes <target>'s unitstate <state> to be equal to <value>.
//
// nothing AddUnitMaxState(unit <target>, unitstate <state>, real <value>)
//     Adds <value> to <target>'s <state> unitstate. Note that you can use
//     negative values with this function.
//
// Both of these functions accept unitstate's other than UNIT_STATE_MAX_LIFE and
// UNIT_STATE_MAX_MANA. There is a small performance penalty in using these over
// direct usage of SetUnitState.
// 
// You must not use life/mana boosting upgrades in combination with this system.
// 
// Attempting to set a unit's maximum life below 1, or mana below 0 will do
// nothing. A debug message will be output if the script is compiled in
// debug mode.
//==============================================================================



//==============================================================================
// Configuration:
//------------------------------------------------------------------------------
// The below textmacro call is an all-in-one configuration line.
//------------------------------------------------------------------------------
// The first parameter is a boolean.
// 
// If true, the abilities used by this system will be created on save. This adds
// a slight delay to saving your map. You only ever have to create the abilities
// the first time this library is added to your map, or if you modify any of
// the other configuration options.
// 
// Note that to make the ability creation permanent, you must save with ability
// creation enabled, close your map, and reopen it in the editor. You can then
// disable ability creation, as the abilities will be permanently in your map.
//------------------------------------------------------------------------------
// The second parameter is an integer.
// 
// This is the number of abilities this system will use for adding/removing
// life/mana. Note that this system uses four sets of abilities, so the actual
// number of abilities generated and used will be the value you pass here,
// multiplied by 4.
// 
// The higher this number, the faster large bonuses will be added. This number
// should never have to go above 13. Between 3 and 5 will work fine for most
// maps.
//------------------------------------------------------------------------------
// The fourth and fifth parameters are 3 character prefixes for rawcodes.
//
// The first one is for the life-modifying abilities, while the second is for
// the mana-modifying abilities.
// 
// Please, make sure your map has no abilities whose rawcodes begin with either
// of these prefixes before saving! Otherwise, those abilities will be
// overwritten. You can change these to any 3 character combination, if your
// map does already contain abilities whose rawcodes begin with these prefixes.
//------------------------------------------------------------------------------

//! runtextmacro UnitMaxState_Configuration("true", "3", "ZxL", "ZxM")

//------------------------------------------------------------------------------
// End of configuration
//------------------------------------------------------------------------------

//! textmacro UnitMaxState_Configuration takes LOAD_ABILITIES, ABILITY_COUNT, LIFE_PREFIX, MANA_PREFIX
    //*
    //! externalblock extension=lua ObjectMerger $FILENAME$
    //! i function CreateAbilities(baseAbility, rawcodePrefix, field, name, icon)
    //! i     k = 0
    //! i     for sign = -1, 1, 2 do
    //! i         signStr = "+"
    //! i         if sign < 0 then
    //! i             signStr = "-"
    //! i         end
    //! i         j = 0
    //! i         for i = 0, (abilityCount - 1) * 3, 3 do
    //! i             j = j + 1
    //! i             createobject(baseAbility, rawcodePrefix .. string.sub(Chars, k + 1, k + 1))
    //! i             makechange(current, "anam", "UnitMaxState - " .. name)
    //! i             makechange(current, "ansf", "(" .. signStr .. tostring(j) .. ")")
    //! i             makechange(current, "aart", "ReplaceableTextures\\CommandButtons\\" .. icon)
    //! i             makechange(current, "aite", 0)
    //! i             makechange(current, "alev", 4)
    //! i             makechange(current, field, 1, 0)
    //! i             makechange(current, field, 2, 2^(i + 0) * sign)
    //! i             makechange(current, field, 3, 2^(i + 1) * sign)
    //! i             makechange(current, field, 4, 2^(i + 2) * sign)
    //! i             k = k + 1
    //! i         end
    //! i     end
    //! i end
    //! i if $LOAD_ABILITIES$ then
    //! i     setobjecttype("abilities")
    //! i     abilityCount = $ABILITY_COUNT$
    //! i     Chars = "abcdefghijklmnopqrstuvwxyz"
    //! i     CreateAbilities("AIlf", "$LIFE_PREFIX$", "Ilif", "Life", "BTNHealthStone.blp")
    //! i     CreateAbilities("AImz", "$MANA_PREFIX$", "Iman", "Mana", "BTNManaStone.blp")
    //! i end
    //! endexternalblock
    // */
    
    globals
        private constant integer RAWCODE_LIFE = '$LIFE_PREFIX$a'
        private constant integer RAWCODE_MANA = '$MANA_PREFIX$a'
        
        public constant integer ABILITY_COUNT = $ABILITY_COUNT$
    endglobals
//! endtextmacro
globals
    private constant boolean PRELOAD_ABILITIES = true
    
    private integer array POWERS_OF_2
endglobals

private function ErrorMsg takes string s returns nothing
    debug call BJDebugMsg("SetUnitMaxState: " + s)
endfunction

function SetUnitMaxState takes unit target, unitstate state, real targetValue returns nothing
    local integer difference
    local integer rawcode
    
    local integer abilityId
    local integer abilityLevel
    
    local integer currentAbility
    
    if state == UNIT_STATE_MAX_LIFE then
        set rawcode = RAWCODE_LIFE
        
        if targetValue < 1 then
            call ErrorMsg("You can not set a unit's max life to below 1")
            return
        endif
    elseif state == UNIT_STATE_MAX_MANA then
        set rawcode = RAWCODE_MANA
        
        if targetValue < 0 then
            call ErrorMsg("You can not set a unit's max mana to below 0")
            return
        endif
    else
        call SetUnitState(target, state, targetValue)
        return
    endif
    
    set difference = R2I(targetValue) - R2I(GetUnitState(target, state))
    
    if difference < 0 then
        set difference = -difference
        set rawcode = rawcode + ABILITY_COUNT
    endif
    
    set abilityId = ABILITY_COUNT - 1
    set abilityLevel = 4
    set currentAbility = rawcode + abilityId
    loop
        exitwhen difference == 0
        
        if difference >= POWERS_OF_2[abilityId * 3 + (abilityLevel - 2)] then
            call UnitAddAbility(target, currentAbility)
            call SetUnitAbilityLevel(target, currentAbility, abilityLevel)
            call UnitRemoveAbility(target, currentAbility)
            
            set difference = difference - POWERS_OF_2[abilityId * 3 + (abilityLevel - 2)]
        else
            set abilityLevel = abilityLevel - 1
            if abilityLevel <= 1 then
                set abilityId = abilityId - 1
                set abilityLevel = 4
                set currentAbility = rawcode + abilityId
            endif
        endif
    endloop
endfunction

function AddUnitMaxState takes unit target, unitstate state, real additionalValue returns nothing
    call SetUnitMaxState(target, state, GetUnitState(target, state) + additionalValue)
endfunction

//! textmacro UnitMaxState_Preload takes RAWCODE
    set i = 0
    loop
        exitwhen i == ABILITY_COUNT * 2 - 1
        
        static if LIBRARY_AbilityPreload then
            call AbilityPreload($RAWCODE$ + i)
        elseif LIBRARY_xepreload then
            call XE_PreloadAbility($RAWCODE$ + i)
        endif
        
        set i = i + 1
    endloop
//! endtextmacro

private function Initialize takes nothing returns nothing
    local integer i
    local integer k
    
    set i = 1
    set POWERS_OF_2[0] = 1
    loop
        exitwhen i == ABILITY_COUNT * 2 * 2 * 3 + 1
        
        set POWERS_OF_2[i] = POWERS_OF_2[i - 1] * 2
        set i = i + 1
    endloop
    
    static if DEBUG_MODE and PRELOAD_ABILITIES and not LIBRARY_AbilityPreload and not LIBRARY_xepreload then
        call ErrorMsg("Ability preloading was enabled, but neither of the supported preload libraries are present")
    elseif PRELOAD_ABILITIES then
        //! runtextmacro UnitMaxState_Preload("RAWCODE_LIFE")
        //! runtextmacro UnitMaxState_Preload("RAWCODE_MANA")
    endif
endfunction
endlibrary

Save the map, close it, and reopen. After the objects are generated, change this line:
JASS:
//! runtextmacro UnitMaxState_Configuration("true", "3", "ZxL", "ZxM")
To:
JASS:
//! runtextmacro UnitMaxState_Configuration("false", "3", "ZxL", "ZxM")
 
Level 9
Joined
Dec 12, 2007
Messages
489
the one you have probably an incomplete one...
because as far as i remember, the SetUnitMaxState library is a complex one that consists of a lot of functions and macros.
the complete one has a readme with it, and you need JNGP to compile it.
 
Level 7
Joined
Mar 22, 2010
Messages
228
am i going to create a new trigger then convert it to text then paste everything?

why syntax will show when i enable it?
 
Level 7
Joined
Mar 22, 2010
Messages
228
after i copy everything..i tried to disable the trigger and enable it again..

it says..
line 14: Expected end of line
and others are "Expected a reserve type or handle type"(line 171 - 182)
the rest are expected a code name...
there are 78 errors..

but when i try it in jassnewgen no syntax will show..
 
Level 7
Joined
Mar 22, 2010
Messages
228
ok after pasting it in JNPG close and then reopen then change some thing..
after that im not gonna touch it again??
 
Status
Not open for further replies.
Top