• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Stealing money trigger

Status
Not open for further replies.
Level 7
Joined
Jul 25, 2008
Messages
292
As often happens, I know exactly what I want a trigger to do, but am having trouble figuring it out.


How would you guys set up a trigger, where if one 'unit type', was in range of a unit from a second 'unit type' (both specific unit types that can be built, so trigger can not refer to specific on map units, but must refer to the type in whole), every 60 seconds of those two units being in range (continuous) take 60 gold from owner of second 'unit type' and give to owner of first 'unit type'.
 
Level 22
Joined
Aug 27, 2013
Messages
3,973
Pick every unit in the map with condition that the picked unit is your unit type, i think that's possible. I can't check it and give the trigger right away as i don't have WE right now. Use the ITE and check the range with real comparison. I guess you'll need two triggers for this, one is to check whether the units are in range, the other one is to check every 60 seconds and take 60 gold. Hope it's understandable.
 
Event - Every 1.00 seconds of game time

Set TempGroup = all units in playable map
Pick all units in TempGroup
If unit is first type then
Set picked unit = U1
If unit is unit type of other type then
Set picked unit = U2
If owner of U1 is an enemy of U2 then
Set Loc1 = position of U1
Set Loc2 = position of U2
Set Distance from Loc1 to Loc2 = D
If D is less than 800 then
Set T = T+1
Else then
Set T = 0
If T = 60 then
Remove 60 gold from owner of U2
Add 60 gold to owner of U1
Set T = 0
RemoveLocations Loc1 and Loc2
Destroy Unit Group

Someone will certainly point out that this will only work if there is only one of each unit in the game. I didn't want to get into that first because it is a bit complex and I wanted to get you the basics of running a check once.

To account for multiple units of either type and possibly owned by multiple players you will need to index them. One way to do this might be with an integer array.

So you would create an integer variable (i). Then set i = i +1, so that we count ever time this function runs. Then Set Picked unit = U1. That way we have all picked units of type 1 labeled with variables. Then do the same with i2. Set i2 = i2 + 1. Then Set U2[i2] = picked unit. Then you would need to check each integer i against each interger i2 for distance. We can do this by looping. You would use a loop functions command. So for each (integer A) from 0 to i do the following: For each integer B from 0 to i2 do the following. Then we do this part:

If owner of U1 is an enemy of U2 then
Set Loc1[Integer A] = position of U1[integer A]
Set Loc2[integer B] = position of U2[integer B]
Set Distance from Loc1[Integer A] to Loc2[integer B] = D
If D is less than 800 then

Now we know all units of type 1 in range with a unit of type 2
All that is left is counting to 60 for each set. We need a new index for this.
Let's call it 'm' for match. But we don't want to overwrite it each time.
We want a match to stay a match until the go more than the distance apart.


set m = (

Set T[m] = T[m] + 1
Else then
Set T[m] = 0
If T[m] = 60 then
Remove 60 gold from owner of U2[integer A]
Add 60 gold to owner of U1[integer B]
Set T[m] = 0
Remove Locations Loc1[integer A] and Loc2[integer B]
Destroy Unit Group


Nope I lost it. I can't think of how to index it exactly. I'm sorry. Someone can fill in the rest. This is the basic idea though.

Another way might be to use the event "A unit comes within 800 of a unit"
Then check for types. Then start the time. If it reaches 60 then swap the gold.
If the units get farther away than 800 turn off the timer and reset.
When I say timer, I mean a looping trigger dynamically indexed for time, not an actual timer.

Pick every unit in the map with condition that the picked unit is your unit type, i think that's possible.
It is possible but it creates a non-removable leak. Just pick all units and only do actions for picked units of type.
 
So the
  • Unit Group - Pick every unit in (Units in (Playable map area) matching ((Unit-type of (Triggering unit)) Equal to Footman)) and do (Actions)
    • Loop - Actions
line leaks?

well, if so we can just replace it with ITE, can't we?

Yes, that line creates 2 group and only one would be removed by bjwantRemoveGroup = true. But, yes, you are right we can just you the if/then/else.
 
Level 11
Joined
Dec 19, 2012
Messages
411
If i understand you correctly, you want

-unit type A take unit type B 60 gold of within X range
-check every 60 seconds.

For such trigger, it would be a heavy operation to handle since you have to loop through all units of type A.


What I would do is, if possible, I would try to avoid (Pick every unit in playable map area) and add each unit type A manually to group A.

Next, every 60 seconds, pick units in group A, and pick every units within X range of picked unit (nested group), check if unit type B near picked Unit (refers to a unit in group A), if so, just take 60 gold from unit type B.

This would applies to all units of type A, and also enable multiple units of type A to take 60 gold from a specific of unit type B.
 
If i understand you correctly, you want

-unit type A take unit type B 60 gold of within X range
-check every 60 seconds.

For such trigger, it would be a heavy operation to handle since you have to loop through all units of type A.


What I would do is, if possible, I would try to avoid (Pick every unit in playable map area) and add each unit type A manually to group A.

Next, every 60 seconds, pick units in group A, and pick every units within X range of picked unit (nested group), check if unit type B near picked Unit (refers to a unit in group A), if so, just take 60 gold from unit type B.

This would applies to all units of type A, and also enable multiple units of type A to take 60 gold from a specific of unit type B.

I think you mostly have it right.

I agree pick all units is really expensive and this way might be a quite a bit better, but you need to make sure the units stay inside the radius range of the other unit. So for example, the steal shouldn't work if the units cross paths and then one escapes range for 55 seconds, but the thief unit catches the other unit at 59 seconds and then steals the money at 60 seconds. He should have to stay within range the whole time and we would need to be checking for this. I recommended a 1 second periodic event, but there may be a way to check to make sure the unit stays within range without a periodic. For example an event that a unit leaves a region.... no, that doesn't work, you would still need to be creating a region periodically around one of the units. I think the best way is just to have the periodic event check a distance variable. So the fewest functions occur.
 
Level 7
Joined
Jul 25, 2008
Messages
292
I was trying to avoid it, but would it make it less complicated if every unit type B was static, and within a region, so instead it was simply checking that Unit type A was within said region for 60 seconds? It would still need to also detect the ownership of both units though, because it would need to know who to take the money from...
 
Level 11
Joined
Dec 19, 2012
Messages
411
Making unity type B static wouldn't make the whole trigger less complicates as long as you need to check for every unit type A and distance between each unit type A and unit type B is changing over time.

To detect ownership of both unit, aren't there already present a function which able to get the owning player of a unit in GUI?
 
Level 12
Joined
May 22, 2015
Messages
1,051
How many of each kind of unit are there? You might be able to just loop over unit type A and check their distance to unit type B. You'd need to have a unit group for each unit type and add units to those groups as they enter the map. If either group is small, then it will run fast (it's only a problem if both groups are big).

