• 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.

BotL - Coding & Systems

Status
Not open for further replies.
Level 18
Joined
Sep 14, 2012
Messages
3,413
JASS:
library Transparency requires Table
    globals
        private constant real FPS = 0.062500
    endglobals
    
    struct Transparency extends array
        private unit target
        private real temp
        private integer delta
        private thistype next
        private thistype prev
        private static integer count
        private static timer period
        private static HandleTable tab
        
        static method GetUnitAlpha takes unit u returns integer
            if tab.exists(u) then
                return tab[u]
            else
                return 255
            endif
        endmethod
        
        private static method cond takes nothing returns boolean
            local unit u = GetTriggerUnit()
            if tab.exists(u) then
                call tab.flush(u)
            endif
            set u = null
            return false
        endmethod
        
        private static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next
            local integer i
            loop
                exitwhen this == 0
                set this.temp = this.temp - FPS
                if this.temp <= 0 then
                    call this.destroy()
                else
                    set i = GetUnitAlpha(this.target)-this.delta
                    call SetUnitVertexColor(this.target, 255, 255, 255, i)
                    set tab[this.target] = i
                endif
                set this = this.next
            endloop
        endmethod
        
        static method fadeOut takes unit targ, real dur returns nothing
            local thistype this
            local integer i
            if thistype(0).prev == 0 then
                set count = count + 1
                set this = count
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.periodic)
            else
                set thistype(0).next.prev = this
            endif
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0).prev
            set this.target = targ
            set this.temp = dur - FPS
            set this.delta = - R2I(255/dur/FPS)+1
            set i = GetUnitAlpha(targ)-this.delta
            call SetUnitVertexColor(targ, 255, 255, 255, i)
            set tab[targ] = i
        endmethod
        
        static method fadeIn takes unit targ, real dur returns nothing
            local thistype this
            local integer i
            if thistype(0).prev == 0 then
                set count = count + 1
                set this = count
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.periodic)
            else
                set thistype(0).next.prev = this
            endif
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0).prev
            set this.target = targ
            set this.temp = dur - FPS
            set this.delta = R2I(255/dur/FPS)+1
            set i = GetUnitAlpha(targ)-this.delta
            call SetUnitVertexColor(targ, 255, 255, 255, i)
            set tab[targ] = i
        endmethod
        
        private method destroy takes nothing returns nothing
            if this.next != 0 then
                set this.next.prev = this.prev
            endif
            set this.prev.next = this.next
            set this.prev = thistype(0).prev
            set thistype(0).prev = this
            if thistype(0).next == 0 then
                call PauseTimer(period)
            endif
            set this.target = null
        endmethod

        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
            call TriggerAddCondition(t, Condition(function thistype.cond))
            set tab = HandleTable.create()
            set count = 0
            set period = CreateTimer()
            set t = null
        endmethod
    endstruct
endlibrary
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
i found the bug!!
JASS:
        private static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next
            local integer i
            loop
                exitwhen this == 0
                set this.temp = this.temp - FPS
                if this.temp <= 0 then
                    call SetUnitVertexColor(this.target, 255, 255, 255, 255)
                    call this.destroy()
                else
                    set i = GetUnitAlpha(this.target)-this.delta
                    call BJDebugMsg(R2S(GetUnitAlpha(this.target)))
                    call BJDebugMsg(R2S(this.delta))
                    call SetUnitVertexColor(this.target, 255, 255, 255, i)
                    set tab[this.target] = i
                endif
                set this = this.next
            endloop
        endmethod
This is what happens XD
2IVPuWi.png
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
Thanks for the idea chobibo :)

