PUI Error

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
Hey there.
I'm creating some sort of casting trigger for my boss on my map but I ran into a little problem with the newest PUI. I'm also using Cohadar's Damage Deteciton system (that requires PUI).
I get this error:
JASS:
Comparing two variables of different primitive types (except real and integer) is not allowed

on this line:
JASS:
if DP(illidan) == true then

But I need to check when DP is true...

Other way maybe is to use ordinary GetUnitIndex with an assigned global array, if this can't be accomplished with the nasty macro properties, right?

JASS:

scope WhenToCast

//! runtextmacro PUI_PROPERTY("private", "boolean", "DP", "true")

private function DemPact takes unit illidan returns nothing
    call TriggerSleepAction(60.)
    set DP[illidan] = true
endfunction

private function Cast takes nothing returns boolean
    local unit illidan = GetTriggerUnit()
    local unit dmgr = GetEventDamageSource()
    local real x
    local real y
    if IsUnitType(illidan, UNIT_TYPE_HERO) == true and GetOwningPlayer(illidan) == Player(PLAYER_NEUTRAL_AGGRESSIVE) == true then
        if GetWidgetLife(illidan) < 4700. then
            if DP(illidan) == true then
                set x = GetUnitX(dmgr)
                set y = GetUnitY(dmgr)
                call IssuePointOrder(illidan, "carrionswarm", x, y)
                set DP[illidan] = false
                call DemPact.execute(illidan)
            endif
        endif
    endif
    set illidan = null
    set dmgr = null
    return true
endfunction

function InitTrig_WhenToCast takes nothing returns nothing
    call TriggerAddCondition(GlobalOnDamageTrigger, Condition(function Cast))
endfunction

endscope


PUI:
JASS:

//==============================================================================
//  PUI -- Perfect Unit Indexing by Cohadar -- v5.1
//==============================================================================
//
//  PURPOUSE:
//       * Extending UnitUserData()
//       * This is basically perfect hashing algorithm for units
//
//  HOW TO USE:
//       * You have only one function at your disposal GetUnitIndex(unit)
//         It will return a unique index for each unit in range 1..8190
//
//       * What you will do with that index is all up to you
//         Of course using global arrays is the most obvious choice
//         Advanced jassers will think of a couple of more clever ones ofc.
//
//       * There are also 2 textmacros available at the end of library code
//         They can be used for easier attaching to units
//         PUI for structs 
//         PUI_PROPERTY for unit, integer, real, boolean and string variables
//
//  PROS: 
//       * You can use any number of systems that previously could not work together
//         because they all required exclusive access of UnitUserData()
//
//       * You can also use this to attach spell data structs to casters
//
//       * There are no SetUnitIndex() or ClearUnitIndex() functions here
//         Each unit gets assigned one index that cannot be changed
//         That index will be automatically recycled when unit is removed from the game.
//
//  CONS:
//       * This system uses UnitUserData() itself
//         That means that if you want to use PUI you must recode 
//         any other system that uses UnitUserData() to use GetUnitIndex() instead
//
//       * If you use UnitIndex for arrays of non-native types (timers, effects and similar)
//         you must check if timer on that index already exists before you create a new one.
//         This can happen if GetUnitIndex() assigns a recycled index (index of some dead and removed unit)
//         to the newly created unit for which you intended to use timer for
//
//       * All in all this is not a sys for newbies, it gives great power,
//         but it requires knowledge and carefull handling
//
//  DETAILS:
//       * System is using unit array to keep track of all units with an index.
//         Array is periodically checked for removed units,
//         when removed unit is found, index is recycled.
//         Indexes have "decay time" to prevent bugs
//         caused by attaching to "Can't Raise, Does not decay" type units,
//         or by using RemoveUnit() function
//
//  SYSTEM COMMANDS: (debug mode only, red player only)
//
//       * type -pui to display indexes of currently selected units
//       * type -puistats to display some stats
//
//  THANKS TO:
//       * Vexorian - for his help with PUI textmacro
//
//  HOW TO IMPORT:
//       * Just create a trigger named PUI
//       * convert it to text and replace the whole trigger text with this one
//
//==============================================================================


library PUI initializer Init

//==============================================================================
globals    
    //-----------------------------------------------
    private constant real INDEX_DECAY_TIME = 5.  // seconds
    
    //-----------------------------------------------    
    private constant real PERIOD = 0.03125   // 32 fps
        
    //-----------------------------------------------
    private constant integer DECAY_TICKS = R2I(INDEX_DECAY_TIME/PERIOD)
    
    //-----------------------------------------------
    private integer array Indexz
    private unit    array Unitz
    private integer array Decayz
    private integer array Tickz

    private integer maxindex = 0
    private integer topindex = 0
    private integer decayindex = 0
    private integer checker  = 0
    private integer decayer  = 0
    private integer tick = 0
