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

Tower Range Check

Status
Not open for further replies.
Level 7
Joined
Oct 14, 2008
Messages
340
Perhaps you could use

  • (Current acquisition range of (your unit)) Greater than or equal to x
then create an effect circle for that radius? and maybe make this circle disappear when the unit is deselected.

You would of course have to set the acquisition range for all of your towers equal to their attack range.
 
Level 18
Joined
Mar 7, 2005
Messages
824
uhm I don't think you could use the aquisation range, because it's only the range within the tower notices the units.. so the AR could be 800 and the tower notices units within the range of 800 but if he has an attackrange of 600 he can't attack but he would lock some units, maybe some with low HP or something else.. so it would create a bigger circle than the tower has for its attack (maybe, normally it's set higher than attackrange) so how about using a variable "TowerRange" and make it an array.. then just add it to some tower types, like Canon Tower, or Ice Tower whatever you're using.. and set the range for it.. e.g. CanonTower will be "TowerRange[1]" = 700, and then use a trigger that creates a unit, maybe some shiny thingy around the tower with the range of "TowerRange[1]" you need so do some maths for the degree numbers.. but that's it
 
Level 10
Joined
Sep 6, 2008
Messages
423
uhm I don't think you could use the aquisation range, because it's only the range within the tower notices the units.. so the AR could be 800 and the tower notices units within the range of 800 but if he has an attackrange of 600 he can't attack but he would lock some units, maybe some with low HP or something else.. so it would create a bigger circle than the tower has for its attack (maybe, normally it's set higher than attackrange) so how about using a variable "TowerRange" and make it an array.. then just add it to some tower types, like Canon Tower, or Ice Tower whatever you're using.. and set the range for it.. e.g. CanonTower will be "TowerRange[1]" = 700, and then use a trigger that creates a unit, maybe some shiny thingy around the tower with the range of "TowerRange[1]" you need so do some maths for the degree numbers.. but that's it

But if you have the same acquistion range to the same as attack range it should work and this is what Maximilianx meant (i think) and that makes your comment a bit off when you say that the towers acquistion range is higher than attack range..
 
Level 18
Joined
Mar 7, 2005
Messages
824
normally it is, and i said normally, sure you can set it to the same range as the attackrange, but mostly it has more range, so that the tower can attack the best unit..
however there are some ways to do it =)
so if you use aquisation range set it to attackrange (but I don't suggest it)
 
Level 7
Joined
Oct 14, 2008
Messages
340
normally it is, and i said normally, sure you can set it to the same range as the attackrange, but mostly it has more range, so that the tower can attack the best unit..
however there are some ways to do it =)
so if you use aquisation range set it to attackrange (but I don't suggest it)

...What? like i said in my post, you would have to set your towers' acquisition range equal to that of their attack range.

And man I'm so adjusted to jass i can't even think how I would do this in GUI..

EDIT: came up with a little something, should be easy to customize. Tested and works like a charm :D
JASS:
//This will create an effect circle around your towers who's radius is equal to their acquisition range.
//which you should set equal to their attack range (in the object editor)
function EffectString takes nothing returns string
    return "Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl"
    
    //Replace Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl with the path of your desired effect.
    //you MUST use two forward slashes instead of one or it will not work.
endfunction

function Delay takes nothing returns real
    return 1.0
    
    //Replace 1.0 with your desired delay for the effect to disapear after a player deselects the unit.. 
    //Don't go too low with this. 0.1 at the lowest.
endfunction

function Towers takes unit u returns boolean
    //Copy and paste this if statement and change the rawcode for every tower you want this to work for.
    if GetUnitTypeId(u) == 'n000' then
        return true
    endif

    return false
endfunction


//===========================================================================
function SelectTowerConditions takes nothing returns boolean
    return Towers(GetTriggerUnit())
endfunction

function AddSpecialEffectPlayer takes player p, string modelName, real x, real y returns effect
    if GetLocalPlayer() == p then
        return AddSpecialEffect(modelName, x, y)
    endif
    return null
endfunction

function SelectTowerActions takes nothing returns nothing
    local player p = GetTriggerPlayer()
    local unit tower = GetTriggerUnit()
    local real range = GetUnitDefaultAcquireRange(GetTriggerUnit())
    local integer amount = R2I(range/1.5)
    local real angle = 0.0
    local real increment = 360.0/25
    local real x = GetUnitX(tower)
    local real y = GetUnitY(tower)
    local real x2
    local real y2
    local effect array e
    local integer i = 0
    local integer i2 = 0
    loop
        set x2 = x+range*Cos(angle*bj_DEGTORAD)
        set y2 = y+range*Sin(angle*bj_DEGTORAD)
        set e[i] = AddSpecialEffectPlayer(p, EffectString(), x2, y2)
        set angle = angle + increment
        set i = i+1
        exitwhen i == amount
    endloop
    loop
        exitwhen GetWidgetLife(tower) < 0.2 or IsUnitSelected(tower, p) == false
        call TriggerSleepAction(Delay())
    endloop
    loop
        call DestroyEffect(e[i2])
        set e[i2] = null
        set i2 = i2+1
        exitwhen i2 == i+1
    endloop
endfunction

//===========================================================================
function InitTrig_SelectTower takes nothing returns nothing
    set gg_trg_SelectTower = CreateTrigger()
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(0), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(1), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(2), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(3), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(4), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(5), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(6), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(7), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(8), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(9), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(10), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(11), true)
    
    call TriggerAddCondition(gg_trg_SelectTower, Condition(function SelectTowerConditions))
    call TriggerAddAction(gg_trg_SelectTower, function SelectTowerActions)
