System Fade System

Reaction score
456
It won't be any simplier to me :p.. I don't even know what that text macro does there and so on.. I just know how to use structures and libraries and scopes.. (somehow). :p
 

Cohadar

master of fugue
Reaction score
209
//3.0 Again I rewrote the code. There is still a bug when same unit is faded repeatedly. I also changed the order of the arguments.

You can fix this by checking units current Vertex color

If it is not on 100% it means that unit is already fading and that you should not add it again to the array.

EDIT:

btw you don't need this no matter where trigger is, just delete it.
JASS:
//This maybe removed if code is placed in map's header.
function InitTrig_Fade_System takes nothing returns nothing
endfunction


EDIT2:
Ups there is no way to get default Vertex coloring....

You should probably use something like this
JASS:
	function alreadyFading takes integer dat returns boolean
	    local integer i = 0
		loop
		    exitwhen i >= size
			if dat  == FadeArray<i> then
			    return true
			endif
			set i = i + 1
		endloop
		return false
	endfunction
</i>


This might look slow, but I don't see how someone would start fade on more than 20 units at the same microsecond,
besides you would be calling this only in FadeUnit function,
it will not be called periodically from timer.
 
Reaction score
456
>btw you don't need this no matter where trigger is, just delete it.
Well.. Again I looked that up from Vexorian's castersystem. He had those under the system with a comment "Forced by World Editor", or something like that.

JASS:
function alreadyFading takes integer dat returns boolean
	    local integer i = 0
		loop
		    exitwhen i &gt;= size
			if dat  == FadeArray<i> then
			    return true
			endif
			set i = i + 1
		endloop
		return false
	endfunction</i>

Does that size variable mean total structures there is used? And what shall be the "integer dat"?

EDIT: Great, I noticed that the system doesn't work at all..
 

Cohadar

master of fugue
Reaction score
209
//Forced By WE is not needed in new NewGen versions

dat is your struct ofc. - FadeSystemData

yes size is total struct number - udg_FadeSystem_total

Why it does not work at all?

It works for me...
 
Reaction score
456
Doesn't work for me at all..

Code:
Untitled Trigger 001
    Events
        Player - Player 1 (Red) Selects a unit
    Conditions
    Actions
        Custom script:   call FadeUnit(GetTriggerUnit(), 1.00, 0.00, true)

Tried with that event.
 

Cohadar

master of fugue
Reaction score
209
Bah you probably made some error.
It looks really simple here:
JASS:

function FadeUnit takes unit whichUnit, real duration, real minimumFade, boolean removeAfterFade returns nothing
    local FadeSystemData dat = FadeSystemData.create()

    set dat.whichUnit = whichUnit
    set dat.duration = duration
    set dat.minimumFade = minimumFade
    set dat.removeAfterFade = removeAfterFade
    
    if not CollectionF.contains(dat) then   // &lt;&lt; ----- see no complications
        call CollectionF.add(dat)
    endif
    
    if (CollectionF.size() &gt; 0) then
        call TimerStart(FS_Timer, PERIOD, true, function FadeUnitHandler)
    endif     
endfunction



You should really consider using collections,
here is collection system, play a little with it and you will be enlightened :D
JASS:

//==============================================================================
//  Collections -- STRUCT STORAGE SYSTEM BY COHADAR -- v2.1c
//==============================================================================
//
//  PURPOUSE:
//      * Storing structs for spells that require variable number of data
//      * Great for algorithms that need random access.
//      * Able to create 100% MUI spells.
//
//  REFERENCE:
//      * This system was inspired by java Collection interface
//        <a href="http://java.sun.com/docs/books/tutorial/collections/interfaces/collection.html" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://java.sun.com/docs/books/tutorial/collections/interfaces/collection.html</a>
//        <a href="http://java.sun.com/javase/6/docs/api/java/util/Iterator.html" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://java.sun.com/javase/6/docs/api/java/util/Iterator.html</a>
//
//  DETAILS:
//      * Collections are now implemented as static-only classes
//        this removes limitations in number of elements from version 1.3
//
//      * Main purpouse of collections is fast storing and removing of structs,
//        Structs in Collection are NOT ordered in any way.
//        Structs can change place inside collection at any time.
//        Iterators are the only safe way to access collection elements.
//
//      * Do NOT create or destoy Collection or Iterator classes,
//        there is no point to that because all operations are static
//
//      * Each Collection has exactly one iterator (for performanse reasons)
//
//      * Collections are implemented with global array that is created
//        by calling a collection macro inside a trigger scope.
//        you can have 8191 structs stored in one collection.
//
//      * Since collections are just a wrapper around of global array $X$_buff
//        some people will feel the need to inline collection calls.
//        Please do NOT do this unless it is really necessary for performanse.
//        This will almost never be the case, collections are extremely fast.
//
//
//  HOW TO USE:
//      * For a trigger to use collections it MUST be inside a scope.
//        At the beginning of scope insert this macro call
//        //! runtextmacro COLLECTION(&quot;A&quot;)
//
//      * This will create global array and other fields and methods 
//        needed for collection manipulation
//
//      * To prevent lag when collections are first used put this into spells InitTrigger
//        call CollectionA.init()   // This is optional
//
//---------------------------------------------------------------------------
//  BASIC LOOP:  (data is your custom struct)
//---------------------------------------------------------------------------
//
//        call IteratorA.reset()   // &lt;-- positions iterator at the beginning of collection
//        loop
//            exitwhen IteratorA.noNext()
//            set data = IteratorA.next()
//    
//            if SomeExitCondition(data)
//			     call data.destroy()	
//               call IteratorA.remove()
//		      else
//               -- Process data --
//            endif		
//        endloop
//
//---------------------------------------------------------------------------
//  LIST OF FUNCTIONS:  (all methods are static)
//---------------------------------------------------------------------------
//      struct CollectionX
//          .init()
//          .isEmpty() -&gt; boolean
//          .size() -&gt; integer
//          .contains(integer) -&gt; boolean
//          .add(integer) -&gt; boolean
//          .remove(integer) -&gt; boolean
//          .clear()
//      endstruct
//
//      struct IteratorX
//          .reset()
//          .noNext() -&gt; boolean
//          .next() -&gt; integer
//          .remove()
//      endstruct
//---------------------------------------------------------------------------
//
//  HOW TO IMPORT:
//       * Just create a trigger named Collections
//       * convert it to text and replace the whole trigger text with this one
//
//==============================================================================


globals
	integer MAX_COLLECTION_SIZE = 8191
endglobals

//! textmacro COLLECTION takes X, MODIFIER

// Do NOT use this fields directly
globals
	// Collection fields
	private integer array $X$_buff
	private integer $X$_size = 0
	
	// Iterator fields
	private integer  $X$_index = -1   			
	private boolean  $X$_removeOK = false
endglobals

//==============================================================================
$MODIFIER$ struct Collection$X$
	
	// prevents the lag by forcing wc3 to allocate whole array at once
	static method init takes integer size returns nothing
	    set $X$_buff[size-1] = 0
	endmethod
	
	// checks if collection is empty
	static method isEmpty takes nothing returns boolean
	    return $X$_size &lt;= 0
	endmethod
	
	// returns the current size of collection
	static method size takes nothing returns integer
	    return $X$_size
	endmethod
	
	// checks is element e is inside collection
	static method contains takes integer e returns boolean
	    local integer i = 0
		loop
		    exitwhen i &gt;= $X$_size
			if e == $X$_buff<i> then
			    return true
			endif
			set i = i + 1
		endloop
		return false
	endmethod
	
	// adds element e into collection
	static method add takes integer e returns boolean
	    if $X$_size &lt; MAX_COLLECTION_SIZE then
		    set $X$_buff[$X$_size] = e
		    set $X$_size = $X$_size + 1
			return true
		else
		    call BJDebugMsg(&quot;|C00FF0000ERROR: Collection$X$ overflow in scope &quot; + SCOPE_PREFIX)
		    return false
		endif
	endmethod
	
	// removes first element that matches e from collection
	static method remove takes integer e returns boolean
	    local integer i = 0
		loop
		    exitwhen i &gt;= $X$_size
			if e == $X$_buff<i> then
			    set $X$_size = $X$_size - 1
			    set $X$_buff<i> = $X$_buff[$X$_size]
			    return true
			endif
			set i = i + 1
		endloop
		return false	    
	endmethod
	
	// removes ALL elements from collection
	static method clear takes nothing returns nothing
	    set $X$_size = 0
	endmethod
	