endglobals


//==============================================================================
private function PeriodicRecycler takes nothing returns boolean
    local integer temp
    
    set tick = tick + 1
    
    if topindex > decayindex then
        set checker = checker + 1
        if checker > topindex then
            set checker = decayindex + 1
        endif
        if (GetUnitUserData(Unitz[checker])==0) then
            set decayindex = decayindex + 1
            set Unitz[checker] = Unitz[decayindex]
            
            // swap(checker, decayindex)
            set temp = Indexz[checker]
            set Indexz[checker] = Indexz[decayindex]
            set Indexz[decayindex] = temp
            
            set Decayz[decayindex] = DECAY_TICKS
            set Tickz[decayindex] = tick
        endif
    endif

    if decayindex > 0 then
        set decayer = decayer + 1
        if decayer > decayindex then
            set decayer = 1
        endif
        set Decayz[decayer] = Decayz[decayer] - (tick-Tickz[decayer])
        if Decayz[decayer] > 0 then
            set Tickz[decayer] = tick
        else
            // swap(decayer, decayindex)
            set temp = Indexz[decayer]
            set Indexz[decayer] = Indexz[decayindex]
            set Indexz[decayindex] = temp
            
            set Unitz[decayindex] = Unitz[topindex]
            
            // swap(decayindex, topindex)
            set temp = Indexz[decayindex]
            set Indexz[decayindex] = Indexz[topindex]
            set Indexz[topindex] = temp
            
            set decayindex = decayindex - 1
            set topindex = topindex - 1
        endif    
    endif
    
    return false
endfunction

//==============================================================================
//  Main and only function exported by this library
//==============================================================================
function GetUnitIndex takes unit whichUnit returns integer
    local integer index
    
    debug if whichUnit == null then
    debug   call BJDebugMsg("|c00FF0000ERROR: PUI - Index requested for null unit")
    debug   return 0
    debug endif
    
    set index = GetUnitUserData(whichUnit)

    if index == 0 then
        set topindex = topindex + 1
        if topindex > maxindex then
            set maxindex = topindex
            set Indexz[topindex] = topindex
        endif
        set index = Indexz[topindex]
        set Unitz[topindex] = whichUnit
       
        call SetUnitUserData(whichUnit, index)
        set index = GetUnitUserData(whichUnit)
       
        // this happens when requesting unit index for removed unit
        debug if index == 0 then
        debug     call BJDebugMsg("|c00FFCC00WARNING: PUI - Bad unit handle")
        debug endif
        
        //debug call BJDebugMsg("|c00FFCC00PUI: Index assigned #" + I2S(index))
    endif
    
    return index
endfunction

//==============================================================================
private function DisplayStats takes nothing returns nothing
    call BJDebugMsg("=============================================")    
    call BJDebugMsg("Biggest index ever = " + I2S(maxindex))    
    call BJDebugMsg("Indexes in use = " + I2S(topindex-decayindex))
    call BJDebugMsg("Decaying indexes = " + I2S(decayindex))
    call BJDebugMsg("Released indexes = " + I2S(maxindex-topindex))
    call BJDebugMsg("=============================================")    
endfunction

//===========================================================================
private function DisplaySelectedEnum takes nothing returns nothing
    call BJDebugMsg( "PUI(" + ( GetUnitName(GetEnumUnit()) + ( ") = " + I2S(GetUnitUserData(GetEnumUnit())) ) ) )
endfunction

//===========================================================================
private function DisplaySelected takes nothing returns nothing
    local group g = CreateGroup()
    call SyncSelections()
    call GroupEnumUnitsSelected(g, Player(0), null)
    call ForGroup(g, function DisplaySelectedEnum)
    call DestroyGroup(g)
    set  g = null
endfunction

//==============================================================================
private function Init takes nothing returns nothing
    local trigger trig 
    
    set trig = CreateTrigger()
    call TriggerRegisterTimerEvent( trig, PERIOD, true )
    call TriggerAddCondition( trig, Condition(function PeriodicRecycler) )

    debug set trig = CreateTrigger()
    debug call TriggerRegisterPlayerChatEvent( trig, Player(0), "-pui", true )
    debug call TriggerAddAction( trig, function DisplaySelected )      
    
    debug set trig = CreateTrigger()
    debug call TriggerRegisterPlayerChatEvent( trig, Player(0), "-puistats", true )
    debug call TriggerAddAction( trig, function DisplayStats )
