• Check out the results of the Techtree Contest #19!
  • 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.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

[Trigger] How to detect harvesting.

Status
Not open for further replies.
Level 17
Joined
Jun 12, 2007
Messages
1,261
The title says it all.
How does one detect when a certain tree (summer tree, winter tree, village tree etc.) is being harvest for wood.
And how to detect when a unit deposits the wood at a town hall or lumber mill etc.

Also, are you able to edit the message that is show when a certain resource is deposited, cause I would like it not to be shown.
 
for the first part isnt "harvesting" an ability?
use unit uses an ability target is a destruclible blablabla
 
It's possible to detect it, but it's very hard (if you want the harvesters to be selectable / controllable)
It'll be smth like:

Event: Unit is issued any order
If: Order comparison - Issued order = harvest
Do:
w8 some time (time to harvest + distance between building where do you keep resourses / unit's speed)

Also, you'll have to make triggers for the cases if unit will recieve any other orders from players, like to stop harvestiong or to move to other location.
 
It's possible to detect it, but it's very hard (if you want the harvesters to be selectable / controllable)
It'll be smth like:

Event: Unit is issued any order
If: Order comparison - Issued order = harvest
Do:
w8 some time (time to harvest + distance between building where do you keep resourses / unit's speed)

Also, you'll have to make triggers for the cases if unit will recieve any other orders from players, like to stop harvestiong or to move to other location.

Ahh crap... I have tried looking for good solutions but it really seems that it's not possible... Not in GUI at the least..
Well I guess it's time to throw away this map and get back to the drawing board.. =:(
 
Hmm, yes it does reduce the hp of the destructible as far as I know. Could you give me a link?

I tried it but it doesnt work =(
Because Destructibles dont have custom values, and that is what is needed.
I will try to do it with some variable,
Getting back to you on it,,

EDIT:
You are fairly lucky my fellow mate ^^
It worked!
I cannot garuantee you that it does not contain bugs,
And i do not know how to ressurect trees,,
But you can now check when a destructible is attacked (!! WATCH! ATTACKED,, so when somebody attacks them, it also does the actions,, also things like Flame strike will trigger it.
(also other destructibles then trees are checked, like crates)

EDIT 2: I am now working on how to check if it is harvested!
 
I tried it but it doesnt work =(
Because Destructibles dont have custom values, and that is what is needed.
I will try to do it with some variable,
Getting back to you on it,,

EDIT:
You are fairly lucky my fellow mate ^^
It worked!
I cannot garuantee you that it does not contain bugs,
And i do not know how to ressurect trees,,
But you can now check when a destructible is attacked (!! WATCH! ATTACKED,, so when somebody attacks them, it also does the actions,, also things like Flame strike will trigger it.
(also other destructibles then trees are checked, like crates)

EDIT 2: I am now working on how to check if it is harvested!

Great thanks for helping me. ^^ Can't wait to see if it works.
 
Here is how to check if a destructible is a tree:
JASS:
function IsDesATree takes destructable a returns boolean
    local unit u=CreateUnit(Player(0),'ugho',GetDestructableX(a),GetDestructableY(a),0)
    if(IssueTargetOrder(u,"harvest",a)) then
       call RemoveUnit(u)
       set u=null
       return true
    endif
    call RemoveUnit(u)
    set u=null
    return false
endfunction
In this case(with default ids) creating a ghoul and ordering it to harvest the tree.
Unit id should be that of any unit with a harvest ability. The order string should be of the harvest ability the unit has.
 
Last edited:
Here is how to check if a destructible is a tree:
JASS:
function IsDesATree takes destructable a returns boolean
    local unit u=CreateUnit(0,'ugho',GetDestructableX(a),GetDestructableY(a),0)
    if(IssueTargetOrder(u,"harvest",a)) then
       call RemoveUnit(u)
       set u=null
       return true
    endif
    call RemoveUnit(u)
    set u=null
    return false
endfunction
In this case(with default ids) creating a ghoul and ordering it to harvest the tree.
Unit id should be that of any unit with a harvest ability. The order string should be of the harvest ability the unit has.

Check wether it is a tree? Is a good System though,,
Isnt needed anymore,, the harvest tree order string is 'smart' not 'harvest'
And since no other destructibles but trees can be harvested, there is no need
I found out how to do it, Now all i have to do is make it multi-race available,,\

EDIT: Ok i got some problems, and i gotta go now,,
But i will try to fix it for you!
 
Last edited:
Isnt needed anymore,, the harvest tree order string is 'smart' not 'harvest'
And since no other destructibles but trees can be harvested, there is no need
I found out how to do it, Now all i have to do is make it multi-race available,,

No, smart is an order that calls some sort of a function that checks for available orders, selects the most suitable and orders it to the unit. Smart is the right mouse button(it does a lot of things move, attack, patrol, harvest, pick up item and etc). If a unit can attack a tree but doesn't have a harvest based ability right clicking on a tree ( smart ordering it) would return true as well.
Harvest is the harvest order ;)
It can be done in GUI, but checking if the result from an issued order is true or false cannot - so a custom script is necessary.

It was intended to supplement the thing you did, as you said it fired up for non harvestable destructables or generally give anyone the idea how he/she can check that ;)
I am just too lazy to post complete code.
 
No, smart is an order that calls some sort of a function that checks for available orders, selects the most suitable and orders it to the unit. Smart is the right mouse button(it does a lot of things move, attack, patrol, harvest, pick up item and etc). If a unit can attack a tree but doesn't have a harvest based ability right clicking on a tree ( smart ordering it) would return true as well.
Harvest is the harvest order ;)
It can be done in GUI, but checking if the result from an issued order is true or false cannot - so a custom script is necessary.

It was intended to supplement the thing you did, as you said it fired up for non harvestable destructables or generally give anyone the idea how he/she can check that ;)
I am just too lazy to post complete code.

Jass is no option, custom scripts are fine.
So one more time: I need a trigger that will run as soon as a tree is harvested, then I need to check what kind of tree it is.
Depending on the tree the unit will get an custom value, lets say summer tree is value 1 while barrens is value 2.
When the 'lumber' is returned I want to cancel the deposit and the message showing the lumber and instead based of the custom value of the unit store a value to the fitting integer and also show a message.

My main problem is detecting when a resource is harvested and when it's deposited. xD
 
Jass is no option, custom scripts are fine.
So one more time: I need a trigger that will run as soon as a tree is harvested, then I need to check what kind of tree it is.
Depending on the tree the unit will get an custom value, lets say summer tree is value 1 while barrens is value 2.
When the 'lumber' is returned I want to cancel the deposit and the message showing the lumber and instead based of the custom value of the unit store a value to the fitting integer and also show a message.

My main problem is detecting when a resource is harvested and when it's deposited. xD

I got your problem, i fixed it, but does it need to include Night-Elfs?
Cause Night elves dont damage trees, so that is a lot harder,,
Also, i got a little problem with when more units harvesting the same tree,,
Does it need to run when you GOT the lumber, or when you CUT it,,??
 
I got your problem, i fixed it, but does it need to include Night-Elfs?
Cause Night elves dont damage trees, so that is a lot harder,,
Also, i got a little problem with when more units harvesting the same tree,,
Does it need to run when you GOT the lumber, or when you CUT it,,??

As long as it works for peasants it's fine. :P Peons are the same so they count as well, but just worry about the peasants.

And well it does hardly matter I think, for example when a peasant has 7 lumber and it will deposit it, it will not deposit 7 lumber and show a +7 lumber income message.
But instead it will show 7 *resource value*. And the resource value should be based on the doodad it was harvesting.
So when it harvests for example summer tree the peasant will get a custom value of 1 indicating it is harvesting gold.
So basically when it's cut?

Also the deposits will have either like 99999999999999999 health aka they can't be destroyed unless you play for 10 hours or something.
Or a trigger will run when it's cut and set it's health to maximum again, depends on what is best. xD
 
As long as it works for peasants it's fine. :P Peons are the same so they count as well, but just worry about the peasants.

And well it does hardly matter I think, for example when a peasant has 7 lumber and it will deposit it, it will not deposit 7 lumber and show a +7 lumber income message.
But instead it will show 7 *resource value*. And the resource value should be based on the doodad it was harvesting.
So when it harvests for example summer tree the peasant will get a custom value of 1 indicating it is harvesting gold.
So basically when it's cut?

Also the deposits will have either like 99999999999999999 health aka they can't be destroyed unless you play for 10 hours or something.
Or a trigger will run when it's cut and set it's health to maximum again, depends on what is best. xD

Ok,, then i got no problem ^^ otherwise i would have to change the whole thing,,
Would it be ok if like: when it cuts, it will get one custom value extra, and it check immediately what kind of tree it is??
 
well for trees as long as wisps aren't harvesting they get damaged with each attack. i think it's 2 per hit with ghouls and one per hit with peons/peasants. so do like a tree is damaged and condition dmg ammount equal or less than 2. but i'm not sure if you can do tree is damaged as an event. oh whoops silly me we've reached the second page and someone already answered what i said.
 
Do you know how to check how much lumber the peasant has (already)?
That could be the key to the harvest-detecting system =)

P.S. Mana didnt work, the ability doesnt extract mana when i set the mana cost to 1 or 2 =S

Well it should be stored somewhere.. but I don't know how to get the value back..
My idea was every time a doodad gets attacked and the unit is worker then just add 1 mana, but since there is no such event...
 
Well it should be stored somewhere.. but I don't know how to get the value back..
My idea was every time a doodad gets attacked and the unit is worker then just add 1 mana, but since there is no such event...

Yeah, but then the problem stays about multiple units around one tree.
If that problem wouldnt be there, the system would be done a long time ago xD


EDIT:
We are making Progress! It is almost done,, ^^
Little bug fixing now,,
 
Last edited:
OMG OMG OMG!!
I got it!!
Uses 1 custom ability, 2 triggers and 4 variables ^^
Ill post it here for you, there is some lagg somewhere, somehow, and i dont know if it is bug free, so you need to test it yourself,,

Ill post it in a few minutes,,

Ok,, The lagg at the first harvesting is really bad:cred:
But im still working on it!
 

Attachments

OMG OMG OMG!!
I got it!!
Uses 1 custom ability, 2 triggers and 4 variables ^^
Ill post it here for you, there is some lagg somewhere, somehow, and i dont know if it is bug free, so you need to test it yourself,,

Ill post it in a few minutes,,

Ok,, The lagg at the first harvesting is really bad:cred:
But im still working on it!

Great, I'll check it out Saturday when I have some free time on my hands, I'm going to sleep now and well, me issa busy man.
Keep improving it, I think the lag is caused by leaks, do you fix them? In any caseI can fix them myself aswell. ^^

Thanks for so far! =:D
 
:/ I'm looking for a similar system xD. For mine it's a bit more complicated though. I'm making an RTS and each race has different resource types. I have it all planned out but I need a harvesting system for debris :/ I got a system semi working, however, if you tell 2 guys to harvest at 2 dif times before the first one begins harvesting, the first one won't harvest until the second unit starts harvesting.

I have it set so that when a worker uses smart on the debris, it waits until it is damaged then adds it to a unit group. In a second trig it gives +1 ability level (that counts the resources carried) until it reaches 20 and then drops it off at the building. Then I have a 3rd trig for when the worker moves, attacks, stops or w/e that removes him from the group.
(Idk if any of this will help you make it but I thought I'd post it just in case)
 
Well,, im first finishing Airandius' system, then i will help you =)
And i didnt fully understand you actually,,
Can you explain it a little bit more? Maybe some more 'enter' s? :grin:
So,, as soon as this sys is done, i will take a look for you =)
 
The whole system is different and I think I have my own solution, so no worries.

Actually, now it works but I need to detect when a debris dies xD
There is an event, but it only picks up on the first 64 destructibles so I can't use that.
 
The whole system is different and I think I have my own solution, so no worries.

Actually, now it works but I need to detect when a debris dies xD
There is an event, but it only picks up on the first 64 destructibles so I can't use that.

Pick every destructible in Entire map, and do:
If life of picked destructible equal to 0
Then: Your actions,,
Else: Your actions,,

Maybe?
 
Well, if you want to check wether a tree is damaged, i got you the system!
But if you also want to check which unit, dont come to me! =P

Found out how to make it usable more then one time for a unit :grin:
Still not killed the lagg, but i will :mwahaha:
Added little drop-off point, which immediately converts the custom value to lumber =)

