HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

A little help...

08-02-2007, 06:05 AM#1
Av3n
Hi guys. Right now Im having problemsin my spell Web:
Code

Collapse JASS:
//-----------------------------------------------------------------------------------------------------------
//
//                                         Web v2.01
//                                          By Av3n
//  Contact me by PM at [url]www.wc3campaigns.net[/url], [url]www.clancbs.com/board[/url], or [url]www.forums.hiveworkshop.com[/url]
//
// Requires:
// - JASSHelper preprocessor
// - HandleVars library
// - CSSafety library
//
//-----------------------------------------------------------------------------------------------------------

scope Web //Using scopes to enable the use of the keyword 'private' so simliar named function 
          //won't be interfered
//---------------------------------------------------------------------------------------------------
//
//                                        Configuration
//
//---------------------------------------------------------------------------------------------------
//Use Ctrl + D to find rawcodes
globals
    private constant integer Web_id        = 'A001' //Web spell id based on Channel
    private constant integer Web_dummy     = 'e000' //Web's dummy unit
    private constant integer Web_timerbuff = 'BTLF' //Web's timer buff which is showed when clicking on the web Example:
                                                    // '|||Water Elemantal|  |' will be showed the UI when Water Elemental clicked on          
    private constant integer Web_permhide  = 'A003' //Web Permenant Invisiblity id. Also this could be any ability.
    private constant integer Web_regen     = 'A000' //Web Regeneration id. Also this could be any ability.
    private constant real Web_looprate  = .1     //Loop rate for checking if the caster within the web
endglobals

private constant function Web_lasttime takes real level returns real
    return 30.*level //Web's last time, make sure that the word level is in it or else errors will
                     //occur. The value is a real 
endfunction

private constant function Web_radius takes real level returns real
    return 300.+(level-level) //I want it to stay the same all level's so I done that
endfunction

//---------------------------------------------------------------------------------------------------
//
//                                     Other functions
//
//----------------------------------------------------------------------------------------------------
private struct Web
    unit c = null //The caster
    unit d = null //The dummy for Web!
    integer i = 0 //The spell level
    real x = 0.00 //Dummy's/Location x position
    real y = 0.00 //Dummys's/Location y position
endstruct

private function Web_Timed takes nothing returns nothing
    local timer t = GetExpiredTimer() //We need this to reaccess the struct
    local Web dat = GetHandleInt(t,"struct") //We have our struct again
    local group g = CreateGroup() //We will need to regroup everyone around the web to see if dat.c
                                  //is around
    call GroupEnumUnitsInRange(g,dat.x,dat.y,Web_radius(I2R(dat.i)),null) //Grouping the units and
    if IsUnitInGroup(dat.c,g) then //Checking if it dat.c is in the group
        if GetUnitAbilityLevel(dat.c,Web_permhide) >= 1 then       
            call SetUnitAbilityLevel(dat.c,Web_permhide,dat.i) //We are setting the spell 
            call SetUnitAbilityLevel(dat.c,Web_regen,dat.i) //To dat.i if it is greater than 1
        else
            call UnitAddAbility(dat.c,Web_permhide) //Adding it if it isn't
            call UnitAddAbility(dat.c,Web_regen)
            call SetUnitAbilityLevel(dat.c,Web_permhide,dat.i) 
            call SetUnitAbilityLevel(dat.c,Web_regen,dat.i)
        endif
    else
        call UnitRemoveAbility(dat.c,Web_permhide) //Or removing it if dat.c isn't in the group
        call UnitRemoveAbility(dat.c,Web_regen) 
    endif
    call DestroyGroup(g) //Destroying the group which is required or we are leaking
    if GetWidgetLife(dat.d) <= 0.405 then //Checks if the Web's life is zero
        call UnitRemoveAbility(dat.c,Web_permhide) //Removing the abilities
        call UnitRemoveAbility(dat.c,Web_regen)
        call FlushHandleLocals(t) //Cleaning the struct and info about it
        call dat.destroy() //Destroying the struct
        call ReleaseTimer(t) //Killing the timer with no need to null it
    endif
    set t = null //Cleaning up now
    set g = null
endfunction

//---------------------------------------------------------------------------------------------------
//
//                                       Primary Functions
//
//---------------------------------------------------------------------------------------------------
//Note that these functions below are publics because we still want to use privates and the 
//InitTrig wouldn't be screwed because it isn't part of the scope. And we can still call them. Also
//the fact that a library is exactly like the custom script section so we will keep the code here.
public function Web_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == Web_id //Returns the spell's id
endfunction

public function Web_Actions takes nothing returns nothing
    local Web dat = Web.create() //Creating the struct
    local location p = GetSpellTargetLoc() //We are using this to store tempoary info
    local player o //An empty variable because it relies on 'dat.c'
    local timer t = NewTimer() //As you see CSSafety is required
    set dat.c = GetTriggerUnit() //Now we are setting up the struct fields
    set dat.x = GetLocationX(p)
    set dat.y = GetLocationY(p)
    set dat.i = GetUnitAbilityLevel(dat.c,Web_id)
    set o = GetOwningPlayer(dat.c) //Setting the local fields up
    set dat.d = CreateUnit(o,Web_dummy,dat.x,dat.y,bj_UNIT_FACING)
    call UnitApplyTimedLife(dat.d,Web_timerbuff,Web_lasttime(I2R(dat.i)))
    call RemoveLocation(p) //We destoryed something we won't need because the struct has 
    set p = null //it. So we don't have to clean it up later
    set o = null //Same as the location why we don't need it anymore
    call SetHandleInt(t,"struct",dat) //Saving the struct so it can be used later
    call TimerStart(t,Web_looprate,true,function Web_Timed) //Starting the Timer
    call UnitAddAbility(dat.c,Web_permhide) //Adding the abilities
    call UnitAddAbility(dat.c,Web_regen)
endfunction
endscope //Ending the scope and now Initialising it

function InitTrig_Web takes nothing returns nothing
    local trigger t //Creating an local trigger creating it then nulling it. No global trigger 
    //varibles are needed
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition(t, Condition( function Web_Web_Conditions ) )
    call TriggerAddAction(t, function Web_Web_Actions )
    set t = null
endfunction


I need help with one thing... Is to check if the unit has the ability already in another web. This is the code I understand why it is doing this. But I can't seem to fix it. I thought I nearly got it then bam it didn't remove the ability upon leaving any web(s). So far I might plan resorting to check if it has a aura buff . So any help?

-Av3n
08-03-2007, 01:16 PM#2
Anitarf
A couple of things first:
  • Since you're using a scope and private functions and variables, they don't all need the Web prefix everywhere.
  • (level-level)... where did you get the idea that you have to use your parameters? Remove this nonsense.
  • local group g = CreateGroup() you should just reuse a private global group instead of creating it every time. Also,
  • IsUnitInGroup(dat.c,g) Just use IsUnitInRange, it will be faster than creating a group and then checking if the unit is in it.
Now, for your main problem: the whole thing would be a whole lot easier if you had all your webs running on the same periodic timer/trigger. You would keep a list of units who can cast it and for each one, a linked list of webs. Then, for each unit on the list, you would loop through it's linked list of webs, checking if the unit is within the range of any of them and storing their level to a variable if it's bigger than the current level stored there (thus getting the max level web in range). If the variable is 0 at the end of the loop then the unit isn't in range of any of it's webs, remove abilities, else, set the level of abilities to the value of the variable.
08-04-2007, 07:26 AM#3
Av3n
Thanks Anitarf

-Av3n