endstruct

//==============================================================================
$MODIFIER$ struct Iterator$X$
	// Use before any looping to reset iterator to the beginning of collection
	static method reset takes nothing returns nothing
		set $X$_index = -1
		set $X$_removeOK = false
	endmethod
	
	// returns true if at the end of collection
	static method noNext takes nothing returns boolean
	    return $X$_index &gt;= ($X$_size-1)
	endmethod
	
	// Not safe operation, use only if noNext returns false
	static method next takes nothing returns integer
	    set $X$_index = $X$_index + 1
		set $X$_removeOK = true
	    return $X$_buff[$X$_index]
	endmethod
	
	//This method can be called only once per call to next.
	static method remove takes nothing returns nothing
	    if $X$_removeOK then
			set $X$_size = $X$_size - 1
			set $X$_buff[$X$_index] = $X$_buff[$X$_size]    
			set $X$_index = $X$_index - 1
			set $X$_removeOK = false
		else
		    call BJDebugMsg(&quot;|c00FF0000ERROR: Iterator$X$ attempted invalid remove in scope&quot; + SCOPE_PREFIX)
		endif
	endmethod
	
endstruct

//! endtextmacro

//forced by WE
function InitTrig_Collections takes nothing returns nothing
endfunction


</i></i></i>
 
Reaction score
456
I wouldn't like to use other system to run my own system :p..

dividedbyzeroerror.PNG


Like it wouldn't store any data..
 

Cohadar

master of fugue
Reaction score
209
*sigh*

Put a not in front of that function call
you are adding new units ONLY if they are NOT already in the array.
 
Reaction score
456
What do you mean? What function call? Why would I?

I already started to rewrite it.
 

Cohadar

master of fugue
Reaction score
209
:banghead:

Look here, you are trying to remove a bug when unit is faded twice right?

The way to do that is to check in FadeUnit function if unit is already fading.
If unit is already fading you ignore second fade request.

Learn to use collections, your life will be simpler.
 

Cohadar

master of fugue
Reaction score
209
Fixing a bug should have a higher priority than adding new features...
Well do as you like I see my help is not appreciated.
 
Reaction score
456
It sure is appreciated. But I just wonder why it stopped working as it worked perfectly yesterday..
 

Cohadar

master of fugue
Reaction score
209
post your last version so I can look for a bug.
(post here inside spoiler and jass tags)
 
Reaction score
456
It is this 3.0 (latest)

JASS:
library FadeSystem
    private struct FadeSystemData
        unit    whichUnit
        real    duration
        real    minimumFade
        boolean removeAfterFade
        real    current = 0.00
        boolean wantDestroy = false
    endstruct
    
    globals
        private FadeSystemData array udg_FadeSystem_array
        private timer                udg_FadeSystem_timer = CreateTimer()
        private integer              udg_FadeSystem_total = 0
    endglobals
    
    private function FadeUnitHandler takes nothing returns nothing
        local FadeSystemData dat
        local integer index = 0
        loop
            exitwhen (index == udg_FadeSystem_total)
            set dat = udg_FadeSystem_array[index]
            if (dat.current &gt;= 100.00 - dat.minimumFade) or (GetUnitState(dat.whichUnit, UNIT_STATE_LIFE) &lt;= 0.00) then
                if (dat.removeAfterFade == true) then
                    call RemoveUnit(dat.whichUnit)
                endif   
                set udg_FadeSystem_array[index] = udg_FadeSystem_array[udg_FadeSystem_total - 1]
                set udg_FadeSystem_total = udg_FadeSystem_total - 1
                call dat.destroy()
                set index = index - 1
            else 
                set dat.current = dat.current + (100.00 - dat.minimumFade) / dat.duration * 0.035
                call SetUnitVertexColor(dat.whichUnit, 255, 255, 255, R2I((100.00-dat.current)*I2R(255)*0.01))  
            endif 
            set index = index + 1
        endloop
        if (udg_FadeSystem_total == 0) then
            call PauseTimer(udg_FadeSystem_timer)
        endif
    endfunction
    
    function FadeUnit takes unit whichUnit, real duration, real minimumFade, boolean removeAfterFade returns nothing
        local FadeSystemData dat = FadeSystemData.create()
        local integer index = 0
        loop
            if (whichUnit == udg_FadeSystem_array[index].whichUnit) then
                call dat.destroy()
                return
            endif
            exitwhen (index == udg_FadeSystem_total)
            set index = index + 1 
        endloop
        set dat.whichUnit = whichUnit
        set dat.duration = duration
        set dat.minimumFade = minimumFade
        set dat.removeAfterFade = removeAfterFade
        set udg_FadeSystem_total = udg_FadeSystem_total + 1
        set udg_FadeSystem_array[udg_FadeSystem_total] = dat
        if (udg_FadeSystem_total == 1) then
            call TimerStart(udg_FadeSystem_timer, 0.035, true, function FadeUnitHandler)
        endif     
    endfunction