Map not updated yet!
Tomorrow i will!!
 
Tacking on more stuff to my already existing timed events wouldn't really change the number of calculations/memory usages. It wouldn't much matter putting it in a separate trigger or not.

Also, I'm not using harvest in any way. I'm targeting debris, not trees. It works differently. They also don't need to hold the resource in this case.
 
Well, if you want to check wether a tree is damaged, i got you the system!
But if you also want to check which unit, dont come to me! =P

Found out how to make it usable more then one time for a unit :grin:
Still not killed the lagg, but i will :mwahaha:
Added little drop-off point, which immediately converts the custom value to lumber =)

Map not updated yet!
Tomorrow i will!!

It's great to hear there is progress. ^^ I rlly appreciate the help! =:D
 
Maybe someone can help?
I just DONT know where the lagg comes from =S
Here are the triggers:
  • Tree Check
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • Custom script: local group udg_zz_Destr_Group2
      • Set zz_Destr_Array = 1
      • Destructible - Pick every destructible in (Entire map) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked destructible) is dead) Equal to False
              • ((Picked destructible) is invulnerable) Equal to False
              • Or - Any (Conditions) are true
                • Conditions
                  • (Substring((Name of (Picked destructible)), ((Length of (Name of (Picked destructible))) - 3), (Length of (Name of (Picked destructible))))) Equal to Tree
                  • (Substring((Name of (Picked destructible)), ((Length of (Name of (Picked destructible))) - 8), (Length of (Name of (Picked destructible))))) Equal to Tree Wall
            • Then - Actions
              • Set zz_Destr_Group2 = (Units within 135.00 of zz_Destr_Point[zz_Destr_Array] matching ((Current order of (Matching unit)) Equal to (Order(harvest))))
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in zz_Destr_Group2) Greater than 0
                • Then - Actions
                  • Unit Group - Pick every unit in zz_Destr_Group2 and do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ((Picked unit) is in zz_Destr_Group) Equal to True
                        • Then - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Custom value of (Picked unit)) Equal to 10
                            • Then - Actions
                              • Unit - Remove Harvest Check from (Picked unit)
                              • Unit Group - Remove (Picked unit) from zz_Destr_Group
                            • Else - Actions
                              • Unit - Set level of Harvest Check for (Picked unit) to ((Level of Harvest Check for (Picked unit)) + 1)
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • (Level of Harvest Check for (Picked unit)) Equal to 3
                                • Then - Actions
                                  • Unit - Set the custom value of (Picked unit) to ((Custom value of (Picked unit)) + 1)
                                  • Unit - Set level of Harvest Check for (Picked unit) to 1
                                  • Game - Display to (All players) the text: ((String((Custom value of (Picked unit)))) + wood!)
                                • Else - Actions
                        • Else - Actions
                          • Unit - Add Harvest Check to (Picked unit)
                          • Unit - Set level of Harvest Check for (Picked unit) to 2
                          • Unit Group - Add (Picked unit) to zz_Destr_Group
                • Else - Actions
            • Else - Actions
          • Set zz_Destr_Life[zz_Destr_Array] = (Current life of (Picked destructible))
          • Set zz_Destr_Point[zz_Destr_Array] = (Position of (Picked destructible))
          • Set zz_Destr_Array = (zz_Destr_Array + 1)
      • Custom script: call DestroyGroup(udg_zz_Destr_Group2)
