• 🏆 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!

[JASS] Problem with the training cues of doom

Status
Not open for further replies.
Level 17
Joined
Apr 13, 2008
Messages
1,597
Hiya. I have two major problems:

1.) I can't refer to the
"canceling research/training by clicking on the training cue"
event. It's not an order and after some googling I found out that it's not possible.
- Is there a workaround?

I made myself some kind of a workaround (or is it a walkaround?) but I found another problem there:
2.) I don't know how to refer to the unit/tech currently under training.
Would someone please help me out?
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
1) How about putting a "Unit is issued an order" event and under conditions check if it is cancel research/training?

2) I would detect the start of the research/training and always keep track of the last one, if that was not what you meant, give me more details on the situation.
 
Level 17
Joined
Apr 13, 2008
Messages
1,597
1)
As I said, the cancel research/training has nothing to do with the canceling by clicking on the cue event. It is not registered as an order.

2) I want to get the unit/tech currently in training / research, because when someone clicks on the freaking cue it doesn't register as an order so I won't know if the training / tech was canceled.

I want to create a function like this:
When a research order is issued my function will be executed.
It should check every 0.25 seconds if the research is still in progress or not. If it is not in progress then that would mean the player canceled the research by clicking on the cue icon.
GetResearched() does not give you the current tech in research.
 
Level 17
Joined
Apr 13, 2008
Messages
1,597
Well, I guess if there was a way to solve this someone would have helped me by now. Another walkaround would be to check the building's animation, but I can't find a function for that either, so it looks like WE vs me - 3:0. Thanks for your time though.
I have to go with an ugly, long, complicated solution instead of this. I'm a sad mapper :(
 
Last edited:
Level 3
Joined
Oct 31, 2007
Messages
30
That is exactly what that is saying. You have to -save- it for each building capable of teching/training.

EDIT: Based on something like this
JASS:
function Trig_Untitled_Trigger_002_Actions takes nothing returns nothing
    set udg_CurrentTech[GetUnitUserData(GetTriggerUnit())] = GetResearched()
endfunction

//===========================================================================
function InitTrig_Untitled_Trigger_002 takes nothing returns nothing
    set gg_trg_Untitled_Trigger_002 = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Untitled_Trigger_002, EVENT_PLAYER_UNIT_RESEARCH_START )
    call TriggerAddAction( gg_trg_Untitled_Trigger_002, function Trig_Untitled_Trigger_002_Actions )
endfunction

Btw, have you tried GetUnitCurrentOrder()? I'm not sure if that function works.
 
Level 17
Joined
Apr 13, 2008
Messages
1,597
No, a few post earlier I said why I need the current research:
I want to create a function like this:
When a research order is issued my function will be executed.
It should check every 0.25 seconds if the research is still in progress or not. If it is not in progress then that would mean the player canceled the research by clicking on the cue icon.
My map works with 7 kind of resources and each time the player would cancel the research by clicking on the stupid cue the player would lose resources.

There are other ways to make sure the player won't lose resources but that would need more cpu/memory usage or it would look much uglier ingame.

Edit: oh, and forgot to mention:
Of course I tried GetUnitCurrentOrder(), it always says 0.

Edit2: And by the way you wouldn't need global variables just to do that. You can simply set the building's custom unit value to the tech's ID.
 
Level 3
Joined
Oct 31, 2007
Messages
30
"current research" sounds more like what the building is actually researching, than the research queue. Sorry for the misunderstanding.

But then:
There is no way to refer to queued research or training orders.

You could however only substract the resources when the order reaches the "is being worked on" status. (And reset gold and lumber to the contents of the corresponding variables every 0.25 secs.)

Edit2: And by the way you wouldn't need global variables just to do that. You can simply set the building's custom unit value to the tech's ID.
Only if that is the only thing you want to use the custom value for.
 