endlibrary

//This maybe removed if code is placed in map&#039;s header.
function InitTrig_Fade_System takes nothing returns nothing
endfunction

It doesn't work sometimes (usually when trying to fade only one unit at the same time)
 

Cohadar

master of fugue
Reaction score
209
lool

JASS:
        if (udg_FadeSystem_total == 1) then
            call TimerStart(udg_FadeSystem_timer, 0.035, true, function FadeUnitHandler)
        endif


JASS:
        if (udg_FadeSystem_total &gt;= 1) then  // &lt;------&lt;&lt;&lt;
            call TimerStart(udg_FadeSystem_timer, 0.035, true, function FadeUnitHandler)
        endif
 
Reaction score
456
If I run the same timer many times, the handler function is run more often, which causes the units to fade faster.

That's there for a reason.
 

Cohadar

master of fugue
Reaction score
209
No, you are making an error in your system to fix some other error,
that will not help you.

You have to use >= 1 and use checking as I described in my previous posts.

I told you all the info you need to know to fix this,
you are on your own. - learn to read more carefully.
 
Reaction score
456
I'm glad that you took some time with this <3

> Then just add a 'GetFadedUnit' event response function that returns the value of a global variable. Well, that's just my suggestion to make the system more generic.
How am I able to get the unit which was faded? If I use global variable, it get's overwritten when function is ran many times..?
 

Cohadar

master of fugue
Reaction score
209
no phyrexian is correct GetFadedUnit() should return last faded unit via global.

It will not get overwritten if you do it in same thread... um a bit complicated to explain.

But you should not do it manually, Jasshelper will do that automatically for you if you make it with function interface.

JASS:

function interface IFadedUnitHandler takes unit u returns nothing

private struct FadeSystemData
    unit    whichUnit
    real    duration
    real    minimumFade
    
    //boolean removeAfterFade
    IFadedUnitHandler callback  // &lt;--&lt;&lt;
    
    real    current = 0.00
    boolean wantDestroy = false
endstruct


also chang here:
JASS:

        if (dat.current &gt;= 100.00 - dat.minimumFade) or (GetUnitState(dat.whichUnit, UNIT_STATE_LIFE) &lt;= 0.00) then
            if (dat.callback != null) then
                call dat.callback.execute(dat.whichUnit)
            endif


and here is a trigger that uses Fade System with function interface:
JASS:

// this function is using IFadedUnitHandler interface
function MyHandler takes unit u returns nothing
    call RemoveUnit(u) // or anything else you want
endfunction

function Trig_Fade_Test_Actions takes nothing returns nothing
    call FadeUnit( GetTriggerUnit(), 5.0, 0.5, IFadedUnitHandler.MyHandler)
endfunction

//===========================================================================
function InitTrig_Fade_Test takes nothing returns nothing
    set gg_trg_Fade_Test = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Fade_Test, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction( gg_trg_Fade_Test, function Trig_Fade_Test_Actions )
endfunction


Read more about function interfaces in NewGen documentation
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top