And the order Check, to make it not use 'smart' but 'harvest'

  • Order Check
    • Events
      • Unit - A unit Is issued an order targeting an object
    • Conditions
      • (Issued order) Equal to (Order(smart))
      • Or - Any (Conditions) are true
        • Conditions
          • (Substring((Name of (Target destructible of issued order)), ((Length of (Name of (Target destructible of issued order))) - 3), (Length of (Name of (Target destructible of issued order))))) Equal to Tree
          • (Substring((Name of (Target destructible of issued order)), ((Length of (Name of (Target destructible of issued order))) - 8), (Length of (Name of (Target destructible of issued order))))) Equal to Tree Wall
    • Actions
      • Unit - Order (Triggering unit) to Harvest (Target destructible of issued order)
      • Game - Display to (All players) the text: (String((Current order of (Triggering unit))))
 

Attachments

First of all, that local will never be used, as the GUI if's will destroy the purpose for it.

Everytime an if condition is used in GUI it creates another function which returns true or false depending on the condition. The local is not accessible from here, since the if is calling the condition function...

Also, why does it lag?
Due to this (I may be wrong at the first point, but it is logical if its like I say), you destroy the local group at the end, but not the real one stored in the global inside the if.
So 1 group leak will be made everytime the trigger runs.

Additionally, picking all destructibles in the whole map is nothing you should toy around with, as the whole map could be huge, and the amount of trees is often far over a thousand, and it will also pick all destructables, even those which are not trees.
Imagine to pick thousand units on a map... It would also lag like hell.