In order to keep track of how long a unit has been in range, I think you need to use a hashtable. Key1 would be whichever unit of type A and key2 would be whichever unit of type B and you'd store an integer equal to the number of seconds - to do this, while looping over them, you just use the key of loop 1 unit for key1, use the key of the loop 2 unit for key2, and add 1 to the value found with those keys if they are in range. If the number is 60, reset to 0 and steal the gold. If they are not in range, reset the value to 0.

It's a little complicated, but it would get the job done.
 
Cant you just create an autocast ability that has a cd 60 sec and does nothing,and then create a triigger that gives the caster 60 g and removes 60 g from the other unit.

You set a variable:
Set enemygold = (current enemy gold) - 60 //this is just an example

Autocast could get interrupted by spells like stun. He wants to make sure that the units are within range the whole time. The autocast idea is interesting but it could get bugged.
 
Level 11
Joined
Dec 19, 2012
Messages
411
Using the buff from an aura for checking the distance is pretty neat idea, then you could avoid heavy group functions and distance checking function.

But, that would leave a buff icon from the aura, which I'm not sure if Hell_Raider wouldn't matter about the buff icon.

If unit type A and unit type B are both non-static units, a periodic timer event need to be used for updating the position of each dummy unit for each units of type A (or type B, either one)

If unit type B is static, then updating the position of each dummy unit is not needed (just place dummy unit at the position of unit type B).


I believe we've got enough ideas for him, all depends on which method he gonna use.
 
I believe we've got enough ideas for him, all depends on which method he gonna use.

Not really. No one ever game him the last bits of my idea. From what I read, no one actually came up with a complete working solution, except SAUS but then he needs to know how to use hashtables, which I doubt he does. Shucks, I don't even know how to use hashtables.

The only other idea i have is he could create an aura and dummy units(which have my idea above). Don't know about leaks though.
The leaks could be cleaned. I think this could work. It still needs dynamic indexing but it is a lot easier. If a unit gets the buff, then start counting, if the unit loses the buff then stop and rest. I wonder if you could make this purely in OE based off of pillage. If you could make a pillage aura with a 60 duration and an attack damage of 1, it might be possible. A combination of smart abilities and triggers could make this work really well.
 
Level 7
Joined
Jul 25, 2008
Messages
292
The dummy aura is a pretty great idea, especially because I could set all Unit B's to be of one type (for instance Ancient, and have them the only 'Ancient units') and that way I could probably keep it simple as if a unit is effected by X Aura for 60 seconds take gold from owner of effected unit and give it to owner of unit casting spell. I can't check this works until Sunday, and I'm not sure how I would set it up to do it every 60 seconds rather than only once (perhaps there is a way to pulse Auras, so it would simply force the trigger to repeat every time the aura is re-cast?).

I really do appreciate all of these suggestions, and any more that I get. I'll make sure to test out this option on Sunday and see how it goes :)
 
Status
Not open for further replies.
Top