Try this :
JASS:
library Transparency requires Table
    globals
        private constant real FPS = 0.062500
    endglobals
    
    struct Transparency extends array
        private unit target
        private real temp
        private integer delta
        private thistype next
        private thistype prev
        private static integer count
        private static timer period
        private static HandleTable tab
        
        static method GetUnitAlpha takes unit u returns integer
            if tab.exists(u) then
                return tab[u]
            else
                return 255
            endif
        endmethod
        
        private static method cond takes nothing returns boolean
            local unit u = GetTriggerUnit()
            if tab.exists(u) then
                call tab.flush(u)
            endif
            set u = null
            return false
        endmethod
        
        private static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next
            local integer i
            loop
                exitwhen this == 0
                set this.temp = this.temp - FPS
                if this.temp <= 0 then
                    if this.delta < 0 then
                        call SetUnitVertexColor(this.target, 255, 255, 255, 255)
                    else
                        call SetUnitVertexColor(this.target, 255, 255, 255, 0)
                    endif
                    call this.destroy()
                else
                    set i = GetUnitAlpha(this.target)-this.delta
                    call SetUnitVertexColor(this.target, 255, 255, 255, i)
                    set tab[this.target] = i
                endif
                set this = this.next
            endloop
        endmethod
        
        static method fadeOut takes unit targ, real dur returns nothing
            local thistype this
            local integer i
            if thistype(0).prev == 0 then
                set count = count + 1
                set this = count
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.periodic)
            else
                set thistype(0).next.prev = this
            endif
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0).prev
            set this.target = targ
            set this.temp = dur - FPS
            set this.delta = - R2I(255/(dur/FPS))
            set i = GetUnitAlpha(targ)-this.delta
            call SetUnitVertexColor(targ, 255, 255, 255, i)
            set tab[targ] = i
        endmethod
        
        static method fadeIn takes unit targ, real dur returns nothing
            local thistype this
            local integer i
            if thistype(0).prev == 0 then
                set count = count + 1
                set this = count
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.periodic)
            else
                set thistype(0).next.prev = this
            endif
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0).prev
            set this.target = targ
            set this.temp = dur - FPS
            set this.delta = R2I(255/(dur/FPS))
            set i = GetUnitAlpha(targ)-this.delta
            call SetUnitVertexColor(targ, 255, 255, 255, i)
            set tab[targ] = i
        endmethod
        
        private method destroy takes nothing returns nothing
            if this.next != 0 then
                set this.next.prev = this.prev
            endif
            set this.prev.next = this.next
            set this.prev = thistype(0).prev
            set thistype(0).prev = this
            if thistype(0).next == 0 then
                call PauseTimer(period)
            endif
            set this.target = null
        endmethod

        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
            call TriggerAddCondition(t, Condition(function thistype.cond))
            set tab = HandleTable.create()
            set count = 0
            set period = CreateTimer()
            set t = null
        endmethod
    endstruct
endlibrary
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
There's still a problem with it dude, approximation sucks haha... (real to integer conversion fucks up the delta value)
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Hey Mal, the problem is with the approximation. You need to disable transparency stacking for the unit and store the current alpha and delta value to a real variable to be able to set the precise alpha value.