endfunction
 
Last edited:
Level 9
Joined
Aug 1, 2008
Messages
453
Do i need to make any varibles cause it comes up with error "Expected a varible name"

What did i do wrong?
JASS:
//This will create an effect circle around your towers who's radius is equal to their acquisition range.
//which you should set equal to their attack range (in the object editor)
function EffectString takes nothing returns string
    return "Doodads\\Cityscape\\Props\\MagicRunes\\MagicRunes"

    //Replace Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl with the path of your desired effect.
    //you MUST use two forward slashes instead of one or it will not work.
endfunction

function Delay takes nothing returns real
    return 0.2

    //Replace 1.0 with your desired delay for the effect to disapear after a player deselects the unit..
    //Don't go too low with this. 0.1 at the lowest.
endfunction

function Towers takes unit u returns boolean
    //Copy and paste this if statement and change the rawcode for every tower you want this to work for.
    if GetUnitTypeId(u) == 'h009' then
return true
    endif

    return false
endfunction


//===========================================================================
function SelectTowerConditions takes nothing returns boolean
    return Towers(GetTriggerUnit())
endfunction

function AddSpecialEffectPlayer takes player p, string modelName, real x, real y returns effect
    if GetLocalPlayer() == p then
        return AddSpecialEffect(modelName, x, y)
    endif
    return null
endfunction

function SelectTowerActions takes nothing returns nothing
    local player p = GetTriggerPlayer()
    local unit tower = GetTriggerUnit()
    local real range = GetUnitDefaultAcquireRange(GetTriggerUnit())
    local integer amount = R2I(range/1.5)
    local real angle = 0.0
    local real increment = 360.0/25
    local real x = GetUnitX(tower)
    local real y = GetUnitY(tower)
    local real x2
    local real y2
    local effect array e
    local integer i = 0
    local integer i2 = 0
    loop
        set x2 = x+range*Cos(angle*bj_DEGTORAD)
        set y2 = y+range*Sin(angle*bj_DEGTORAD)
        set e[i] = AddSpecialEffectPlayer(p, EffectString(), x2, y2)
        set angle = angle + increment
        set i = i+1
        exitwhen i == amount
    endloop
    loop
