HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

[OLY] One With The Wind: code review

08-18-2008, 08:35 PM#1
burningice95
This is my first submission to a spell contest (as well as my first vJass spell), and as such I would like to get your guys opinions on the code.

The spell is a passive, and it increases/decreases movespeed/evasion/transparency every .5 seconds depending on whether the unit is moving or not. It also leaves a "trail" of the unit behind.

Collapse JASS:
//*************************************************************************************************************************************
//                                                   Olympic Spell Contest 2008 Entry
//                                                          Category: Wind
//                                                  Spell name: One with the Wind
//                                                        Made by: Burningice65
//                                                        [url]www.Wc3Campaigns.net[/url]
//*************************************************************************************************************************************

//This spell is FULLY COMPATIBLE with slows/movement speed adding items
scope OneWithTheWind initializer Init 
//**************************************************************************************************************************************
//**********************************************************Begin Configuration Section*************************************************
//**************************************************************************************************************************************
globals
    private constant integer SPELL_ID           = 'Wind' //ID of the spell
    private constant integer SPELLBOOK_ID       = 'Book' //ID of the evasion ability
    private constant integer EVASION_ID         = 'Evas' //ID of the Evasion Ability
    private constant integer DUMMY_ID           = 'Dumb' //ID of the dummy unit with the model of your hero
    private constant integer WALK_ANM_INDEX     = 6 //Index for the "walk" animation of the dummy unit. 
    private constant integer RED                = 255 //These are for if you have tinted your unit in the object editor
    private constant integer BLUE               = 255 //Change these values to match the ones in the editor
    private constant integer GREEN              = 255 //Or if you want the dummy in the trail to have a different color. 
    private constant real MAIN_TIMER_PRD        = .5 //This is very important. This function controls how often the timer that updates the bonuses is. As it currently is, the trigger will
                                                //update the bonuses based on whether the hero is moving every .5 seconds. 
    private constant real TRAIL_TIMER_PRD       = .04 //frequency of the timer that creates the trial
endglobals



private constant function MoveSpeedPerLevel takes integer level returns integer 
//This function allows you to modify how much movement speed is gained for moving. 
if level == 1 then
    return 3
elseif level == 2 then
    return 4 
elseif level == 3 then
    return 5 //gain 5 ms every interval, if you are moving at level 3. 
endif
return 3 
endfunction

private function MovespeedCap takes integer level returns real
//This function allows you to modify the maximum movement speed that unit can have.
if level == 1 then 
    return 450.
elseif level == 2 then 
    return 500.
elseif level == 3 then 
    return 522.
endif
return 522.
//Note you must return reals, so instead of "25" use "25." or "25.0" 
endfunction

private constant function EvasionPerLevel takes integer level returns integer
//This function allows you to modify how much evasion is gained while moving
    return level  //alwasy 1%
endfunction

private function EvasionCap takes integer level returns integer
if level == 1 then 
    return 50
elseif level == 2 then 
    return 60
elseif level == 3 then 
    return 85
endif
return 100
endfunction


private constant function TransparencyPerLevel takes integer level returns integer
//This function allows you to control how much transparency for every 1 second spent moving
    return 2 //currently you lose 2% transparency for every second spent moving, regardless 
endfunction 

private constant function ImageDuration takes integer level returns real
//This function allows you to control how long the images left by the trail last
    return .75
endfunction

private constant function CollisionThreshold takes integer level returns real
//This function allows you to control how fast the unit has to be traveling before collision is turned off
    return 450.
//use return 0 if you want the unit the unit to never lose collision.
endfunction

private constant function UseTrail takes nothing returns boolean
//This function allows you control whether a trail is created behind the unit
    return true 
endfunction


//**************************************************************************************************************************************
//**********************************************************End Configuration Section***************************************************
//*************************************************************************************************************************************

//-------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------


//**************************************************************************************************************************************
//******************************************************Spell Code. Modify beyond here at your own risk!!!******************************
//**************************************************************************************************************************************   
   
globals
    private integer array Transparency //Keeps track of how transparent our target is
    private unit array Unit //keeps track of our hero, via unit indexin
    private real array MsAdded //keeps track of how much MsAdded the target has gained
    private integer array Ticks //Keeps track of bonuses
    private location array Location//keep track of loc for bonuses
    private location array Location2//keep track of loc for trail
    public trigger OWTW_Trig   = CreateTrigger() //Incase you need to refer to the trigger outside of this spell
    private trigger Die = CreateTrigger() //To remove the dummies when they die
    endglobals