JASS:
library Transparency requires Table
    globals
        private constant real FPS = 0.062500
    endglobals
   
    struct Transparency extends array
        private unit target
        private real temp
        private integer alpha
        private integer delta
        private thistype next
        private thistype prev
        private static integer count
        private static timer period
        private static HandleTable tab
       
        static method GetUnitAlpha takes unit u returns integer
            if tab.exists(u) then
                return tab[u]
            else
                return 255
            endif
        endmethod
       
        private static method cond takes nothing returns boolean
            local unit u = GetTriggerUnit()
            if tab.exists(u) then
                call tab.flush(u)
            endif
            set u = null
            return false
        endmethod
       
        private static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next
            local integer i
            loop
                exitwhen this == 0
                set this.temp = this.temp - FPS
                if this.temp <= 0 then
                    call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Alpha is "+I2S(this.alpha))
                    call this.destroy()
                else
                    //set i = GetUnitAlpha(this.target)+this.delta
                    set this.alpha=this.alpha+this.delta
                    call SetUnitVertexColor(this.target, 255, 255, 255, this.alpha)
                    //set tab[this.target] = i
                endif
                set this = this.next
            endloop
        endmethod
       
        static method fadeOut takes unit targ, real dur returns nothing
            local thistype this
            local integer i
            if thistype(0).prev == 0 then
                set count = count + 1
                set this = count
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.periodic)
            else
                set thistype(0).next.prev = this
            endif
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0).prev
            set this.target = targ
            set this.temp = dur
            set this.alpha = 255
            set this.delta = R2I(255/(dur/FPS))*-1
            //set i = GetUnitAlpha(targ)+this.delta
            call SetUnitVertexColor(targ, 255, 255, 255, 255+this.delta)
            set tab[targ] = i
        endmethod
       
        static method fadeIn takes unit targ, real dur returns nothing
            local thistype this
            local integer i
            if thistype(0).prev == 0 then
                set count = count + 1
                set this = count
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.periodic)
            else
                set thistype(0).next.prev = this
            endif
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0).prev
            set this.target = targ
            set this.temp = dur
            set this.alpha = 0
            set this.delta = R2I(255/(dur/FPS))
            //set i = GetUnitAlpha(targ)+this.delta
            call SetUnitVertexColor(targ, 255, 255, 255, 0+this.delta)
            set tab[targ] = i
        endmethod
       
        private method destroy takes nothing returns nothing
            if this.next != 0 then
                set this.next.prev = this.prev
            endif
            set this.prev.next = this.next
            set this.prev = thistype(0).prev
            set thistype(0).prev = this
            if thistype(0).next == 0 then
                call PauseTimer(period)
            endif
            set this.target = null
        endmethod

        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
            call TriggerAddCondition(t, Condition(function thistype.cond))
            set tab = HandleTable.create()
            set count = 0
            set period = CreateTimer()
            set t = null
        endmethod
    endstruct
endlibrary
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
JASS:
        private static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next
            local integer i
            loop
                exitwhen this == 0
                set this.temp = this.temp - FPS
                if this.temp <= 0 then
                    if this.delta < 0 then
                        call SetUnitVertexColor(this.target, 255, 255, 255, 255)
                    else
                        call SetUnitVertexColor(this.target, 255, 255, 255, 0)
                    endif
                    call this.destroy()
                else
                    set i = GetUnitAlpha(this.target)-this.delta
                    call BJDebugMsg(R2S(GetUnitAlpha(this.target)))
                    call BJDebugMsg(R2S(this.delta))
                    call SetUnitVertexColor(this.target, 255, 255, 255, i)
                    set tab[this.target] = i
                endif
                set this = this.next
            endloop
        endmethod
after first use:
lexz.png

after consecutive uses:
zdRGiH1.png
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
What? It works on a my copy. You must be doing something wrong.