exitwhen GetWidgetLife(tower) < 0.2 or IsUnitSelected(tower, p) == false
        call TriggerSleepAction(Delay())
    endloop
    loop
        call DestroyEffect(e[i2])
        set e[i2] = null
        set i2 = i2+1
        exitwhen i2 == i+1
    endloop
endfunction

//===========================================================================
function InitTrig_SelectTower takes nothing returns nothing
    set gg_trg_SelectTower = CreateTrigger()
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(0), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(1), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(2), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(3), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(4), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(5), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(6), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(7), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(8), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(9), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(10), true)
    call TriggerRegisterPlayerSelectionEventBJ(gg_trg_SelectTower, Player(11), true)

    call TriggerAddCondition(gg_trg_SelectTower, Condition(function SelectTowerConditions))
    call TriggerAddAction(gg_trg_SelectTower, function SelectTowerActions)
endfunction

I made a trigger "SelectTower" and changed it to custom txt.
 
Last edited:
Level 7
Joined
Oct 14, 2008
Messages
340
k first.. change:
JASS:
return "Doodads\\Cityscape\\Props\\MagicRunes\\MagicRunes"

to:
JASS:
return "Doodads\\Cityscape\\Props\\MagicRunes\\MagicRunes.mdl"

and what line does your error show up on? like which line is highlighted?

Edit:
i tried out your magic rune effect, it doesn't seem to show up.. for some reason most doodads won't o_O
try finding a special effect in the buffs/abilities/missile category, they work better.

AAAND another thing.. I'm not sure why but this code constantly creates effect rings until you deselect the unit.. causing lag, I'd try to figure this out but I gotta go.. tall cans are calling my name.

lol, once again edit: quickly found out why the lag was happening.. retarded calculations.
change:
JASS:
    local integer amount = R2I(range/1.5)
    local real angle = 0.0
    local real increment = 360.0/25

to:
JASS:
    local integer amount = R2I(range/10)
    local real angle = 0.0
    local real increment = 360.0/(R2I(range/12))
 
Level 9
Joined
Aug 1, 2008
Messages
453
K thanks, I have 3 questions

1. this isn't that important but is there a way to stop people from clicking on the same tower over and over cause lag?

2. How would i do the range check if a unit casts an ability instead of clicking on it. Would be nice.

3. How do i add the extra towers?
JASS:
//Lvl 1 Archer Tower
    if GetUnitTypeId(u) == 'h00I' then
return true
    endif
    return false

//Lvl 2 Archer Tower
    if GetUnitTypeId(u) == 'h00A' then
return true
    endif
    return false

//Lvl 3 Archer Tower
    if GetUnitTypeId(u) == 'h00B' then
return true
    endif
    return false

//Lvl 4 Archer Tower
    if GetUnitTypeId(u) == 'h00C' then
return true
    endif
    return false

I had that as my coding. It came up with no errors, just it didn't do anything. Only the first section of the Coding worked. If you could help me with these questions it would be a great help. You also could upload this spell to the Spell Section on the hive. I bet a bunch of other people would find this as a great help.

{EDIT}
*Bump*
 
Last edited by a moderator:
Level 8
Joined
Nov 9, 2008
Messages
502
Halarious. I'm actualy making this in GUI right now!

Will edit and upload when I finish.

EDIT:
Here we go. VERY simple trigger.

  • Untitled Trigger 003 Copy
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to range
    • Actions
      • Set q[1] = (Position of (Triggering unit))
      • For each (Integer A) from 1 to 12, do (Actions)
        • Loop - Actions
          • Set q[2] = (q[1] offset by (Current acquisition range of (Triggering unit)) towards ((Real((Integer A))) x 30.00) degrees)
          • Special Effect - Create a special effect at q[2] using Abilities\Spells\Other\Monsoon\MonsoonBoltTarget.mdl
          • Special Effect - Destroy (Last created special effect)
          • Custom script: call RemoveLocation(udg_q[2])
      • Custom script: call RemoveLocation(udg_q[1])
I used Channel as dummy instant cast ability and the cool monsoon model for animation.

If you want more points to show a smoother circle just increase the size of integer A, divide 360 by max of A and change the angle offset to this number.

