Ticket #548 (closed task: fixed)
GUI should give feedback when training queue entry is blocked
| Reported by: | Philip | Owned by: | |
|---|---|---|---|
| Priority: | Nice to Have | Milestone: | |
| Component: | Core engine | Keywords: | simple, review |
| Cc: |
Description
When a training queue contains a item at the front that hasn't started yet, and the player doesn't have a high enough population limit to start training it, it won't start training. Currently the player is never notified about that - the queue looks normal, with no indication the player needs more houses (or more corpses). We need some kind of notification (I don't know what - maybe a message in the tooltip in the training queue? and/or a message sent to the player's screen? and/or make the population counter flash red? etc).
Attachments
Change History
comment:1 Changed 3 years ago by fcxSanya
- Keywords simple, review added; simple removed
I implemented following logic: When training queue can't reserve population slots, it sets trainQueueBlocked flag in player object. When updatePlayerDisplay function in session.js updates resource counters it also calls new blinkPopulationCounter function, which checks current player's trainQueueBlocked flag. If flag is set this function starts timer for blinkPopulationCounterTick function, which change population counter's text color from black to red and back until trainQueueBlocked will change to false. Training queue change trainQueueBlocked flag to false when it can continue training or when it is emptied.
This is my first diff for 0 A.D. with more than one line of code, so it probably have some issues (not optimal implementation, wrong files for my functions, some bugs etc.). Any criticism is welcomed :)
comment:2 follow-up: ↓ 4 Changed 3 years ago by Philip
- Keywords simple added; simple, review removed
Thanks, looks good so far :-)
I think the timing code could be simplified a lot. Instead of using setTimeout, in session.js's onTick just do something like:
if (isTrainingQueueBlocked && (Date.now() % 1000) < 500)
getGUIObjectByName("resourcePop").textcolor = "255 0 0";
else
getGUIObjectByName("resourcePop").textcolor = "0 0 0";
where isTrainingQueueBlocked is a global set by updatePlayerDisplay. (Not tested but I hope this is about right...)
If the player only has one training queue and it is blocked, and then the building is destroyed or captured, what will happen? It looks like UnBlockTrainQueue will never get called, so the population counter will continue flashing forever.
Maybe we could add something like Player.prototype.OnTurnStart = function() { this.trainQueueBlocked = false; } and then remove the explicit UnBlockTrainQueue. Then it will be considered unblocked unless anybody called BlockTrainQueue during that turn. Hopefully that's an adequate way of handling this.
The code should probably say TrainingQueue instead of TrainQueue, for consistency.
comment:3 Changed 3 years ago by Philip
Oh, I'm wrong about the OnTurnStart thing - the training queues only operate on a timer, not every turn, so it won't get correctly set every turn. Need a different solution, then.
comment:4 in reply to: ↑ 2 Changed 3 years ago by fcxSanya
- Keywords simple, review added; simple removed
Replying to Philip:
I think the timing code could be simplified a lot. Instead of using setTimeout, in session.js's onTick ...
I used your version.
If the player only has one training queue and it is blocked, and then the building is destroyed or captured, what will happen? It looks like UnBlockTrainQueue will never get called, so the population counter will continue flashing forever.
I added UnBlockTrainingQueue call in the OnOwnershipChanged function.
The code should probably say TrainingQueue instead of TrainQueue, for consistency.
Done.
comment:5 Changed 3 years ago by Philip
Seems to work fine, and I can't find or think of any cases where it might break, so I think this is good. Thanks!