JASS:
library Transparency requires Table
    globals
        private constant real FPS = 0.062500
    endglobals
   
    struct Transparency extends array
        private unit target
        private real temp
        private real alpha
        private real delta
        private thistype next
        private thistype prev
        private static integer count
        private static timer period
        private static HandleTable tab
       
        static method GetUnitAlpha takes unit u returns integer
            if tab.exists(u) then
                return tab[u]
            else
                return 255
            endif
        endmethod
       
        private static method cond takes nothing returns boolean
            local unit u = GetTriggerUnit()
            if tab.exists(u) then
                call tab.flush(u)
            endif
            set u = null
            return false
        endmethod
       
        private static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next
            local integer i
            loop
                exitwhen this == 0
                set this.temp = this.temp - FPS
                if this.temp < 0 then
                    call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Alpha is "+R2S(this.alpha))
                    call this.destroy()
                else
                    //set i = GetUnitAlpha(this.target)+this.delta
                    set this.alpha=this.alpha+this.delta
                    call SetUnitVertexColor(this.target, 255, 255, 255, R2I(this.alpha))
                    //set tab[this.target] = i
                endif
                set this = this.next
            endloop
        endmethod
       
        static method fadeOut takes unit targ, real dur returns nothing
            local thistype this
            local integer i
            if thistype(0).prev == 0 then
                set count = count + 1
                set this = count
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.periodic)
            else
                set thistype(0).next.prev = this
            endif
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0).prev
            set this.target = targ
            set this.temp = dur
            set this.alpha = 255
            set this.delta = (255/(dur/FPS))*-1
            //set i = GetUnitAlpha(targ)+this.delta
            call SetUnitVertexColor(targ, 255, 255, 255, 255+R2I(this.delta))
            set tab[targ] = i
        endmethod
       
        static method fadeIn takes unit targ, real dur returns nothing
            local thistype this
            local integer i
            if thistype(0).prev == 0 then
                set count = count + 1
                set this = count
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.periodic)
            else
                set thistype(0).next.prev = this
            endif
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0).prev
            set this.target = targ
            set this.temp = dur
            set this.alpha = 0
            set this.delta = 255/(dur/FPS)
            //set i = GetUnitAlpha(targ)+this.delta
            call SetUnitVertexColor(targ, 255, 255, 255, 0+R2I(this.delta))
            set tab[targ] = i
        endmethod
       
        private method destroy takes nothing returns nothing
            if this.next != 0 then
                set this.next.prev = this.prev
            endif
            set this.prev.next = this.next
            set this.prev = thistype(0).prev
            set thistype(0).prev = this
            if thistype(0).next == 0 then
                call PauseTimer(period)
            endif
            set this.target = null
        endmethod

        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
            call TriggerAddCondition(t, Condition(function thistype.cond))
            set tab = HandleTable.create()
            set count = 0
            set period = CreateTimer()
            set t = null
        endmethod
    endstruct
endlibrary

Here dude, just add the stacking restriction Malhorne.

NOTE: fadeIn: 0 to 100; fadeOut: 100 to 0
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
no, the 'system' works for me, BUT it does something wrong with the spell...

BUT not STOP i fixed it
i told you that the alpha thing in the table was wrong:
JASS:
        private static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next
            local integer i
            loop
                exitwhen this == 0
                set this.temp = this.temp - FPS
                if this.temp <= 0 then
                    if this.delta < 0 then
                        call SetUnitVertexColor(this.target, 255, 255, 255, 255)
                    else
                        call SetUnitVertexColor(this.target, 255, 255, 255, 0)
                    endif
                    @set tab[this.target] = 255@ // this should've been done
                    call this.destroy()
                else
                    set i = GetUnitAlpha(this.target)-this.delta
                    call SetUnitVertexColor(this.target, 255, 255, 255, i)
                    set tab[this.target] = i
                endif
                set this = this.next
            endloop
        endmethod
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Yeah, it shouldn't apply two instances on a single unit because it would look weird. The end result will still be proper though. (multiple fadeOut will result to an invisible unit, but the fading out effect would be fucked haha xD)

EDIT:
@JAD: I'm NOT using the table. I just added what was needed, I didn't remove the unneeded stuff.

EDIT:
That's not my code dude...
JASS:
        private static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next
            local integer i
            loop
                exitwhen this == 0
                set this.temp = this.temp - FPS
                if this.temp < 0 then
                    call DisplayTextToPlayer(GetLocalPlayer(),0,0,"Alpha is "+R2S(this.alpha))
                    call this.destroy()
                else
                    //set i = GetUnitAlpha(this.target)+this.delta
                    set this.alpha=this.alpha+this.delta
                    call SetUnitVertexColor(this.target, 255, 255, 255, R2I(this.alpha))
                    //set tab[this.target] = i
                endif
                set this = this.next
            endloop
        endmethod
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
it's hard to describe, in simple form: when using chobi's one the spell gets stuck, doesn't work...