EDITED... trigger because you don't need a unit type check. This trigger is so simple! Almost plug and play! Just change the ability! The rest is up to you
 
Last edited:
Level 40
Joined
Dec 14, 2005
Messages
10,532
For the love of god, use a loop to make the events, Maximilianx.

Also, GetWidgetLife(tower) < 0.2 - that's an interesting number. Haven't seen it used before for such a purpose.

Also also, this desyncs:

JASS:
function AddSpecialEffectPlayer takes player p, string modelName, real x, real y returns effect
    if GetLocalPlayer() == p then
        return AddSpecialEffect(modelName, x, y)
    endif
    return null
endfunction

JASS:
//Don't go too low with this. 0.1 is the lowest.
I'd be interested in knowing why you say this as well.
 
Level 7
Joined
Oct 14, 2008
Messages
340
0.1 because it's used as a sleep action in a loop, and you wouldn't want the check to be happening a gazillion times in any given fraction of a second..

used 0.2 hp because i heard somewhere that a unit is dead when it's hitpoints reach somewhere around 0.2, don't remember the exact number, but this is what I use instead of isunitalive.. and it works just fine.

and are you sure localized effects cause desyncs?

Oh, and @ toofless.. that is a simple trigger.. and it is GUI, but I wouldn't have spent the time on mine if i thought he wanted something that simple.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
0.1 because it's used as a sleep action in a loop, and you wouldn't want the check to be happening a gazillion times in any given fraction of a second..
Waits are actually pretty slow, so no. It can't even happen fast enough for you to notice a speed drop. In fact, even a timer running at maximum speed is pretty unnoticeable by itself.

used 0.2 hp because i heard somewhere that a unit is dead when it's hitpoints reach somewhere around 0.2, don't remember the exact number, but this is what I use instead of isunitalive.. and it works just fine.
.405, but you shouldn't care. Units that are dead have 0 life unless you are silly enough to change it.

and are you sure localized effects cause desyncs?
Yes, as they offset the heap for certain players only.

And they say there are no benefits of GUI over JASS...
With reason.
 
Level 7
Joined
Oct 14, 2008
Messages
340
Shendoo, there only needs to be one "return false" ..and it goes after all of the if then statements.

and why would local effects cause desyncs when you can add things like weather, texttags, change multiboard items etc. without a desync?
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
lol you guys are arguing over the stupidest things..
Is it stupid when that line kicks every other player in your game because it's badly thought out?

Offtopic: Why are all the icons all messed up? it shows like a hammer for all the icons on the forums..
I think it's supposed to be funny. At least, that's what they say.
 
Level 8
Joined
Nov 9, 2008
Messages
502
Why would I spend 30 minutes to write a trigger in jass when i can create a trigger to do such a simple thing in 2 minutes?

EDIT: You are a fool! That's why icons are different.
 
Level 13
Joined
May 11, 2008
Messages
1,198
i guess i haven't really thought much about acquisition range, i figure it's mostly for chasing after units. why would towers have a higher acquisition range than attack range? they can't move like units can...

yeah as far as i can tell all towers have acquisition range and range as the same. you could make the acquisition range shorter i guess but that would be weird. making it longer than the range i would think would be glitchy.

i'm not sure what the original poster is looking for. you want a number to appear next to it? or what? range is shown in the unit data section of the screen when you mouse over the weapon icon of the unit. are you saying you want that information on the battlefield next to the unit?

toofless has the solution so i guess i'll just look at that.
 
Level 8
Joined
Nov 9, 2008
Messages
502
Ye he wanted an effect like in Enfo's it shows the range of your unit by creating some effects on the ground in a circle.

I heard somewhere range cannot exceed acquisition range. Don't know if that's true and too tired to open WE right now.

I guess if you set acquisition range higher than range possibly tower won't change target if current target >range and <acq. range. Will just wait for target to either come back in range or exit acq. range. Dunno :)
 
Status
Not open for further replies.
Top