endfunction

endlibrary


//===========================================================================
//  Allowed PUI_PROPERTY TYPES are: unit, integer, real, boolean, string
//  Do NOT put handles that need to be destroyed here (timer, trigger, ...)
//  Instead put them in a struct and use PUI textmacro
//===========================================================================
//! textmacro PUI_PROPERTY takes VISIBILITY, TYPE, NAME, DEFAULT
$VISIBILITY$ struct $NAME$
    private static unit   array pui_unit
    private static $TYPE$ array pui_data
    
    //-----------------------------------------------------------------------
    //  Returns default value when first time used
    //-----------------------------------------------------------------------
    static method operator[] takes unit whichUnit returns $TYPE$
        local integer pui = GetUnitIndex(whichUnit)
        if .pui_unit[pui] != whichUnit then
            set .pui_unit[pui] = whichUnit
            set .pui_data[pui] = $DEFAULT$
        endif
        return .pui_data[pui]
    endmethod
    
    //-----------------------------------------------------------------------
    static method operator[]= takes unit whichUnit, $TYPE$ whichData returns nothing
        local integer pui = GetUnitIndex(whichUnit)
        set .pui_unit[pui] = whichUnit
        set .pui_data[pui] = whichData
    endmethod
endstruct
//! endtextmacro

//===========================================================================
//  Never destroy PUI structs directly.
//  Use .release() instead, will call .destroy()
//===========================================================================
//! textmacro PUI
    private static unit    array pui_unit
    private static integer array pui_data
    private static integer array pui_id
    
    //-----------------------------------------------------------------------
    //  Returns zero if no struct is attached to unit
    //-----------------------------------------------------------------------
    static method operator[] takes unit whichUnit returns integer
        local integer pui = GetUnitIndex(whichUnit)
        if .pui_data[pui] != 0 then
            if .pui_unit[pui] != whichUnit then
                // recycled handle detected
                call .destroy(.pui_data[pui])
                set .pui_unit[pui] = null
                set .pui_data[pui] = 0            
            endif
        endif
        return .pui_data[pui]
    endmethod
    
    //-----------------------------------------------------------------------
    //  This will overwrite already attached struct if any
    //-----------------------------------------------------------------------
    static method operator[]= takes unit whichUnit, integer whichData returns nothing
        local integer pui = GetUnitIndex(whichUnit)
        if .pui_data[pui] != 0 then
            call .destroy(.pui_data[pui])
        endif
        set .pui_unit[pui] = whichUnit
        set .pui_data[pui] = whichData
        set .pui_id[whichData] = pui
    endmethod

    //-----------------------------------------------------------------------
    //  If you do not call release struct will be destroyed when unit handle gets recycled
    //-----------------------------------------------------------------------
    method release takes nothing returns nothing
        local integer pui= .pui_id[integer(this)]
        call .destroy()
        set .pui_unit[pui] = null
        set .pui_data[pui] = 0
    endmethod
//! endtextmacro

Damage Detection:
JASS:

//==============================================================================
//  DD -- DAMAGE DETECTION SYSTEM BY COHADAR -- v1.0
//==============================================================================
//
//  PURPOUSE:
//       * detects when unit is damaged (not when it is attacked)
//
//  HOW TO USE:
//       * To register damage you will have to assign conditions to a GlobalOnDamageTrigger
//
//       ---------------------------------------------------------------------------------
//       call TriggerAddCondition( GlobalOnDamageTrigger, Condition(function YourCondition) )
//       ---------------------------------------------------------------------------------
// 
//       * Or assign an action to a GlobalOnDamageTrigger
//       ---------------------------------------------------------------------------------
//       call TriggerAddAction( GlobalOnDamageTrigger, function YourAction )
//       ---------------------------------------------------------------------------------
//     
//       * Condition functions MUST take nothing and return boolean
//
//       * Condition functions MUST ALWAYS RETURN TRUE or system will not work
//        
//       * System will first execute all conditions and then all actions
//
//       * Do NOT use waits in Conditions, you can use waits in actions
//
//       * Conditions are faster than actions
//
//       * Do NOT destroy, null or in any other way modify GlobalOnDamageTrigger
//
//       * Inside your Action or Condition you can use this functions
//
//       ---------------------------------------------------------------------------------
//         GetTriggerUnit() - damaged unit 
//         GetEventDamage() - amount of damage (real)
//         GetEventDamageSource() - unit that did the damage, this can be null.
//       ---------------------------------------------------------------------------------
//
//  PROS: 
//       * This is the most optimized OnDamage system of all times,
//         also the most simple one to use. (I am so modest<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite1" alt=":)" title="Smile    :)" loading="lazy" data-shortname=":)" />
//
//       * You can use UnitDamageTarget() and similar functions in your actions and conditions
//         This system is resistant to requrzion. (thanks to PUI)
//
//  CONS:
//       * None by itself, 
//         but it uses PUI and hence has all PROS and CONS that come with PUI
//
//  DETAILS:
//       * Just read the code, it is short and comments are good
//
//  THANKS TO:
//       * emjlr3 for showing me his OnAttack sys
//
//  HOW TO IMPORT:
//       * Just create a trigger named DamageDetection
//       * convert it to text and replace the whole trigger text with this one
//
//==============================================================================