NOW STOP
Here is the final WORKING Product:
JASS:
library Transparency requires Table
    globals
        private constant real FPS = 0.062500
    endglobals
   
    struct Transparency extends array
        private unit target
        private real temp
        private integer delta
        private thistype next
        private thistype prev
        private static integer count
        private static timer period
        private static HandleTable tab
       
        static method GetUnitAlpha takes unit u returns integer
            if tab.exists(u) then
                return tab[u]
            else
                return 255
            endif
        endmethod
       
        private static method cond takes nothing returns boolean
            local unit u = GetTriggerUnit()
            if tab.exists(u) then
                call tab.flush(u)
            endif
            set u = null
            return false
        endmethod
       
        private static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next
            local integer i
            loop
                exitwhen this == 0
                set this.temp = this.temp - FPS
                if this.temp <= 0 then
                    if this.delta < 0 then
                        call SetUnitVertexColor(this.target, 255, 255, 255, 255)
                    else
                        call SetUnitVertexColor(this.target, 255, 255, 255, 0)
                    endif
                    call this.destroy()
                else
                    set i = GetUnitAlpha(this.target)-this.delta
                    call SetUnitVertexColor(this.target, 255, 255, 255, i)
                    set tab[this.target] = i
                endif
                set this = this.next
            endloop
        endmethod
       
        static method fadeOut takes unit targ, real dur returns nothing
            local thistype this
            local integer i
            if thistype(0).prev == 0 then
                set count = count + 1
                set this = count
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.periodic)
            else
                set thistype(0).next.prev = this
            endif
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0).prev
            set this.target = targ
            set this.temp = dur - FPS
            set this.delta = - R2I(255/(dur/FPS))
            set tab[this.target] = 0
            set i = GetUnitAlpha(targ)-this.delta
            call SetUnitVertexColor(targ, 255, 255, 255, i)
            set tab[targ] = i
        endmethod
       
        static method fadeIn takes unit targ, real dur returns nothing
            local thistype this
            local integer i
            if thistype(0).prev == 0 then
                set count = count + 1
                set this = count
            else
                set this = thistype(0).prev
                set thistype(0).prev = thistype(0).prev.prev
            endif
            if thistype(0).next == 0 then
                call TimerStart(period, FPS, true, function thistype.periodic)
            else
                set thistype(0).next.prev = this
            endif
            set this.next = thistype(0).next
            set thistype(0).next = this
            set this.prev = thistype(0).prev
            set this.target = targ
            set this.temp = dur - FPS
            set this.delta = R2I(255/(dur/FPS))
            set tab[this.target] = 255
            set i = GetUnitAlpha(targ)-this.delta
            call SetUnitVertexColor(targ, 255, 255, 255, i)
            set tab[targ] = i
        endmethod
       
        private method destroy takes nothing returns nothing
            if this.next != 0 then
                set this.next.prev = this.prev
            endif
            set this.prev.next = this.next
            set this.prev = thistype(0).prev
            set thistype(0).prev = this
            if thistype(0).next == 0 then
                call PauseTimer(period)
            endif
            set this.target = null
        endmethod

        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
            call TriggerAddCondition(t, Condition(function thistype.cond))
            set tab = HandleTable.create()
            set count = 0
            set period = CreateTimer()
            set t = null
        endmethod
    endstruct
endlibrary
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Hah, that has bugs, try printing the final Alpha, don't say I didn't tell you though. Enjoy the bugs Jad. :D

Eh Malhorne, I'll post the clean code I made, just for fun.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
I already explained the bug, believe what you want to believe.

EDIT: Oh, and setting the final value to 255 is a programming flaw, the current algorithm you're using doesn't fade the units smoothly... Oh and I guess you didn't see the bug with the this.temp <= 0 condition right?
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
The bug was unrelated to my edit dude, when I removed all the table calls the thing worked fine...
 
Status
Not open for further replies.
Top