HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Detecting that a hero is using a Town Portal scroll...

02-04-2007, 05:32 PM#1
Zycat
As far as I know a TP scroll only changes the hero's armor to invulnerable... is there anything else that I can detect?

Triggers aren't an option, this is for an A.I
02-04-2007, 08:08 PM#2
Av3n
Why can't you detect the actual town portal item being used or the ability fo Scroll of Town Portal

-Av3n
02-04-2007, 08:21 PM#3
Zycat
Quote:
Originally Posted by Av3n
Why can't you detect the actual town portal item being used or the ability fo Scroll of Town Portal

-Av3n

Well can you? Without triggers that is. AFAIK there's no "Town Portal" ability.

EDIT: Wait.. there's "Item Town Portal" ability. Heh I must've missed that.
EDIT 2 : I just tried using GetUnitAbilityLevel(u,'AItp')>0 and it seems that it returned true regardless of the hero using a TP or not.
02-04-2007, 08:58 PM#4
Pyrogasm
You can use this:
Trigger:
Collapse Events
Unit - A unit starts the effect of an ability
Collapse Conditions
Ability being cast equal to (Item Town Portal)
Collapse Actions
Do your actions here...
Or, if you're using JASS (which it appears that you're doing), add this to your conditions:
Collapse JASS:
function Trig_Untitled_Trigger_001_Conditions takes nothing returns boolean
    if GetSpellAbilityId() == 'AItp' then
        return true
    endif
    return false
endfunction

The EVENT_PLAYER_UNIT_SPELL_EFFECT event runs if an item is used, by-the-way.
02-04-2007, 09:06 PM#5
Zycat
Err... I'm not sure how to implement it in an A.I script
02-04-2007, 09:09 PM#6
Pyrogasm
D'oh. I didn't see that this was for an AI. I'd suggest you go and talk to the AMAI guys about this. They might be able to help you.

At any rate, you could look at how AMAI is set up; that might give you some ideas. Personally, I don't know.
02-04-2007, 09:43 PM#7
Zycat
Well AMAI uses a custom script to tele, and everything is handled directly (from the using of TP scroll), but mine doesn't. Mine relies on Blizzard's internal TP scroll sequence, so I need to detect that the TP scroll is being used.

Anyway, your solution may be implementable inside Blizzard.j, but I'll see my other options first.
02-05-2007, 01:40 AM#8
moyack
The problem with JASS AI is the difficulty to get some kind of information, like which specific unit has some item or ability or unit state. The only way is making functions in the AI script which returns the unit which has an item, taking in account that you have to use natives from common.ai and common.j ONLY.
02-05-2007, 05:42 AM#9
Zycat
Well yeah I know that.

@Pyrogasm
Will EVENT_PLAYER_UNIT_SPELL_CHANNEL work in place of EVENT_PLAYER_UNIT_SPELL_EFFECT for Town Portal? I want the trigger to be fired continuously... (inefficient, I know, but I don't know what else to do)

my code so far :
Collapse JASS:
//===========================================================================
// Trigger: Micro Town Portal (Owner)
//===========================================================================
function Trig_Micro_Town_Portal_Conditions takes nothing returns boolean
    if GetSpellAbilityId() != 'AItp' then
        return false
    endif
    if ( not ( GetPlayerController(GetOwningPlayer(GetTriggerUnit())) == MAP_CONTROL_COMPUTER ) ) then
        return false
    endif
    return true
endfunction

function Trig_Micro_Town_Portal_Actions takes nothing returns nothing
local group g = null
local unit u = null
local real dist = 1000

    set g = CreateGroup()
//    call DisplayDebugPlain("Town Portal")
    call GroupEnumUnitsOfPlayer(g, GetOwningPlayer(GetTriggerUnit()), null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        set dist = DistanceBetweenPoints(GetUnitLoc(u), GetUnitLoc(GetTriggerUnit()))
        if dist < 1500 and dist > 600 then
            call IssuePointOrder(u, "move", GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()))
        endif
        call GroupRemoveUnit(g, u )
    endloop        
    
    call DestroyGroup(g)
    set u = null
    set g = null

endfunction

//===========================================================================
function InitTrig_Micro_Town_Portal takes nothing returns nothing
local trigger gg_trg_Micro_Town_Portal = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Micro_Town_Portal, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Micro_Town_Portal, Condition( function Trig_Micro_Town_Portal_Conditions ) )
    call TriggerAddAction( gg_trg_Micro_Town_Portal, function Trig_Micro_Town_Portal_Actions )
endfunction

Oh yeah BTW does it leak a "local trigger"?
02-05-2007, 06:14 AM#10
Av3n
the distance you didn't clean it up with an null

-Av3n
02-05-2007, 03:45 PM#11
Zycat
Quote:
Originally Posted by Av3n
the distance you didn't clean it up with an null

-Av3n

Really? So real variables leak then?
Or do you mean the Locations? I'm cleaning it up.
02-05-2007, 05:00 PM#12
blu_da_noob
Reals do not need to be nulled.
02-05-2007, 05:20 PM#13
moyack
I think Av3n means about the location :P

@Zycat: I did a small modification to your code

Collapse JASS:
//===========================================================================
// Trigger: Micro Town Portal (Owner) // modified by Moyack
//===========================================================================
function Trig_Micro_Town_Portal_Conditions takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local player p = GetOwningPlayer(u)
    local boolean b1 = GetSpellAbilityId() == 'AItp'
    local boolean b2 = GetPlayerController(p) == MAP_CONTROL_COMPUTER
    set u = null
    set p = null
    return b1 and b2
endfunction

function Trig_Micro_Town_Portal_Distance takes real x1, real y1, real x2, real y2 returns real
    // I implement a distance function which is more efficient, because it doesn't use locations, saving memory and avoiding memory leaks
    local real dx= x2 - x1
    local real dy= y2 - y1
    return SquareRoot(dx*dx+dy*dy)
endfunction

function Trig_Micro_Town_Portal_Actions takes nothing returns nothing
    local group g = CreateGroup()
    local unit c = GetTriggerUnit() // code more readable 
    local unit u
    local real dist

    //    call DisplayDebugPlain("Town Portal")
    call GroupEnumUnitsOfPlayer(g, GetOwningPlayer(c), null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        set dist = Trig_Micro_Town_Portal_Distance(GetUnitX(u), GetUnitY(u), GetUnitX(c), GetUnitY(c))
        if dist < 1500 and dist > 600 then
            call IssuePointOrder(u, "move", GetUnitX(c), GetUnitY(c))
        endif
        call GroupRemoveUnit(g, u )
    endloop        
    
    call DestroyGroup(g)
    set u = null
    set c = null
    set g = null
endfunction

//===========================================================================
function InitTrig_Micro_Town_Portal takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( t, Condition( function Trig_Micro_Town_Portal_Conditions ) )
    call TriggerAddAction( t, function Trig_Micro_Town_Portal_Actions )
    set t = null
endfunction


With it, now you don't need to use locations to calculate distances, avoiding possible memory leaks.
02-05-2007, 06:07 PM#14
Zycat
Quote:
Originally Posted by moyack
I think Av3n means about the location :P

@Zycat: I did a small modification to your code

With it, now you don't need to use locations to calculate distances, avoiding possible memory leaks.

Much appreciated, thanks!
02-05-2007, 07:31 PM#15
Av3n
Quote:
Originally Posted by moyack
I think Av3n means about the location :P

@Zycat: I did a small modification to your code

With it, now you don't need to use locations to calculate distances, avoiding possible memory leaks.

thats what i can of meant

-Av3n