//Conditions of the Spell
private function Conditions takes nothing returns boolean 
    return GetLearnedSkill() ==  SPELL_ID
endfunction


//We create a trigger that hides the dummies for the trail when they die, so that their death animation isn't shown
private function Conditions2 takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) == DUMMY_ID 
endfunction

private function Actions2 takes nothing returns nothing 
    call RemoveUnit(GetTriggerUnit())
endfunction


function Trail takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer index = GetTimerData(t)
local unit u = Unit[index]
local location NewLoc = GetUnitLoc(u) //We compare the dist. between these two locs to see if the unit has moved
local unit dummy 
local integer i = GetUnitAbilityLevel(u, SPELL_ID) 
  if  DistanceBetweenPoints(Location2[index],NewLoc) > 0 then 
    set dummy = CreateUnit(Player(1),DUMMY_ID,GetUnitX(u),GetUnitY(u),GetUnitFacing(u))
    call UnitAddAbility(dummy, 'Aloc')
    call SetUnitColor(dummy, GetPlayerColor(GetOwningPlayer(u)) )
    call UnitApplyTimedLife(dummy,'BTLF',ImageDuration(i))
        if Transparency[index] > 50 then
            call SetUnitVertexColor(dummy, RED, BLUE, GREEN, 50)
        else
                call SetUnitVertexColor(dummy, RED, BLUE, GREEN, Transparency[index]) 
        endif
    call SetUnitExploded(dummy, true)
    call SetUnitTimeScalePercent(dummy, 65) 
    call SetUnitAnimationByIndex(dummy, WALK_ANM_INDEX)
    endif
set Location2[index] = GetUnitLoc(u)
call RemoveLocation(NewLoc)
set NewLoc = null
set dummy = null
set u = null
endfunction

private function Callback takes nothing returns nothing
local timer t = GetExpiredTimer() 
local integer index = GetTimerData(t) //Now we know which unit goes with this timer 
local unit u = Unit[index] 
local unit dummy 
local player p = GetOwningPlayer(u)
local integer i = GetUnitAbilityLevel(u, SPELL_ID)  
local location NewLoc = GetUnitLoc(u) //We compare the dist. between these two locs to see if the unit has moved


if  DistanceBetweenPoints(Location[index],NewLoc) > 0 then 
//Stuff to do if the unit is moving
//Increase evasion, but prevent it from going over the maximum allowed per level

        call SetUnitAbilityLevel(u, EVASION_ID, GetUnitAbilityLevel(u, EVASION_ID) + EvasionPerLevel(i)) 
            if GetUnitAbilityLevel(u, EVASION_ID) > EvasionCap(i) then
                    call SetUnitAbilityLevel(u, EVASION_ID, EvasionCap(i))
            endif

//This section decreases transparency, and makes sure it goes below 0 (otherwise it would take too long to go up if you stood still)
        set Transparency[index] = Transparency[index] - TransparencyPerLevel(i)
                    if Transparency[index] < 0 then 
                        set Transparency[index] = 0                  
                    endif         
    call SetUnitVertexColor(u, RED, BLUE, GREEN, Transparency[index])       

//Increase movement speed, and turn off collision if it is high enough

    call SetUnitMoveSpeed(u, GetUnitDefaultMoveSpeed(u) - MsAdded[index]) 
    set MsAdded[index] = MsAdded[index] + MoveSpeedPerLevel(i)
    call SetUnitMoveSpeed(u, GetUnitDefaultMoveSpeed(u) + MsAdded[index])

                if GetUnitMoveSpeed(u) >= CollisionThreshold(i) then 
                    call SetUnitPathing(u, false)
               else 
                   call SetUnitPathing(u,true)
      
                endif

                                
//Stuff to do if the unit is not moving
    else    
    //Decrease evasion and increase transparency 
    call SetUnitAbilityLevel(u, EVASION_ID, GetUnitAbilityLevel(u, EVASION_ID) - EvasionPerLevel(i))
    set Transparency[index] = Transparency[index] + TransparencyPerLevel(i)
               if Transparency[index] > 255 then
                    set Transparency[index] = 255 
               endif
    call SetUnitVertexColor(u, RED, BLUE, GREEN, Transparency[index])
    //Decrease Movement Speed
   call SetUnitMoveSpeed(u, GetUnitDefaultMoveSpeed(u) - MsAdded[index]) 
        if MsAdded[index] == 0 then 
          else 
          set MsAdded[index]= MsAdded[index] - MoveSpeedPerLevel(i) 
              call SetUnitMoveSpeed(u, GetUnitDefaultMoveSpeed(u) + MsAdded[index]) 
        endif
    //Turn on/off collision
       if GetUnitMoveSpeed(u) >= CollisionThreshold(i) then 
           call SetUnitPathing(u, false)
               else 
                   call SetUnitPathing(u,true)
        endif