library DamageDetection initializer Init uses PUI

globals
    //===========================================================================
    //  This trigger is the only thing this system exports
    //  This trigger will be executed when ever ANY unit on the map is damaged
    //===========================================================================    
    trigger GlobalOnDamageTrigger

    // prevents requrzion
    private boolean array ignore 
    
    // array of OnDamage triggers, one unit - one trigger
    private trigger array OnDamagePerUnit 
endglobals


//===========================================================================
// Per Unit OnDamage triggers call this function,
// This function then calls GlobalOnDamageTrigger
//===========================================================================
private function OnDamage takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local integer index = GetUnitIndex(u)
    
    //call BJDebugMsg(&quot;|c0000FF00&quot; + &quot;OnDamage&quot;)
    
    if ignore[index] then
        //call BJDebugMsg(&quot;|c0000FF00&quot; + &quot;endless requrzion prevented&quot;)
    else
        // mutex <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
        set ignore[index] = true
        if TriggerEvaluate(GlobalOnDamageTrigger) then
            call TriggerExecute(GlobalOnDamageTrigger)
        else
            call BJDebugMsg(&quot;|c00FF0000&quot; + &quot;ERROR: Conditions for GlobalOnDamageTrigger MUST return TRUE&quot;)
        endif
        
        set ignore[index] = false
    endif

    set u = null 
    return false
endfunction 


// makes sure one and only one OnDamage trigger is created per unit
private function LinkOnDamageTrigger takes unit u returns nothing
    local integer index = GetUnitIndex(u)
    local trigger trig = OnDamagePerUnit[index]
    
    // index was recycled so we destroy trigger because 
    // it belongs to previous unit on that index
    if (trig != null) then
        call DestroyTrigger(trig)
    endif

    set trig = CreateTrigger()
    
    //call BJDebugMsg(&quot;Registering OnDamage for &quot; + GetUnitName(u))
    call TriggerRegisterUnitEvent(trig, u, EVENT_UNIT_DAMAGED)   
    call TriggerAddCondition(trig,Condition(function OnDamage))    
    
    set trig = null
endfunction

//Add damage trigger to units who enter map
private function AddTriggers takes nothing returns boolean
    local unit u = GetTriggerUnit()
    call LinkOnDamageTrigger(u)
    set u = null
    return false
endfunction

//Add damage trigger to preplaced units
private function FirstGroup takes nothing returns nothing
    local unit u = GetEnumUnit()   
    call LinkOnDamageTrigger(u)
    set u = null
endfunction

// Init
private function Init takes nothing returns nothing
    local trigger entmap_trig
    local group g
    
    // One trigger to OnDamage them all
    set GlobalOnDamageTrigger = CreateTrigger()
    
    // register OnDamage for preplaced units
    set g = CreateGroup()
    call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea, null)
    call ForGroup(g,function FirstGroup)
    call DestroyGroup(g)
    set g = null    
   
    // create trigger that registers OnDamage for units that enter the map
    set entmap_trig = CreateTrigger()
    call TriggerRegisterEnterRectSimple(entmap_trig, bj_mapInitialPlayableArea)
    call TriggerAddCondition(entmap_trig,Condition(function AddTriggers))
    set entmap_trig = null
endfunction

endlibrary
 

Artificial

Without Intelligence
Reaction score
326
Try changing this:
JASS:
if DP(illidan) == true then
to this:
JASS:
if DP[illidan] == true then
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
Oh, right. Forgot this type brackets. I'm still used to using "( )" brackets, maybe that's why I have forgotten that. ^^
Thanks, +rep
/ when I can again :( /
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top