Level 17
Joined
Apr 13, 2008
Messages
1,597
1.) No problem, my english is not 100% perfect, sadly, it might have been my poor explanation.
2.) I don't understand what you mean. By "is being worked on" do you mean it becomes first in the cue and the progress bar starts to fill?

I made my buildings so they only have 1 cue slot, so everything starts as being worked on.

When the player orders another research the current one gets canceled, a trigger will extract the previous research's ID from the building's custom value and gives back the resources. When the player presses cancel (or escape) the tech will be canceled and resources will be given back.

My plan was this to walk around the canceling by clicking on the cue problem:
When the player starts research I check every 0.xx seconds if the current research is not null. If it would be null, I would give back the resources.

3.) Right. :p
 
Level 5
Joined
Oct 27, 2007
Messages
158
Too bad, you can use all queue slots and still be able to make this work. You're wrong that orders are not involved. The problem with queuing units is that the event will only fire for the unit that actually is starting to train. So queued ones don't fire the event. The solution is to have an event that checks for raw orders. A unit build order is nothing more than an order with the raw unit type id as argument. Look below for the events and how to use.

JASS:
function Trig_Cancel_Actions takes nothing returns nothing
    local eventid e = GetTriggerEventId()

    if e == EVENT_PLAYER_UNIT_ISSUED_ORDER then // This catches any queueing of units/researches
        // Order ID 851976 is issued when you click cancel or press escape when something is queued.
        // You only need to catch add to queue orders so skip that order ID.
        // The reason why is because the cancel events will catch all user cancel interactions.
        // And clicking on a queued icon isn't interpreted as an order.
        if not (GetIssuedOrderId() == 851976) then
            call DisplayTextToPlayer(user, 0, 0, GetUnitName(GetOrderedUnit()) + " is issued an order.")
            call DisplayTextToPlayer(user, 0, 0, "Issued order is " + GetObjectName(GetIssuedOrderId()))
        endif
    // These cancel events will cancel requested queue where the user will press escape, click cancel or click on the queued icon.
    elseif e == EVENT_PLAYER_UNIT_TRAIN_CANCEL then
        call DisplayTextToPlayer(user, 0, 0, GetObjectName(GetTrainedUnitType()) + " cancelled.")
    elseif e == EVENT_PLAYER_UNIT_RESEARCH_CANCEL then
        call DisplayTextToPlayer(user, 0, 0, GetObjectName(GetResearched()) + " cancelled.")
    elseif e == EVENT_PLAYER_UNIT_UPGRADE_CANCEL then
        call DisplayTextToPlayer(user, 0, 0, "An upgrade is cancelled.")
        // Luckily upgrades can only be qeueued as one, so not getting the cancelled upgrade is not a problem.
        // You already got the upgrade with the issued order event.
    endif
    set e = null
endfunction

//===========================================================================
function InitTrig_Cancel takes nothing returns nothing
    local trigger t = CreateTrigger()

    call TriggerRegisterPlayerUnitEvent(t, user, EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
    call TriggerRegisterPlayerUnitEvent(t, user, EVENT_PLAYER_UNIT_TRAIN_CANCEL, null)
    call TriggerRegisterPlayerUnitEvent(t, user, EVENT_PLAYER_UNIT_RESEARCH_CANCEL, null)
    call TriggerRegisterPlayerUnitEvent(t, user, EVENT_PLAYER_UNIT_UPGRADE_CANCEL, null)
    call TriggerAddAction(t, function Trig_Cancel_Actions)
    set t = null
endfunction

The only thing you still need to do know is make a custom unit queue. This is really easy to setup using arrays for each unit that has a queue. With the event you can simply fill and remove elements from the queue. The nice part is that you can actually remove a specific queued type, if the user pressed on a specific queued icon of a unit type.

ps. I used the order ID because there is no clear order string where you can check against. And yes I tested these events myself and it works for queued stuff. And if there are more non target orders that don't queue anything, then simply check for and ignore those orders. And not to forget this prevents polling. You should avoid to poll wherever you can.
 
Status
Not open for further replies.
Top