Another issue: The substring check to see if the destructable is beginning on the type "tree" or "tree wall" will cause desyncs... You never thought of that different languages in wc3 has objects named differently, did you? So, the substring would be right for an English version of wc3, but not a German one for instance, resulting to "carry on with the trigger" for one person but not another => the 'fearsome' desync.
 
-Ok,, Yeah, i removed the local already (on my comp)
-Well,the lagg is really extraordinary,, it laggs for like 3 secs when the first unit ever
tries to cut, but after that, it doesnt lag anymore, not at all!

-You suggest using the GUI action: clear unit group?

-Maybe adding regions where the trees are? Check wether the amount of units who has 'harvest' is 1 or higher, and THEN pick every destructible?

-Damn! I didnt think of that! What do you suggest? I could add like 50 conditions, to check if the type is a tree (there are like 50 trees, understand what im saying?) but maybe there is an other way?

Well,, You really helped now =D,
Can you tell me what to do about it then??
 
Well, if the lag is extreme only once, its because wc3 has to initialise certain things and store them in the memory adress. For instance, when you create a unit of a certain type, it will lag the first time you create it, since wc3 hasnt registred a memory adress for that type before. Aftert that however, it wont lag since the type has been stored.

Using DestroyGroup works just perfectly and can be at the end of the trigger as you have done, now when you removed the local. Also, locals are not needed if you have a trigger running without any interruptions of waits. wc3 is using a trigger running stack which means that the first trigger in queue is ran, then the next one, then the next... So, if there are no waits, nothing in the current trigger will be lost when its ran.
Oh and, I dont know about Clearing the unit group, since it will not destroy the group you have there, only remove all the units from it. If you then assign a new group to that variable, the cleared group would be lost and leaks anyway.

Well, if the current order of a unit has the current order "harvest" it would be rather pointless to check if the unit has the ability as well. That point is fine.
For the tree filtering you could, for instance, change the life of the trees by +1 or -1 or whatever, in the destructable editor, and check the maxlife of the tree when it is picked. However, you will still have to check all the destructables in the playable map area.
 
@ Eleandor: You might be right, and i might be wrong, but still,, dont be so negative,,

@ Eccho: It might be laggin because of setting the life and position variables? Ill try setting them in an init-trigger,,

Max life of every tree in the map to 51,, trying:grin:

Checking if it has 'harvest' AND if it has the order of the unit is 'harvest' IS actually usefull,, if a unit has harvest, but is not ordered to harvest, or not harvesting,, it will still gain custom value, so i will have to check both
 
How about doing it like this:
Pick all units on the map of type (worker) and filter them by the current order.
If it is harvest, check distance between the unit and the target.
Should be a bit more efficient.
 
Status
Not open for further replies.
Back
Top