endif
call DisplayTextToForce(GetPlayersAll(), R2S(GetUnitMoveSpeed(u)))
 
set Location[index] = GetUnitLoc(u) // so we can compare its old location

//Leak Removal
    call RemoveLocation(NewLoc)
    set NewLoc = null
    set u = null
    set dummy = null
endfunction

private function Actions takes nothing returns nothing

local timer t = NewTimer() //the main timer
local timer t2 =NewTimer() //Timer to control the illusion spawning.
local integer index = GetUnitIndex(GetTriggerUnit())
local integer i = 0
local player playa  
    
set Unit[index] = GetTriggerUnit()
set MsAdded[index] = 0
// Store some info about the unit to use later, if this is the first time the unit has learned this.
if GetUnitAbilityLevel(Unit[index], SPELL_ID) == 1 then

    set Transparency[index] = 255
    set Location[index] = GetUnitLoc(Unit[index])


    //Add the spellbook and disable it
    call UnitAddAbility(Unit[index], SPELLBOOK_ID)
    set playa = GetOwningPlayer(Unit[index])
    call SetPlayerAbilityAvailable(playa, SPELLBOOK_ID, false) 


    ///Attach the unit's index to the timer, so we can refer to it later
    call SetTimerData(t, index)
    call TimerStart(t, MAIN_TIMER_PRD, true, function Callback)
    
    if UseTrail() then 
        call SetTimerData(t2, index)
        call TimerStart(t2, TRAIL_TIMER_PRD, true, function Trail)
endif
endif
endfunction




//===========================================================================
private function Init takes nothing returns nothing
    set OWTW_Trig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(OWTW_Trig, EVENT_PLAYER_HERO_SKILL )
    call TriggerAddCondition(OWTW_Trig, Condition(function Conditions))
    call TriggerAddAction(OWTW_Trig, function Actions)
    
    set Die = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( Die, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( Die, Condition( function Conditions2 ) )
    call TriggerAddAction(Die, function Actions2)
endfunction     
endscope











08-18-2008, 08:45 PM#2
Themerion
Collapse JASS:
 // You mean 5, not 50.
return 50 //gain 5 ms every interval, if you are moving at level 3. 


Why not use constant globals for these?
Collapse JASS:
private constant function UseTrail takes nothing returns boolean
//This function allows you control whether a trail is created behind the unit
    return true 
endfunction

private constant function TimerUpdatePeriod takes nothing returns real
//This is very important. This function controls how often the timer that updates the bonuses is. As it currently is, the trigger will
//update the bonuses based on whether the hero is moving every .5 seconds. 
    return .5
endfunction


Also, in almost all coding languages (jass is no exception) you use CAPITAL LETTERS for constants:
Collapse JASS:
constant integer MY_INTEGER = 17


If you want something to be accessible from outside the scope, you should use public-keyword. Not private.
Collapse JASS:
private trigger OWTW_Trig   = CreateTrigger() //Incase you need to refer to the trigger outside of this spell
// do this instead
public trigger Trig   = CreateTrigger() // From outside, refer to the trigger as SCOPENAME_Trig


You should also mention that this script requires... Rising_Dusk's Timer Indexing system?


RemoveUnit() is by some considered to be evil. Why are you removing them anyway?
Collapse JASS:
call RemoveUnit(GetTriggerUnit())
08-18-2008, 09:02 PM#3
burningice95
I edited it to fix all of that

Oh, and I am removing the unit because otherwise it shows its death animation. I tried Hiding it, but that didnt seem to do it. Why is removing evil?
08-18-2008, 10:32 PM#4
TKF
LOL it's funny, it's very close to my first wind name, but thought it would be silly, so I made the caster more visible and renamed my spell to Wind Sailing. It would have been a coincidence if I still kept my spell name Become "One with the Wind"

The difference is that mine is active spell, while yours is passive.