Merge lp:~widelands-dev/widelands/remove-anti-congestion-algorithm into lp:widelands
- remove-anti-congestion-algorithm
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 8936 | ||||
Proposed branch: | lp:~widelands-dev/widelands/remove-anti-congestion-algorithm | ||||
Merge into: | lp:widelands | ||||
Diff against target: |
1225 lines (+414/-446) 8 files modified
src/economy/flag.cc (+126/-255) src/economy/flag.h (+11/-20) src/economy/road.cc (+1/-2) src/economy/road.h (+3/-3) src/logic/map_objects/tribes/carrier.cc (+233/-134) src/logic/map_objects/tribes/carrier.h (+11/-9) src/logic/map_objects/tribes/worker.cc (+28/-22) src/logic/map_objects/tribes/worker.h (+1/-1) |
||||
To merge this branch: | bzr merge lp:~widelands-dev/widelands/remove-anti-congestion-algorithm | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Widelands Developers | Pending | ||
Review via email: mp+359294@code.launchpad.net |
Commit message
Remove the anti-congestion algorithm introduced in r8775 because it has too many bugs in it.
Description of the change
bunnybot (widelandsofficial) wrote : | # |
GunChleoc (gunchleoc) wrote : | # |
We can't start working on the desyncs without this branch, so I'm gonna merge.
@bunnybot merge
bunnybot (widelandsofficial) wrote : | # |
Continuous integration builds have changed state:
Travis build 4286. State: failed. Details: https:/
Appveyor build 4080. State: failed. Details: https:/
bunnybot (widelandsofficial) wrote : | # |
Refusing to merge, since Travis is not green. Use @bunnybot merge force for merging anyways.
Travis build 4286. State: failed. Details: https:/
bunnybot (widelandsofficial) wrote : | # |
Continuous integration builds have changed state:
Travis build 4293. State: passed. Details: https:/
Appveyor build 4086. State: success. Details: https:/
GunChleoc (gunchleoc) wrote : | # |
@bunnybot merge
Preview Diff
1 | === modified file 'src/economy/flag.cc' | |||
2 | --- src/economy/flag.cc 2018-09-04 15:48:47 +0000 | |||
3 | +++ src/economy/flag.cc 2018-11-26 06:43:43 +0000 | |||
4 | @@ -337,30 +337,7 @@ | |||
5 | 337 | } | 337 | } |
6 | 338 | 338 | ||
7 | 339 | /** | 339 | /** |
32 | 340 | * Called by workers wanting to drop a ware to their building's flag. | 340 | * Returns true if the flag can hold more wares. |
9 | 341 | * \return true/allow on low congestion-risk. | ||
10 | 342 | */ | ||
11 | 343 | bool Flag::has_capacity_for_ware(WareInstance& ware) const { | ||
12 | 344 | // avoid iteration for the easy cases | ||
13 | 345 | if (ware_filled_ < ware_capacity_ - 2) { | ||
14 | 346 | return true; // more than two free slots, allow | ||
15 | 347 | } | ||
16 | 348 | if (ware_filled_ >= ware_capacity_) { | ||
17 | 349 | return false; // all slots filled, no room | ||
18 | 350 | } | ||
19 | 351 | |||
20 | 352 | DescriptionIndex const descr_index = ware.descr_index(); | ||
21 | 353 | for (int i = 0; i < ware_filled_; ++i) { | ||
22 | 354 | if (wares_[i].ware->descr_index() == descr_index) { | ||
23 | 355 | return false; // ware of this type already present, leave room for other types | ||
24 | 356 | } | ||
25 | 357 | } | ||
26 | 358 | return true; // ware of this type not present, allow | ||
27 | 359 | } | ||
28 | 360 | |||
29 | 361 | /** | ||
30 | 362 | * \return true/allow if the flag can hold more wares of any type. | ||
31 | 363 | * has_capacity_for_ware() also checks ware's type to prevent congestion. | ||
33 | 364 | */ | 341 | */ |
34 | 365 | bool Flag::has_capacity() const { | 342 | bool Flag::has_capacity() const { |
35 | 366 | return (ware_filled_ < ware_capacity_); | 343 | return (ware_filled_ < ware_capacity_); |
36 | @@ -386,24 +363,13 @@ | |||
37 | 386 | capacity_wait_.erase(it); | 363 | capacity_wait_.erase(it); |
38 | 387 | } | 364 | } |
39 | 388 | 365 | ||
40 | 389 | /** | ||
41 | 390 | * Adds given ware to this flag. | ||
42 | 391 | * Please check has_capacity() or better has_capacity_for_ware() before. | ||
43 | 392 | */ | ||
44 | 393 | void Flag::add_ware(EditorGameBase& egbase, WareInstance& ware) { | 366 | void Flag::add_ware(EditorGameBase& egbase, WareInstance& ware) { |
45 | 367 | |||
46 | 394 | assert(ware_filled_ < ware_capacity_); | 368 | assert(ware_filled_ < ware_capacity_); |
47 | 395 | init_ware(egbase, ware, wares_[ware_filled_++]); | ||
48 | 396 | if (upcast(Game, game, &egbase)) { | ||
49 | 397 | ware.update(*game); // will call call_carrier() if necessary | ||
50 | 398 | } | ||
51 | 399 | } | ||
52 | 400 | 369 | ||
57 | 401 | /** | 370 | PendingWare& pi = wares_[ware_filled_++]; |
54 | 402 | * Properly assigns given ware instance to given pending ware. | ||
55 | 403 | */ | ||
56 | 404 | void Flag::init_ware(EditorGameBase& egbase, WareInstance& ware, PendingWare& pi) { | ||
58 | 405 | pi.ware = &ware; | 371 | pi.ware = &ware; |
60 | 406 | pi.pending = true; | 372 | pi.pending = false; |
61 | 407 | pi.nextstep = nullptr; | 373 | pi.nextstep = nullptr; |
62 | 408 | pi.priority = 0; | 374 | pi.priority = 0; |
63 | 409 | 375 | ||
64 | @@ -423,24 +389,32 @@ | |||
65 | 423 | } | 389 | } |
66 | 424 | 390 | ||
67 | 425 | ware.set_location(egbase, this); | 391 | ware.set_location(egbase, this); |
68 | 392 | |||
69 | 393 | if (upcast(Game, game, &egbase)) { | ||
70 | 394 | ware.update(*game); // will call call_carrier() if necessary | ||
71 | 395 | } | ||
72 | 426 | } | 396 | } |
73 | 427 | 397 | ||
74 | 428 | /** | 398 | /** |
76 | 429 | * \return a ware currently waiting for a carrier to the given destflag. | 399 | * \return true if a ware is currently waiting for a carrier to the given Flag. |
77 | 430 | * | 400 | * |
78 | 431 | * \note Due to fetch_from_flag() semantics, this function makes no sense | 401 | * \note Due to fetch_from_flag() semantics, this function makes no sense |
79 | 432 | * for a building destination. | 402 | * for a building destination. |
80 | 433 | */ | 403 | */ |
82 | 434 | Flag::PendingWare* Flag::get_ware_for_flag(Flag& destflag, bool const pending_only) { | 404 | bool Flag::has_pending_ware(Game&, Flag& dest) { |
83 | 435 | for (int32_t i = 0; i < ware_filled_; ++i) { | 405 | for (int32_t i = 0; i < ware_filled_; ++i) { |
89 | 436 | PendingWare* pw = &wares_[i]; | 406 | if (!wares_[i].pending) { |
90 | 437 | if ((!pending_only || pw->pending) && pw->nextstep == &destflag && | 407 | continue; |
91 | 438 | destflag.allow_ware_from_flag(*pw->ware, *this)) { | 408 | } |
92 | 439 | return pw; | 409 | |
93 | 440 | } | 410 | if (wares_[i].nextstep != &dest) { |
94 | 411 | continue; | ||
95 | 412 | } | ||
96 | 413 | |||
97 | 414 | return true; | ||
98 | 441 | } | 415 | } |
99 | 442 | 416 | ||
101 | 443 | return nullptr; | 417 | return false; |
102 | 444 | } | 418 | } |
103 | 445 | 419 | ||
104 | 446 | /** | 420 | /** |
105 | @@ -450,124 +424,109 @@ | |||
106 | 450 | #define MAX_TRANSFER_PRIORITY 16 | 424 | #define MAX_TRANSFER_PRIORITY 16 |
107 | 451 | 425 | ||
108 | 452 | /** | 426 | /** |
113 | 453 | * Called by the carriercode when the carrier is called away from his job | 427 | * Called by carrier code to indicate that the carrier is moving to pick up an |
114 | 454 | * but has acknowledged a ware before. This ware is then freed again | 428 | * ware. Ware with highest transfer priority is chosen. |
115 | 455 | * to be picked by another carrier. Returns true if a ware was indeed | 429 | * \return true if an ware is actually waiting for the carrier. |
112 | 456 | * made pending again. | ||
116 | 457 | */ | 430 | */ |
118 | 458 | bool Flag::cancel_pickup(Game& game, Flag& destflag) { | 431 | bool Flag::ack_pickup(Game&, Flag& destflag) { |
119 | 432 | int32_t highest_pri = -1; | ||
120 | 433 | int32_t i_pri = -1; | ||
121 | 434 | |||
122 | 459 | for (int32_t i = 0; i < ware_filled_; ++i) { | 435 | for (int32_t i = 0; i < ware_filled_; ++i) { |
129 | 460 | PendingWare& pw = wares_[i]; | 436 | if (!wares_[i].pending) { |
130 | 461 | if (!pw.pending && pw.nextstep == &destflag) { | 437 | continue; |
131 | 462 | pw.pending = true; | 438 | } |
132 | 463 | pw.ware->update(game); // will call call_carrier() if necessary | 439 | |
133 | 464 | return true; | 440 | if (wares_[i].nextstep != &destflag) { |
134 | 465 | } | 441 | continue; |
135 | 442 | } | ||
136 | 443 | |||
137 | 444 | if (wares_[i].priority > highest_pri) { | ||
138 | 445 | highest_pri = wares_[i].priority; | ||
139 | 446 | i_pri = i; | ||
140 | 447 | |||
141 | 448 | // Increase ware priority, it matters only if the ware has to wait. | ||
142 | 449 | if (wares_[i].priority < MAX_TRANSFER_PRIORITY) { | ||
143 | 450 | wares_[i].priority++; | ||
144 | 451 | } | ||
145 | 452 | } | ||
146 | 453 | } | ||
147 | 454 | |||
148 | 455 | if (i_pri >= 0) { | ||
149 | 456 | wares_[i_pri].pending = false; | ||
150 | 457 | return true; | ||
151 | 466 | } | 458 | } |
152 | 467 | 459 | ||
153 | 468 | return false; | 460 | return false; |
154 | 469 | } | 461 | } |
155 | 470 | |||
156 | 471 | /** | 462 | /** |
157 | 472 | * Called by carrier code to find the best among the wares on this flag | 463 | * Called by carrier code to find the best among the wares on this flag |
158 | 473 | * that are meant for the provided dest. | 464 | * that are meant for the provided dest. |
159 | 474 | * \return index of found ware (carrier will take it) | 465 | * \return index of found ware (carrier will take it) |
160 | 475 | * or kNotFoundAppropriate (carrier will leave empty-handed) | 466 | * or kNotFoundAppropriate (carrier will leave empty-handed) |
161 | 476 | */ | 467 | */ |
256 | 477 | int32_t Flag::find_pending_ware(PlayerImmovable& dest) { | 468 | bool Flag::cancel_pickup(Game& game, Flag& destflag) { |
257 | 478 | int32_t highest_pri = -1; | 469 | int32_t lowest_prio = MAX_TRANSFER_PRIORITY + 1; |
258 | 479 | int32_t best_index = kNotFoundAppropriate; | 470 | int32_t i_pri = -1; |
259 | 480 | bool ware_pended = false; | 471 | |
260 | 481 | 472 | for (int32_t i = 0; i < ware_filled_; ++i) { | |
261 | 482 | for (int32_t i = 0; i < ware_filled_; ++i) { | 473 | if (wares_[i].pending) { |
262 | 483 | PendingWare& pw = wares_[i]; | 474 | continue; |
263 | 484 | if (pw.nextstep != &dest) { | 475 | } |
264 | 485 | continue; | 476 | |
265 | 486 | } | 477 | if (wares_[i].nextstep != &destflag) { |
266 | 487 | 478 | continue; | |
267 | 488 | if (pw.priority < MAX_TRANSFER_PRIORITY) { | 479 | } |
268 | 489 | pw.priority++; | 480 | |
269 | 490 | } | 481 | if (wares_[i].priority < lowest_prio) { |
270 | 491 | // Release promised pickup, in case we find a preferable ware | 482 | lowest_prio = wares_[i].priority; |
271 | 492 | if (!ware_pended && !pw.pending) { | 483 | i_pri = i; |
272 | 493 | ware_pended = pw.pending = true; | 484 | } |
273 | 494 | } | 485 | } |
274 | 495 | 486 | ||
275 | 496 | // If dest is flag, we exclude wares that can stress it | 487 | if (i_pri >= 0) { |
276 | 497 | if (&dest != building_ && !dynamic_cast<Flag&>(dest).allow_ware_from_flag(*pw.ware, *this)) { | 488 | wares_[i_pri].pending = true; |
277 | 498 | continue; | 489 | wares_[i_pri].ware->update(game); // will call call_carrier() if necessary |
278 | 499 | } | 490 | return true; |
279 | 500 | 491 | } | |
280 | 501 | if (pw.priority > highest_pri) { | 492 | |
281 | 502 | highest_pri = pw.priority; | 493 | return false; |
282 | 503 | best_index = i; | 494 | } |
283 | 504 | } | 495 | |
284 | 505 | } | 496 | /** |
285 | 506 | 497 | * Wake one sleeper from the capacity queue. | |
286 | 507 | return best_index; | 498 | */ |
287 | 508 | } | 499 | void Flag::wake_up_capacity_queue(Game& game) { |
288 | 509 | 500 | while (!capacity_wait_.empty()) { | |
289 | 510 | /** | 501 | Worker* const w = capacity_wait_.front().get(game); |
290 | 511 | * Like find_pending_ware() above, but for carriers who have a ware to drop on this flag. | 502 | capacity_wait_.pop_front(); |
291 | 512 | * \return same as find_pending_ware() above, plus kDenyDrop (carrier will wait) | 503 | if (w && w->wakeup_flag_capacity(game, *this)) { |
292 | 513 | */ | 504 | break; |
293 | 514 | int32_t Flag::find_swappable_ware(WareInstance& ware, Flag& destflag) { | 505 | } |
294 | 515 | DescriptionIndex const descr_index = ware.descr_index(); | 506 | } |
295 | 516 | int32_t highest_pri = -1; | 507 | } |
296 | 517 | int32_t best_index = kNotFoundAppropriate; | 508 | |
297 | 518 | bool has_same_ware = false; | 509 | /** |
298 | 519 | bool has_allowed = false; | 510 | * Called by carrier code to retrieve one of the wares on the flag that is meant |
299 | 520 | bool ware_pended = false; | 511 | * for that carrier. |
300 | 521 | 512 | * | |
301 | 522 | for (int32_t i = 0; i < ware_filled_; ++i) { | 513 | * This function may return 0 even if \ref ack_pickup() has already been |
302 | 523 | PendingWare& pw = wares_[i]; | 514 | * called successfully. |
303 | 524 | if (pw.nextstep != &destflag) { | 515 | */ |
304 | 525 | if (pw.ware->descr_index() == descr_index) { | 516 | WareInstance* Flag::fetch_pending_ware(Game& game, PlayerImmovable& dest) { |
305 | 526 | has_same_ware = true; | 517 | int32_t best_index = -1; |
306 | 527 | } | 518 | |
307 | 528 | continue; | 519 | for (int32_t i = 0; i < ware_filled_; ++i) { |
308 | 529 | } | 520 | if (wares_[i].nextstep != &dest) { |
309 | 530 | 521 | continue; | |
310 | 531 | if (pw.priority < MAX_TRANSFER_PRIORITY) { | 522 | } |
311 | 532 | pw.priority++; | 523 | |
312 | 533 | } | 524 | // We prefer to retrieve wares that have already been acked |
313 | 534 | // Release promised pickup, in case we find a preferable ware | 525 | if (best_index < 0 || !wares_[i].pending) { |
314 | 535 | if (!ware_pended && !pw.pending) { | 526 | best_index = i; |
315 | 536 | ware_pended = pw.pending = true; | 527 | } |
316 | 537 | } | 528 | } |
317 | 538 | 529 | ||
224 | 539 | // We prefer to retrieve wares that won't stress the destflag | ||
225 | 540 | if (destflag.allow_ware_from_flag(*pw.ware, *this)) { | ||
226 | 541 | if (!has_allowed) { | ||
227 | 542 | has_allowed = true; | ||
228 | 543 | highest_pri = -1; | ||
229 | 544 | } | ||
230 | 545 | } else { | ||
231 | 546 | if (has_allowed) { | ||
232 | 547 | continue; | ||
233 | 548 | } | ||
234 | 549 | } | ||
235 | 550 | |||
236 | 551 | if (pw.priority > highest_pri) { | ||
237 | 552 | highest_pri = pw.priority; | ||
238 | 553 | best_index = i; | ||
239 | 554 | } | ||
240 | 555 | } | ||
241 | 556 | |||
242 | 557 | if (best_index > kNotFoundAppropriate) { | ||
243 | 558 | return (ware_filled_ > ware_capacity_ - 3 || has_allowed) ? best_index : kNotFoundAppropriate; | ||
244 | 559 | } else { | ||
245 | 560 | return (ware_filled_ < ware_capacity_ - 2 || | ||
246 | 561 | (ware_filled_ < ware_capacity_ && !has_same_ware)) ? | ||
247 | 562 | kNotFoundAppropriate : | ||
248 | 563 | kDenyDrop; | ||
249 | 564 | } | ||
250 | 565 | } | ||
251 | 566 | |||
252 | 567 | /** | ||
253 | 568 | * Called by carrier code to retrieve a ware found by the previous methods. | ||
254 | 569 | */ | ||
255 | 570 | WareInstance* Flag::fetch_pending_ware(Game& game, int32_t best_index) { | ||
318 | 571 | if (best_index < 0) { | 530 | if (best_index < 0) { |
319 | 572 | return nullptr; | 531 | return nullptr; |
320 | 573 | } | 532 | } |
321 | @@ -579,43 +538,14 @@ | |||
322 | 579 | sizeof(wares_[0]) * (ware_filled_ - best_index)); | 538 | sizeof(wares_[0]) * (ware_filled_ - best_index)); |
323 | 580 | 539 | ||
324 | 581 | ware->set_location(game, nullptr); | 540 | ware->set_location(game, nullptr); |
325 | 541 | |||
326 | 542 | // wake up capacity wait queue | ||
327 | 543 | wake_up_capacity_queue(game); | ||
328 | 544 | |||
329 | 582 | return ware; | 545 | return ware; |
330 | 583 | } | 546 | } |
331 | 584 | 547 | ||
332 | 585 | /** | 548 | /** |
333 | 586 | * Called by carrier code to notify waiting carriers | ||
334 | 587 | * which may be interested in the new state of this flag. | ||
335 | 588 | */ | ||
336 | 589 | void Flag::ware_departing(Game& game) { | ||
337 | 590 | // Wake up one sleeper from the capacity queue. | ||
338 | 591 | while (!capacity_wait_.empty()) { | ||
339 | 592 | Worker* const w = capacity_wait_.front().get(game); | ||
340 | 593 | capacity_wait_.erase(capacity_wait_.begin()); | ||
341 | 594 | if (w && w->wakeup_flag_capacity(game, *this)) { | ||
342 | 595 | return; | ||
343 | 596 | } | ||
344 | 597 | } | ||
345 | 598 | |||
346 | 599 | // Consider pending wares of neighboring flags. | ||
347 | 600 | for (int32_t dir = 1; dir <= WalkingDir::LAST_DIRECTION; ++dir) { | ||
348 | 601 | Road* const road = get_road(dir); | ||
349 | 602 | if (!road) { | ||
350 | 603 | continue; | ||
351 | 604 | } | ||
352 | 605 | |||
353 | 606 | Flag* other = &road->get_flag(Road::FlagEnd); | ||
354 | 607 | if (other == this) { | ||
355 | 608 | other = &road->get_flag(Road::FlagStart); | ||
356 | 609 | } | ||
357 | 610 | |||
358 | 611 | PendingWare* pw = other->get_ware_for_flag(*this, kPendingOnly); | ||
359 | 612 | if (pw && road->notify_ware(game, *other)) { | ||
360 | 613 | pw->pending = false; | ||
361 | 614 | } | ||
362 | 615 | } | ||
363 | 616 | } | ||
364 | 617 | |||
365 | 618 | /** | ||
366 | 619 | * Accelerate potential promotion of roads adjacent to a newly promoted road. | 549 | * Accelerate potential promotion of roads adjacent to a newly promoted road. |
367 | 620 | */ | 550 | */ |
368 | 621 | void Flag::propagate_promoted_road(Road* const promoted_road) { | 551 | void Flag::propagate_promoted_road(Road* const promoted_road) { |
369 | @@ -684,7 +614,7 @@ | |||
370 | 684 | memmove(&wares_[i], &wares_[i + 1], sizeof(wares_[0]) * (ware_filled_ - i)); | 614 | memmove(&wares_[i], &wares_[i + 1], sizeof(wares_[0]) * (ware_filled_ - i)); |
371 | 685 | 615 | ||
372 | 686 | if (upcast(Game, game, &egbase)) { | 616 | if (upcast(Game, game, &egbase)) { |
374 | 687 | ware_departing(*game); | 617 | wake_up_capacity_queue(*game); |
375 | 688 | } | 618 | } |
376 | 689 | 619 | ||
377 | 690 | return; | 620 | return; |
378 | @@ -755,20 +685,27 @@ | |||
379 | 755 | 685 | ||
380 | 756 | for (int32_t dir = 1; dir <= 6; ++dir) { | 686 | for (int32_t dir = 1; dir <= 6; ++dir) { |
381 | 757 | Road* const road = get_road(dir); | 687 | Road* const road = get_road(dir); |
382 | 688 | Flag* other; | ||
383 | 689 | Road::FlagId flagid; | ||
384 | 690 | |||
385 | 758 | if (!road) { | 691 | if (!road) { |
386 | 759 | continue; | 692 | continue; |
387 | 760 | } | 693 | } |
388 | 761 | 694 | ||
391 | 762 | Flag* other = &road->get_flag(Road::FlagEnd); | 695 | if (&road->get_flag(Road::FlagStart) == this) { |
392 | 763 | if (other == this) { | 696 | flagid = Road::FlagStart; |
393 | 697 | other = &road->get_flag(Road::FlagEnd); | ||
394 | 698 | } else { | ||
395 | 699 | flagid = Road::FlagEnd; | ||
396 | 764 | other = &road->get_flag(Road::FlagStart); | 700 | other = &road->get_flag(Road::FlagStart); |
397 | 765 | } | 701 | } |
398 | 702 | |||
399 | 766 | if (other != &nextflag) { | 703 | if (other != &nextflag) { |
400 | 767 | continue; | 704 | continue; |
401 | 768 | } | 705 | } |
402 | 769 | 706 | ||
403 | 770 | // Yes, this is the road we want; inform it | 707 | // Yes, this is the road we want; inform it |
405 | 771 | if (other->update_ware_from_flag(game, wares_[i], *road, *this)) { | 708 | if (road->notify_ware(game, flagid)) { |
406 | 772 | return; | 709 | return; |
407 | 773 | } | 710 | } |
408 | 774 | 711 | ||
409 | @@ -782,72 +719,6 @@ | |||
410 | 782 | } | 719 | } |
411 | 783 | 720 | ||
412 | 784 | /** | 721 | /** |
413 | 785 | * Called by neighboring flags, before agreeing for a carrier | ||
414 | 786 | * to take one of their wares heading to this flag. | ||
415 | 787 | * \return true/allow on low congestion-risk. | ||
416 | 788 | */ | ||
417 | 789 | bool Flag::allow_ware_from_flag(WareInstance& ware, Flag& flag) { | ||
418 | 790 | // avoid iteration for the easy cases | ||
419 | 791 | if (ware_filled_ < ware_capacity_ - 2) { | ||
420 | 792 | return true; | ||
421 | 793 | } | ||
422 | 794 | |||
423 | 795 | DescriptionIndex const descr_index = ware.descr_index(); | ||
424 | 796 | bool has_swappable = false; | ||
425 | 797 | for (int i = 0; i < ware_filled_; ++i) { | ||
426 | 798 | PendingWare& pw = wares_[i]; | ||
427 | 799 | if (pw.pending && pw.nextstep == &flag) { | ||
428 | 800 | has_swappable = true; | ||
429 | 801 | } else if (pw.ware->descr_index() == descr_index) { | ||
430 | 802 | return false; | ||
431 | 803 | } | ||
432 | 804 | } | ||
433 | 805 | return ware_filled_ < ware_capacity_ || has_swappable; | ||
434 | 806 | } | ||
435 | 807 | |||
436 | 808 | /** | ||
437 | 809 | * Called when a ware is trying to reach this flag through the provided road, | ||
438 | 810 | * having just arrived to the provided flag. | ||
439 | 811 | * Swaps pending wares if possible. Otherwise, | ||
440 | 812 | * asks road for carrier on low congestion-risk. | ||
441 | 813 | * \return false if the ware is not immediately served. | ||
442 | 814 | */ | ||
443 | 815 | bool Flag::update_ware_from_flag(Game& game, PendingWare& pw1, Road& road, Flag& flag) { | ||
444 | 816 | WareInstance& w1 = *pw1.ware; | ||
445 | 817 | DescriptionIndex const w1_descr_index = w1.descr_index(); | ||
446 | 818 | bool has_same_ware = false; | ||
447 | 819 | bool has_swappable = false; | ||
448 | 820 | for (int i = 0; i < ware_filled_; ++i) { | ||
449 | 821 | PendingWare& pw2 = wares_[i]; | ||
450 | 822 | WareInstance& w2 = *pw2.ware; | ||
451 | 823 | if (w2.descr_index() == w1_descr_index) { | ||
452 | 824 | if (pw2.nextstep == &flag) { | ||
453 | 825 | // swap pending wares remotely | ||
454 | 826 | init_ware(game, w1, pw2); | ||
455 | 827 | flag.init_ware(game, w2, pw1); | ||
456 | 828 | w1.update(game); | ||
457 | 829 | w2.update(game); | ||
458 | 830 | return true; | ||
459 | 831 | } | ||
460 | 832 | |||
461 | 833 | has_same_ware = true; | ||
462 | 834 | } else if (pw2.pending && pw2.nextstep == &flag) { | ||
463 | 835 | has_swappable = true; | ||
464 | 836 | } | ||
465 | 837 | } | ||
466 | 838 | |||
467 | 839 | // ask road for carrier on low congestion-risk | ||
468 | 840 | if (ware_filled_ < ware_capacity_ - 2 || | ||
469 | 841 | (!has_same_ware && (ware_filled_ < ware_capacity_ || has_swappable))) { | ||
470 | 842 | if (road.notify_ware(game, flag)) { | ||
471 | 843 | pw1.pending = false; | ||
472 | 844 | return true; | ||
473 | 845 | } | ||
474 | 846 | } | ||
475 | 847 | return false; | ||
476 | 848 | } | ||
477 | 849 | |||
478 | 850 | /** | ||
479 | 851 | * Called whenever a road gets broken or split. | 722 | * Called whenever a road gets broken or split. |
480 | 852 | * Make sure all wares on this flag are rerouted if necessary. | 723 | * Make sure all wares on this flag are rerouted if necessary. |
481 | 853 | * | 724 | * |
482 | 854 | 725 | ||
483 | === modified file 'src/economy/flag.h' | |||
484 | --- src/economy/flag.h 2018-09-25 06:32:35 +0000 | |||
485 | +++ src/economy/flag.h 2018-11-26 06:43:43 +0000 | |||
486 | @@ -47,10 +47,6 @@ | |||
487 | 47 | DISALLOW_COPY_AND_ASSIGN(FlagDescr); | 47 | DISALLOW_COPY_AND_ASSIGN(FlagDescr); |
488 | 48 | }; | 48 | }; |
489 | 49 | 49 | ||
490 | 50 | constexpr bool kPendingOnly = true; // ignore non-pending wares | ||
491 | 51 | constexpr int32_t kNotFoundAppropriate = -1; // no ware appropiate for carrying | ||
492 | 52 | constexpr int32_t kDenyDrop = -2; // flag is full and no ware appropiate for swapping | ||
493 | 53 | |||
494 | 54 | /** | 50 | /** |
495 | 55 | * Flag represents a flag as you see it on the map. | 51 | * Flag represents a flag as you see it on the map. |
496 | 56 | * | 52 | * |
497 | @@ -125,15 +121,7 @@ | |||
498 | 125 | 121 | ||
499 | 126 | bool is_dead_end() const; | 122 | bool is_dead_end() const; |
500 | 127 | 123 | ||
501 | 128 | struct PendingWare { | ||
502 | 129 | WareInstance* ware; ///< the ware itself | ||
503 | 130 | bool pending; ///< if the ware is pending | ||
504 | 131 | int32_t priority; ///< carrier prefers the ware with highest priority | ||
505 | 132 | OPtr<PlayerImmovable> nextstep; ///< next step that this ware is sent to | ||
506 | 133 | }; | ||
507 | 134 | |||
508 | 135 | bool has_capacity() const; | 124 | bool has_capacity() const; |
509 | 136 | bool has_capacity_for_ware(WareInstance&) const; | ||
510 | 137 | uint32_t total_capacity() { | 125 | uint32_t total_capacity() { |
511 | 138 | return ware_capacity_; | 126 | return ware_capacity_; |
512 | 139 | } | 127 | } |
513 | @@ -143,14 +131,10 @@ | |||
514 | 143 | void wait_for_capacity(Game&, Worker&); | 131 | void wait_for_capacity(Game&, Worker&); |
515 | 144 | void skip_wait_for_capacity(Game&, Worker&); | 132 | void skip_wait_for_capacity(Game&, Worker&); |
516 | 145 | void add_ware(EditorGameBase&, WareInstance&); | 133 | void add_ware(EditorGameBase&, WareInstance&); |
519 | 146 | void init_ware(EditorGameBase&, WareInstance&, PendingWare&); | 134 | bool has_pending_ware(Game&, Flag& destflag); |
520 | 147 | PendingWare* get_ware_for_flag(Flag&, bool pending_only = false); | 135 | bool ack_pickup(Game&, Flag& destflag); |
521 | 148 | bool cancel_pickup(Game&, Flag& destflag); | 136 | bool cancel_pickup(Game&, Flag& destflag); |
527 | 149 | void ware_departing(Game&); | 137 | WareInstance* fetch_pending_ware(Game&, PlayerImmovable& dest); |
523 | 150 | bool allow_ware_from_flag(WareInstance&, Flag&); | ||
524 | 151 | int32_t find_swappable_ware(WareInstance&, Flag&); | ||
525 | 152 | int32_t find_pending_ware(PlayerImmovable&); | ||
526 | 153 | WareInstance* fetch_pending_ware(Game&, int32_t); | ||
528 | 154 | void propagate_promoted_road(Road* promoted_road); | 138 | void propagate_promoted_road(Road* promoted_road); |
529 | 155 | Wares get_wares(); | 139 | Wares get_wares(); |
530 | 156 | uint8_t count_wares_in_queue(PlayerImmovable& dest) const; | 140 | uint8_t count_wares_in_queue(PlayerImmovable& dest) const; |
531 | @@ -171,13 +155,20 @@ | |||
532 | 171 | void | 155 | void |
533 | 172 | draw(uint32_t gametime, const Vector2f& point_on_dst, float scale, RenderTarget* dst) override; | 156 | draw(uint32_t gametime, const Vector2f& point_on_dst, float scale, RenderTarget* dst) override; |
534 | 173 | 157 | ||
535 | 158 | void wake_up_capacity_queue(Game&); | ||
536 | 159 | |||
537 | 174 | static void | 160 | static void |
538 | 175 | flag_job_request_callback(Game&, Request&, DescriptionIndex, Worker*, PlayerImmovable&); | 161 | flag_job_request_callback(Game&, Request&, DescriptionIndex, Worker*, PlayerImmovable&); |
539 | 176 | 162 | ||
540 | 177 | void set_flag_position(Coords coords); | 163 | void set_flag_position(Coords coords); |
541 | 178 | 164 | ||
542 | 179 | private: | 165 | private: |
544 | 180 | bool update_ware_from_flag(Game&, PendingWare&, Road&, Flag&); | 166 | struct PendingWare { |
545 | 167 | WareInstance* ware; ///< the ware itself | ||
546 | 168 | bool pending; ///< if the ware is pending | ||
547 | 169 | int32_t priority; ///< carrier prefers the ware with highest priority | ||
548 | 170 | OPtr<PlayerImmovable> nextstep; ///< next step that this ware is sent to | ||
549 | 171 | }; | ||
550 | 181 | 172 | ||
551 | 182 | struct FlagJob { | 173 | struct FlagJob { |
552 | 183 | Request* request; | 174 | Request* request; |
553 | 184 | 175 | ||
554 | === modified file 'src/economy/road.cc' | |||
555 | --- src/economy/road.cc 2018-09-04 15:48:47 +0000 | |||
556 | +++ src/economy/road.cc 2018-11-26 06:43:43 +0000 | |||
557 | @@ -542,8 +542,7 @@ | |||
558 | 542 | * Try to pick up a ware from the given flag. | 542 | * Try to pick up a ware from the given flag. |
559 | 543 | * \return true if a carrier has been sent on its way, false otherwise. | 543 | * \return true if a carrier has been sent on its way, false otherwise. |
560 | 544 | */ | 544 | */ |
563 | 545 | bool Road::notify_ware(Game& game, Flag& flag) { | 545 | bool Road::notify_ware(Game& game, FlagId const flagid) { |
562 | 546 | FlagId flagid = &flag == flags_[Road::FlagEnd] ? Road::FlagEnd : Road::FlagStart; | ||
564 | 547 | // Iterate over all carriers and try to find one which will take the ware | 546 | // Iterate over all carriers and try to find one which will take the ware |
565 | 548 | for (CarrierSlot& slot : carrier_slots_) { | 547 | for (CarrierSlot& slot : carrier_slots_) { |
566 | 549 | if (Carrier* const carrier = slot.carrier.get(game)) { | 548 | if (Carrier* const carrier = slot.carrier.get(game)) { |
567 | 550 | 549 | ||
568 | === modified file 'src/economy/road.h' | |||
569 | --- src/economy/road.h 2018-09-25 06:32:35 +0000 | |||
570 | +++ src/economy/road.h 2018-11-26 06:43:43 +0000 | |||
571 | @@ -113,7 +113,7 @@ | |||
572 | 113 | void presplit(Game&, Coords split); | 113 | void presplit(Game&, Coords split); |
573 | 114 | void postsplit(Game&, Flag&); | 114 | void postsplit(Game&, Flag&); |
574 | 115 | 115 | ||
576 | 116 | bool notify_ware(Game& game, Flag& flag); | 116 | bool notify_ware(Game& game, FlagId flagid); |
577 | 117 | void update_wallet_chargetime(Game& game); | 117 | void update_wallet_chargetime(Game& game); |
578 | 118 | void charge_wallet(Game& game); | 118 | void charge_wallet(Game& game); |
579 | 119 | int32_t wallet() const; | 119 | int32_t wallet() const; |
580 | @@ -148,8 +148,8 @@ | |||
581 | 148 | uint8_t carriers_count() const; | 148 | uint8_t carriers_count() const; |
582 | 149 | 149 | ||
583 | 150 | private: | 150 | private: |
586 | 151 | /// Counter that is incremented for every ware served by this road | 151 | /// Counter that is incremented when a ware does not get a carrier for this |
587 | 152 | /// according to the delay of service and decremented over time. | 152 | /// road immediately and decremented over time. |
588 | 153 | int32_t wallet_; | 153 | int32_t wallet_; |
589 | 154 | 154 | ||
590 | 155 | /// holds the gametime when wallet_ was last charged | 155 | /// holds the gametime when wallet_ was last charged |
591 | 156 | 156 | ||
592 | === modified file 'src/logic/map_objects/tribes/carrier.cc' | |||
593 | --- src/logic/map_objects/tribes/carrier.cc 2018-10-30 18:40:57 +0000 | |||
594 | +++ src/logic/map_objects/tribes/carrier.cc 2018-11-26 06:43:43 +0000 | |||
595 | @@ -51,7 +51,7 @@ | |||
596 | 51 | 51 | ||
597 | 52 | top_state().ivar1 = 0; | 52 | top_state().ivar1 = 0; |
598 | 53 | 53 | ||
600 | 54 | operation_ = INIT; | 54 | promised_pickup_to_ = NOONE; |
601 | 55 | } | 55 | } |
602 | 56 | 56 | ||
603 | 57 | /** | 57 | /** |
604 | @@ -78,14 +78,15 @@ | |||
605 | 78 | return pop_task(game); | 78 | return pop_task(game); |
606 | 79 | } | 79 | } |
607 | 80 | 80 | ||
610 | 81 | if (operation_ == INIT) { | 81 | // Check for pending wares |
611 | 82 | operation_ = find_source_flag(game); | 82 | if (promised_pickup_to_ == NOONE) { |
612 | 83 | find_pending_ware(game); | ||
613 | 83 | } | 84 | } |
614 | 84 | 85 | ||
616 | 85 | if (operation_ > NO_OPERATION) { | 86 | if (promised_pickup_to_ != NOONE) { |
617 | 86 | if (state.ivar1) { | 87 | if (state.ivar1) { |
618 | 87 | state.ivar1 = 0; | 88 | state.ivar1 = 0; |
620 | 88 | return start_task_transport(game, operation_); | 89 | return start_task_transport(game, promised_pickup_to_); |
621 | 89 | } else { | 90 | } else { |
622 | 90 | // Short delay before we move to pick up | 91 | // Short delay before we move to pick up |
623 | 91 | state.ivar1 = 1; | 92 | state.ivar1 = 1; |
624 | @@ -119,10 +120,10 @@ | |||
625 | 119 | * a ware there, we have to make sure that they do not count on us anymore. | 120 | * a ware there, we have to make sure that they do not count on us anymore. |
626 | 120 | */ | 121 | */ |
627 | 121 | void Carrier::road_pop(Game& game, State& /* state */) { | 122 | void Carrier::road_pop(Game& game, State& /* state */) { |
629 | 122 | if (operation_ > NO_OPERATION && get_location(game)) { | 123 | if (promised_pickup_to_ != NOONE && get_location(game)) { |
630 | 123 | Road& road = dynamic_cast<Road&>(*get_location(game)); | 124 | Road& road = dynamic_cast<Road&>(*get_location(game)); |
633 | 124 | Flag& flag = road.get_flag(static_cast<Road::FlagId>(operation_)); | 125 | Flag& flag = road.get_flag(static_cast<Road::FlagId>(promised_pickup_to_)); |
634 | 125 | Flag& otherflag = road.get_flag(static_cast<Road::FlagId>(operation_ ^ 1)); | 126 | Flag& otherflag = road.get_flag(static_cast<Road::FlagId>(promised_pickup_to_ ^ 1)); |
635 | 126 | 127 | ||
636 | 127 | flag.cancel_pickup(game, otherflag); | 128 | flag.cancel_pickup(game, otherflag); |
637 | 128 | } | 129 | } |
638 | @@ -160,99 +161,35 @@ | |||
639 | 160 | return pop_task(game); | 161 | return pop_task(game); |
640 | 161 | } | 162 | } |
641 | 162 | 163 | ||
644 | 163 | int32_t const ivar1 = state.ivar1; | 164 | if (state.ivar1 == -1) { |
643 | 164 | if (ivar1 == -1) { | ||
645 | 165 | // If we're "in" the target building, special code applies | 165 | // If we're "in" the target building, special code applies |
661 | 166 | return deliver_to_building(game, state); | 166 | deliver_to_building(game, state); |
662 | 167 | } | 167 | } else if (!does_carry_ware()) { |
663 | 168 | 168 | // If we don't carry something, walk to the flag | |
664 | 169 | WareInstance* ware = get_carried_ware(game); | 169 | pickup_from_flag(game, state); |
665 | 170 | if (ware) { | 170 | } else { |
666 | 171 | assert(ware->get_location(game) == this); | 171 | Road& road = dynamic_cast<Road&>(*get_location(game)); |
667 | 172 | } | 172 | // If the ware should go to the building attached to our flag, walk |
668 | 173 | 173 | // directly into said building | |
669 | 174 | Road& road = dynamic_cast<Road&>(*get_location(game)); | 174 | Flag& flag = road.get_flag(static_cast<Road::FlagId>(state.ivar1 ^ 1)); |
670 | 175 | int32_t const dest = ware ? ivar1 ^ 1 : ivar1; | 175 | |
671 | 176 | Flag& flag = road.get_flag(static_cast<Road::FlagId>(dest)); | 176 | WareInstance& ware = *get_carried_ware(game); |
672 | 177 | 177 | assert(ware.get_location(game) == this); | |
673 | 178 | if (ware) { | 178 | |
659 | 179 | // If the ware should go to the building attached to our flag, | ||
660 | 180 | // walk directly into said building | ||
674 | 181 | // A sanity check is necessary, in case the building has been destroyed | 179 | // A sanity check is necessary, in case the building has been destroyed |
675 | 180 | PlayerImmovable* const next = ware.get_next_move_step(game); | ||
676 | 182 | 181 | ||
677 | 183 | PlayerImmovable* const next = ware->get_next_move_step(game); | ||
678 | 184 | if (next && next != &flag && &next->base_flag() == &flag) { | 182 | if (next && next != &flag && &next->base_flag() == &flag) { |
679 | 185 | // pay some coins before entering the building, | 183 | // pay some coins before entering the building, |
680 | 186 | // to compensate for the time to be spent in its street-segment | 184 | // to compensate for the time to be spent in its street-segment |
681 | 187 | road.pay_for_building(); | 185 | road.pay_for_building(); |
750 | 188 | 186 | enter_building(game, state); | |
751 | 189 | if (!start_task_walktoflag(game, dest)) { | 187 | } else if ((flag.has_capacity() || !swap_or_wait(game, state)) && |
752 | 190 | // Enter building | 188 | !start_task_walktoflag(game, state.ivar1 ^ 1)) { |
753 | 191 | state.ivar1 = -1; | 189 | // If the flag is overloaded we are allowed to drop wares as |
754 | 192 | start_task_move(game, WALK_NW, descr().get_right_walk_anims(does_carry_ware()), true); | 190 | // long as we can pick another up. Otherwise we have to wait. |
755 | 193 | } | 191 | // Drop the ware, possible exchanging it with another one |
756 | 194 | return; | 192 | drop_ware(game, state); |
689 | 195 | } | ||
690 | 196 | } | ||
691 | 197 | |||
692 | 198 | if (!start_task_walktoflag(game, dest, operation_ == WAIT)) { | ||
693 | 199 | // If the flag is overloaded we are allowed to drop wares, | ||
694 | 200 | // as long as we can pick another up. Otherwise we have to wait. | ||
695 | 201 | |||
696 | 202 | Flag& otherflag = road.get_flag(static_cast<Road::FlagId>(dest ^ 1)); | ||
697 | 203 | int32_t otherware_idx = | ||
698 | 204 | ware ? flag.find_swappable_ware(*ware, otherflag) : flag.find_pending_ware(otherflag); | ||
699 | 205 | if (operation_ == WAIT) { | ||
700 | 206 | if (otherware_idx < kNotFoundAppropriate) { | ||
701 | 207 | return start_task_waitforcapacity(game, flag); // join flag's wait queue | ||
702 | 208 | } else { | ||
703 | 209 | operation_ = dest ^ 1; // resume transport without joining flag's wait queue | ||
704 | 210 | set_animation(game, descr().get_animation("idle")); | ||
705 | 211 | return schedule_act(game, 20); | ||
706 | 212 | } | ||
707 | 213 | } else if (otherware_idx < kNotFoundAppropriate) { | ||
708 | 214 | operation_ = WAIT; // move one node away | ||
709 | 215 | set_animation(game, descr().get_animation("idle")); | ||
710 | 216 | return schedule_act(game, 20); | ||
711 | 217 | } | ||
712 | 218 | |||
713 | 219 | WareInstance* otherware = flag.fetch_pending_ware(game, otherware_idx); | ||
714 | 220 | |||
715 | 221 | if (ware) { | ||
716 | 222 | const bool ware_astray = (ware->get_next_move_step(game) == nullptr); | ||
717 | 223 | // Drop our ware | ||
718 | 224 | flag.add_ware(game, *fetch_carried_ware(game)); | ||
719 | 225 | // If the destination of the dropped ware changed while carrying it and we don't have | ||
720 | 226 | // anything else we should carry, we might pick it up again immediately, so check again | ||
721 | 227 | if (ware_astray && otherware_idx == kNotFoundAppropriate) { | ||
722 | 228 | otherware_idx = flag.find_pending_ware(otherflag); | ||
723 | 229 | otherware = flag.fetch_pending_ware(game, otherware_idx); | ||
724 | 230 | } | ||
725 | 231 | } | ||
726 | 232 | |||
727 | 233 | // Pick up new load, if any | ||
728 | 234 | if (otherware) { | ||
729 | 235 | // pay before getting the ware, while checking for road promotion | ||
730 | 236 | road.pay_for_road(game, flag.count_wares_in_queue(otherflag)); | ||
731 | 237 | |||
732 | 238 | set_carried_ware(game, otherware); | ||
733 | 239 | flag.ware_departing(game); | ||
734 | 240 | |||
735 | 241 | operation_ = state.ivar1 = dest; | ||
736 | 242 | set_animation(game, descr().get_animation("idle")); | ||
737 | 243 | schedule_act(game, 20); | ||
738 | 244 | } else { | ||
739 | 245 | Flag::PendingWare* pw = otherflag.get_ware_for_flag(flag, kPendingOnly); | ||
740 | 246 | if (pw) { | ||
741 | 247 | pw->pending = false; | ||
742 | 248 | |||
743 | 249 | operation_ = state.ivar1 = dest ^ 1; | ||
744 | 250 | set_animation(game, descr().get_animation("idle")); | ||
745 | 251 | schedule_act(game, 20); | ||
746 | 252 | } else { | ||
747 | 253 | operation_ = NO_OPERATION; | ||
748 | 254 | pop_task(game); | ||
749 | 255 | } | ||
757 | 256 | } | 193 | } |
758 | 257 | } | 194 | } |
759 | 258 | } | 195 | } |
760 | @@ -268,7 +205,6 @@ | |||
761 | 268 | BaseImmovable* const pos = game.map()[get_position()].get_immovable(); | 205 | BaseImmovable* const pos = game.map()[get_position()].get_immovable(); |
762 | 269 | 206 | ||
763 | 270 | if (dynamic_cast<Flag const*>(pos)) { | 207 | if (dynamic_cast<Flag const*>(pos)) { |
764 | 271 | operation_ = INIT; | ||
765 | 272 | return pop_task(game); // we are done | 208 | return pop_task(game); // we are done |
766 | 273 | } else if (upcast(Building, building, pos)) { | 209 | } else if (upcast(Building, building, pos)) { |
767 | 274 | // Drop all wares addressed to this building | 210 | // Drop all wares addressed to this building |
768 | @@ -301,51 +237,212 @@ | |||
769 | 301 | } | 237 | } |
770 | 302 | 238 | ||
771 | 303 | /** | 239 | /** |
774 | 304 | * Called by road code to indicate that the given flag | 240 | * Walks to the queued flag and picks up one acked ware |
775 | 305 | * (0 = start, 1 = end) has a ware ready for transfer. | 241 | * |
776 | 242 | * \param g Game the carrier lives on | ||
777 | 243 | * \param s Flags sent to the task | ||
778 | 244 | */ | ||
779 | 245 | void Carrier::pickup_from_flag(Game& game, State& state) { | ||
780 | 246 | int32_t const ivar1 = state.ivar1; | ||
781 | 247 | if (!start_task_walktoflag(game, ivar1)) { | ||
782 | 248 | |||
783 | 249 | promised_pickup_to_ = NOONE; | ||
784 | 250 | |||
785 | 251 | Road& road = dynamic_cast<Road&>(*get_location(game)); | ||
786 | 252 | Flag& flag = road.get_flag(static_cast<Road::FlagId>(ivar1)); | ||
787 | 253 | Flag& otherflag = road.get_flag(static_cast<Road::FlagId>(ivar1 ^ 1)); | ||
788 | 254 | |||
789 | 255 | // Are there wares to move between our flags? | ||
790 | 256 | if (WareInstance* const ware = flag.fetch_pending_ware(game, otherflag)) { | ||
791 | 257 | // pay before getting the ware, while checking for road promotion | ||
792 | 258 | road.pay_for_road(game, flag.count_wares_in_queue(otherflag)); | ||
793 | 259 | set_carried_ware(game, ware); | ||
794 | 260 | |||
795 | 261 | set_animation(game, descr().get_animation("idle")); | ||
796 | 262 | return schedule_act(game, 20); | ||
797 | 263 | } else { | ||
798 | 264 | molog("[Carrier]: Nothing suitable on flag.\n"); | ||
799 | 265 | return pop_task(game); | ||
800 | 266 | } | ||
801 | 267 | } | ||
802 | 268 | } | ||
803 | 269 | |||
804 | 270 | /** | ||
805 | 271 | * Drop one ware in a flag, and pick up a new one if we acked it | ||
806 | 272 | * | ||
807 | 273 | * \param g Game the carrier lives on. | ||
808 | 274 | * \param s Flags sent to the task | ||
809 | 275 | */ | ||
810 | 276 | void Carrier::drop_ware(Game& game, State& state) { | ||
811 | 277 | WareInstance* other = nullptr; | ||
812 | 278 | Road& road = dynamic_cast<Road&>(*get_location(game)); | ||
813 | 279 | Flag& flag = road.get_flag(static_cast<Road::FlagId>(state.ivar1 ^ 1)); | ||
814 | 280 | Flag& otherflag = road.get_flag(static_cast<Road::FlagId>(state.ivar1)); | ||
815 | 281 | |||
816 | 282 | if (promised_pickup_to_ == (state.ivar1 ^ 1)) { | ||
817 | 283 | // If there's a ware we acked, we can drop ours even if the flag is | ||
818 | 284 | // flooded | ||
819 | 285 | other = flag.fetch_pending_ware(game, otherflag); | ||
820 | 286 | |||
821 | 287 | if (!other && !flag.has_capacity()) { | ||
822 | 288 | molog("[Carrier]: strange: acked ware from busy flag no longer " | ||
823 | 289 | "present.\n"); | ||
824 | 290 | |||
825 | 291 | promised_pickup_to_ = NOONE; | ||
826 | 292 | set_animation(game, descr().get_animation("idle")); | ||
827 | 293 | return schedule_act(game, 20); | ||
828 | 294 | } | ||
829 | 295 | |||
830 | 296 | state.ivar1 = promised_pickup_to_; | ||
831 | 297 | promised_pickup_to_ = NOONE; | ||
832 | 298 | } | ||
833 | 299 | |||
834 | 300 | // Drop our ware | ||
835 | 301 | flag.add_ware(game, *fetch_carried_ware(game)); | ||
836 | 302 | |||
837 | 303 | // Pick up new load, if any | ||
838 | 304 | if (other) { | ||
839 | 305 | // pay before getting the ware, while checking for road promotion | ||
840 | 306 | road.pay_for_road(game, flag.count_wares_in_queue(otherflag)); | ||
841 | 307 | set_carried_ware(game, other); | ||
842 | 308 | |||
843 | 309 | set_animation(game, descr().get_animation("idle")); | ||
844 | 310 | return schedule_act(game, 20); | ||
845 | 311 | } else { | ||
846 | 312 | return pop_task(game); | ||
847 | 313 | } | ||
848 | 314 | } | ||
849 | 315 | |||
850 | 316 | /** | ||
851 | 317 | * When picking up wares, if some of them is targeted to the building attached | ||
852 | 318 | * to target flag walk straight into it and deliver. | ||
853 | 319 | * | ||
854 | 320 | * \param g Game the carrier lives on. | ||
855 | 321 | * \param s Flags sent to the task. | ||
856 | 322 | */ | ||
857 | 323 | void Carrier::enter_building(Game& game, State& state) { | ||
858 | 324 | if (!start_task_walktoflag(game, state.ivar1 ^ 1)) { | ||
859 | 325 | state.ivar1 = -1; | ||
860 | 326 | return start_task_move(game, WALK_NW, descr().get_right_walk_anims(does_carry_ware()), true); | ||
861 | 327 | } | ||
862 | 328 | } | ||
863 | 329 | |||
864 | 330 | /** | ||
865 | 331 | * Swaps wares from an overloaded flag for as long as the carrier can pick | ||
866 | 332 | * up new wares from it. Otherwise, changes the carrier state to wait. | ||
867 | 333 | * | ||
868 | 334 | * \param g Game the carrier lives on. | ||
869 | 335 | * \param s Flags sent to the task. | ||
870 | 336 | * | ||
871 | 337 | * \return true if the carrier must wait before delivering his wares. | ||
872 | 338 | */ | ||
873 | 339 | bool Carrier::swap_or_wait(Game& game, State& state) { | ||
874 | 340 | // Road that employs us | ||
875 | 341 | Road& road = dynamic_cast<Road&>(*get_location(game)); | ||
876 | 342 | // Flag we are delivering to | ||
877 | 343 | Flag& flag = road.get_flag(static_cast<Road::FlagId>(state.ivar1 ^ 1)); | ||
878 | 344 | // The other flag of our road | ||
879 | 345 | Flag& otherflag = road.get_flag(static_cast<Road::FlagId>(state.ivar1)); | ||
880 | 346 | |||
881 | 347 | if (promised_pickup_to_ == (state.ivar1 ^ 1)) { | ||
882 | 348 | // All is well, we already acked a ware that we can pick up | ||
883 | 349 | // from this flag | ||
884 | 350 | return false; | ||
885 | 351 | } else if (flag.has_pending_ware(game, otherflag)) { | ||
886 | 352 | if (!flag.ack_pickup(game, otherflag)) { | ||
887 | 353 | throw wexception( | ||
888 | 354 | "MO(%u): transport: overload exchange: flag %u is fucked up", serial(), flag.serial()); | ||
889 | 355 | } | ||
890 | 356 | |||
891 | 357 | promised_pickup_to_ = state.ivar1 ^ 1; | ||
892 | 358 | return false; | ||
893 | 359 | } else if (!start_task_walktoflag(game, state.ivar1 ^ 1, true)) { | ||
894 | 360 | start_task_waitforcapacity(game, flag); // wait one node away | ||
895 | 361 | } | ||
896 | 362 | |||
897 | 363 | return true; | ||
898 | 364 | } | ||
899 | 365 | |||
900 | 366 | /** | ||
901 | 367 | * Called by Road code to indicate that a new ware has arrived on a flag | ||
902 | 368 | * (0 = start, 1 = end). | ||
903 | 306 | * \return true if the carrier is going to fetch it. | 369 | * \return true if the carrier is going to fetch it. |
904 | 307 | */ | 370 | */ |
905 | 308 | bool Carrier::notify_ware(Game& game, int32_t const flag) { | 371 | bool Carrier::notify_ware(Game& game, int32_t const flag) { |
906 | 309 | State& state = top_state(); | 372 | State& state = top_state(); |
907 | 310 | 373 | ||
917 | 311 | if (operation_ == WAIT) { | 374 | // Check if we've already acked something |
918 | 312 | if (state.objvar1.get(game) == | 375 | if (promised_pickup_to_ != NOONE) { |
919 | 313 | &dynamic_cast<Road&>(*get_location(game)).get_flag(static_cast<Road::FlagId>(flag))) { | 376 | return false; |
920 | 314 | operation_ = flag; | 377 | } |
921 | 315 | send_signal(game, "wakeup"); | 378 | |
922 | 316 | return true; | 379 | // If we are currently in a transport. |
923 | 317 | } | 380 | // Explanation: |
924 | 318 | } else if (operation_ == NO_OPERATION) { | 381 | // a) a different carrier / road may be better suited for this ware |
925 | 319 | operation_ = flag; | 382 | // (the transport code does not have priorities for the actual |
926 | 383 | // carrier that is notified) | ||
927 | 384 | // b) the transport task has logic that allows it to | ||
928 | 385 | // drop a ware on an overloaded flag iff it can pick up a ware | ||
929 | 386 | // at the same time. | ||
930 | 387 | // We should ack said ware to avoid more confusion before we move | ||
931 | 388 | // onto the flag, but we can't do that if we have already acked | ||
932 | 389 | // something. | ||
933 | 390 | // c) we might ack for a flag that we are actually moving away from; | ||
934 | 391 | // this will get us into trouble if wares have arrived on the other | ||
935 | 392 | // flag while we couldn't ack them. | ||
936 | 393 | // | ||
937 | 394 | // (Maybe the need for this lengthy explanation is proof that the | ||
938 | 395 | // ack system needs to be reworked.) | ||
939 | 396 | if (State const* const transport = get_state(taskTransport)) | ||
940 | 397 | if ((transport->ivar1 == -1 && find_closest_flag(game) != flag) || flag == transport->ivar1) | ||
941 | 398 | return false; | ||
942 | 399 | |||
943 | 400 | // Ack it if we haven't | ||
944 | 401 | promised_pickup_to_ = flag; | ||
945 | 402 | |||
946 | 403 | if (state.task == &taskRoad) { | ||
947 | 320 | send_signal(game, "ware"); | 404 | send_signal(game, "ware"); |
949 | 321 | return true; | 405 | } else if (state.task == &taskWaitforcapacity) { |
950 | 406 | send_signal(game, "wakeup"); | ||
951 | 322 | } | 407 | } |
954 | 323 | 408 | return true; | |
953 | 324 | return false; | ||
955 | 325 | } | 409 | } |
956 | 326 | 410 | ||
957 | 327 | /** | 411 | /** |
961 | 328 | * Find a pending ware meant for our road, | 412 | * Find a pending ware on one of the road's flags, ack it and set promised_pickup_to_ |
962 | 329 | * remove its pending status, and | 413 | * accordingly. |
960 | 330 | * \return the flag it is on. | ||
963 | 331 | */ | 414 | */ |
967 | 332 | int32_t Carrier::find_source_flag(Game& game) { | 415 | void Carrier::find_pending_ware(Game& game) { |
965 | 333 | assert(operation_ == INIT); | ||
966 | 334 | |||
968 | 335 | Road& road = dynamic_cast<Road&>(*get_location(game)); | 416 | Road& road = dynamic_cast<Road&>(*get_location(game)); |
982 | 336 | int32_t near = find_closest_flag(game); | 417 | uint32_t havewarebits = 0; |
983 | 337 | Flag& nearflag = road.get_flag(static_cast<Road::FlagId>(near)); | 418 | |
984 | 338 | Flag& farflag = road.get_flag(static_cast<Road::FlagId>(near ^ 1)); | 419 | assert(promised_pickup_to_ == NOONE); |
985 | 339 | 420 | ||
986 | 340 | Flag::PendingWare* pw; | 421 | if (road.get_flag(Road::FlagStart).has_pending_ware(game, road.get_flag(Road::FlagEnd))) { |
987 | 341 | if ((pw = nearflag.get_ware_for_flag(farflag))) { | 422 | havewarebits |= 1; |
988 | 342 | pw->pending = false; | 423 | } |
989 | 343 | return near; | 424 | |
990 | 344 | } else if ((pw = farflag.get_ware_for_flag(nearflag, kPendingOnly))) { | 425 | if (road.get_flag(Road::FlagEnd).has_pending_ware(game, road.get_flag(Road::FlagStart))) { |
991 | 345 | pw->pending = false; | 426 | havewarebits |= 2; |
992 | 346 | return near ^ 1; | 427 | } |
993 | 347 | } else { | 428 | |
994 | 348 | return NO_OPERATION; | 429 | // If both flags have a ware, we pick the one closer to us. |
995 | 430 | if (havewarebits == 3) { | ||
996 | 431 | havewarebits = 1 << find_closest_flag(game); | ||
997 | 432 | } | ||
998 | 433 | |||
999 | 434 | // Ack our decision | ||
1000 | 435 | if (havewarebits == 1) { | ||
1001 | 436 | promised_pickup_to_ = START_FLAG; | ||
1002 | 437 | if (!road.get_flag(Road::FlagStart).ack_pickup(game, road.get_flag(Road::FlagEnd))) { | ||
1003 | 438 | throw wexception("Carrier::find_pending_ware: start flag is messed up"); | ||
1004 | 439 | } | ||
1005 | 440 | |||
1006 | 441 | } else if (havewarebits == 2) { | ||
1007 | 442 | promised_pickup_to_ = END_FLAG; | ||
1008 | 443 | if (!road.get_flag(Road::FlagEnd).ack_pickup(game, road.get_flag(Road::FlagStart))) { | ||
1009 | 444 | throw wexception("Carrier::find_pending_ware: end flag is messed up"); | ||
1010 | 445 | } | ||
1011 | 349 | } | 446 | } |
1012 | 350 | } | 447 | } |
1013 | 351 | 448 | ||
1014 | @@ -418,7 +515,7 @@ | |||
1015 | 418 | 515 | ||
1016 | 419 | Worker::log_general_info(egbase); | 516 | Worker::log_general_info(egbase); |
1017 | 420 | 517 | ||
1019 | 421 | molog("operation = %i\n", operation_); | 518 | molog("promised_pickup_to = %i\n", promised_pickup_to_); |
1020 | 422 | } | 519 | } |
1021 | 423 | 520 | ||
1022 | 424 | /* | 521 | /* |
1023 | @@ -428,7 +525,7 @@ | |||
1024 | 428 | 525 | ||
1025 | 429 | ============================== | 526 | ============================== |
1026 | 430 | */ | 527 | */ |
1028 | 431 | constexpr uint8_t kCurrentPacketVersion = 2; | 528 | constexpr uint8_t kCurrentPacketVersion = 3; |
1029 | 432 | 529 | ||
1030 | 433 | Carrier::Loader::Loader() { | 530 | Carrier::Loader::Loader() { |
1031 | 434 | } | 531 | } |
1032 | @@ -437,10 +534,12 @@ | |||
1033 | 437 | Worker::Loader::load(fr); | 534 | Worker::Loader::load(fr); |
1034 | 438 | 535 | ||
1035 | 439 | try { | 536 | try { |
1038 | 440 | uint8_t packet_version = fr.unsigned_8(); | 537 | const uint8_t packet_version = fr.unsigned_8(); |
1039 | 441 | if (packet_version == kCurrentPacketVersion) { | 538 | // TODO(GunChleoc): Remove savegame compatibility after Build 21. |
1040 | 539 | if (packet_version <= kCurrentPacketVersion && packet_version >= 1) { | ||
1041 | 442 | Carrier& carrier = get<Carrier>(); | 540 | Carrier& carrier = get<Carrier>(); |
1043 | 443 | carrier.operation_ = fr.signed_32(); | 541 | // TODO(GunChleoc): std::min is for savegame compatibility. Remove after Build 21. |
1044 | 542 | carrier.promised_pickup_to_ = std::min(-1, fr.signed_32()); | ||
1045 | 444 | } else { | 543 | } else { |
1046 | 445 | throw UnhandledVersionError("Carrier", packet_version, kCurrentPacketVersion); | 544 | throw UnhandledVersionError("Carrier", packet_version, kCurrentPacketVersion); |
1047 | 446 | } | 545 | } |
1048 | @@ -465,7 +564,7 @@ | |||
1049 | 465 | Worker::do_save(egbase, mos, fw); | 564 | Worker::do_save(egbase, mos, fw); |
1050 | 466 | 565 | ||
1051 | 467 | fw.unsigned_8(kCurrentPacketVersion); | 566 | fw.unsigned_8(kCurrentPacketVersion); |
1053 | 468 | fw.signed_32(operation_); | 567 | fw.signed_32(promised_pickup_to_); |
1054 | 469 | } | 568 | } |
1055 | 470 | 569 | ||
1056 | 471 | CarrierDescr::CarrierDescr(const std::string& init_descname, | 570 | CarrierDescr::CarrierDescr(const std::string& init_descname, |
1057 | 472 | 571 | ||
1058 | === modified file 'src/logic/map_objects/tribes/carrier.h' | |||
1059 | --- src/logic/map_objects/tribes/carrier.h 2018-09-04 15:48:47 +0000 | |||
1060 | +++ src/logic/map_objects/tribes/carrier.h 2018-11-26 06:43:43 +0000 | |||
1061 | @@ -24,7 +24,6 @@ | |||
1062 | 24 | #include "logic/map_objects/tribes/worker.h" | 24 | #include "logic/map_objects/tribes/worker.h" |
1063 | 25 | 25 | ||
1064 | 26 | namespace Widelands { | 26 | namespace Widelands { |
1065 | 27 | class PendingWare; | ||
1066 | 28 | 27 | ||
1067 | 29 | class CarrierDescr : public WorkerDescr { | 28 | class CarrierDescr : public WorkerDescr { |
1068 | 30 | public: | 29 | public: |
1069 | @@ -50,7 +49,7 @@ | |||
1070 | 50 | MO_DESCR(CarrierDescr) | 49 | MO_DESCR(CarrierDescr) |
1071 | 51 | 50 | ||
1072 | 52 | explicit Carrier(const CarrierDescr& carrier_descr) | 51 | explicit Carrier(const CarrierDescr& carrier_descr) |
1074 | 53 | : Worker(carrier_descr), operation_(NO_OPERATION) { | 52 | : Worker(carrier_descr), promised_pickup_to_(NOONE) { |
1075 | 54 | } | 53 | } |
1076 | 55 | ~Carrier() override { | 54 | ~Carrier() override { |
1077 | 56 | } | 55 | } |
1078 | @@ -67,7 +66,7 @@ | |||
1079 | 67 | static Task const taskRoad; | 66 | static Task const taskRoad; |
1080 | 68 | 67 | ||
1081 | 69 | private: | 68 | private: |
1083 | 70 | int32_t find_source_flag(Game&); | 69 | void find_pending_ware(Game&); |
1084 | 71 | int32_t find_closest_flag(Game&); | 70 | int32_t find_closest_flag(Game&); |
1085 | 72 | 71 | ||
1086 | 73 | // internal task stuff | 72 | // internal task stuff |
1087 | @@ -78,14 +77,17 @@ | |||
1088 | 78 | static Task const taskTransport; | 77 | static Task const taskTransport; |
1089 | 79 | 78 | ||
1090 | 80 | void deliver_to_building(Game&, State&); | 79 | void deliver_to_building(Game&, State&); |
1091 | 80 | void pickup_from_flag(Game&, State&); | ||
1092 | 81 | void drop_ware(Game&, State&); | ||
1093 | 82 | void enter_building(Game&, State&); | ||
1094 | 83 | bool swap_or_wait(Game&, State&); | ||
1095 | 81 | 84 | ||
1096 | 85 | /// -1: no ware acked; 0/1: acked ware for start/end flag of road | ||
1097 | 82 | // This should be an enum, but this clutters the code with too many casts | 86 | // This should be an enum, but this clutters the code with too many casts |
1104 | 83 | static const int32_t INIT = -3; // ready to undertake or resume operations | 87 | static const int32_t NOONE = -1; |
1105 | 84 | static const int32_t WAIT = -2; // waiting for flag capacity | 88 | static const int32_t START_FLAG = 0; |
1106 | 85 | static const int32_t NO_OPERATION = -1; // idling | 89 | static const int32_t END_FLAG = 1; |
1107 | 86 | static const int32_t START_FLAG = 0; // serving start flag of road | 90 | int32_t promised_pickup_to_; |
1102 | 87 | static const int32_t END_FLAG = 1; // serving end flag of road | ||
1103 | 88 | int32_t operation_; | ||
1108 | 89 | 91 | ||
1109 | 90 | // saving and loading | 92 | // saving and loading |
1110 | 91 | protected: | 93 | protected: |
1111 | 92 | 94 | ||
1112 | === modified file 'src/logic/map_objects/tribes/worker.cc' | |||
1113 | --- src/logic/map_objects/tribes/worker.cc 2018-11-23 21:26:24 +0000 | |||
1114 | +++ src/logic/map_objects/tribes/worker.cc 2018-11-26 06:43:43 +0000 | |||
1115 | @@ -137,11 +137,10 @@ | |||
1116 | 137 | totalres += amount; | 137 | totalres += amount; |
1117 | 138 | totalchance += 8 * amount; | 138 | totalchance += 8 * amount; |
1118 | 139 | 139 | ||
1122 | 140 | // Add penalty for fields that are running out | 140 | // Add penalty for fields that are running out |
1120 | 141 | // Except for totally depleted fields or wrong ressource fields | ||
1121 | 142 | // if we already know there is no ressource (left) we won't mine there | ||
1123 | 143 | if (amount == 0) | 141 | if (amount == 0) |
1125 | 144 | totalchance += 0; | 142 | // we already know it's completely empty, so punish is less |
1126 | 143 | totalchance += 1; | ||
1127 | 145 | else if (amount <= 2) | 144 | else if (amount <= 2) |
1128 | 146 | totalchance += 6; | 145 | totalchance += 6; |
1129 | 147 | else if (amount <= 4) | 146 | else if (amount <= 4) |
1130 | @@ -1820,11 +1819,12 @@ | |||
1131 | 1820 | if (upcast(Flag, flag, pos)) { | 1819 | if (upcast(Flag, flag, pos)) { |
1132 | 1821 | // Is this "our" flag? | 1820 | // Is this "our" flag? |
1133 | 1822 | if (flag->get_building() == location) { | 1821 | if (flag->get_building() == location) { |
1139 | 1823 | WareInstance* const ware = get_carried_ware(game); | 1822 | if (state.ivar1 && flag->has_capacity()) { |
1140 | 1824 | if (state.ivar1 && ware && flag->has_capacity_for_ware(*ware)) { | 1823 | if (WareInstance* const ware = fetch_carried_ware(game)) { |
1141 | 1825 | flag->add_ware(game, *fetch_carried_ware(game)); | 1824 | flag->add_ware(game, *ware); |
1142 | 1826 | set_animation(game, descr().get_animation("idle")); | 1825 | set_animation(game, descr().get_animation("idle")); |
1143 | 1827 | return schedule_act(game, 20); // rest a while | 1826 | return schedule_act(game, 20); // rest a while |
1144 | 1827 | } | ||
1145 | 1828 | } | 1828 | } |
1146 | 1829 | 1829 | ||
1147 | 1830 | // Don't try to enter building if it is a dismantle site | 1830 | // Don't try to enter building if it is a dismantle site |
1148 | @@ -2057,18 +2057,16 @@ | |||
1149 | 2057 | if (ware) { | 2057 | if (ware) { |
1150 | 2058 | // We're in the building, walk onto the flag | 2058 | // We're in the building, walk onto the flag |
1151 | 2059 | if (upcast(Building, building, location)) { | 2059 | if (upcast(Building, building, location)) { |
1157 | 2060 | Flag& baseflag = building->base_flag(); | 2060 | if (start_task_waitforcapacity(game, building->base_flag())) { |
1158 | 2061 | if (baseflag.has_capacity_for_ware(*ware)) { | 2061 | return; |
1154 | 2062 | start_task_leavebuilding(game, false); // exit throttle | ||
1155 | 2063 | } else { | ||
1156 | 2064 | start_task_waitforcapacity(game, baseflag); | ||
1159 | 2065 | } | 2062 | } |
1161 | 2066 | return; | 2063 | |
1162 | 2064 | return start_task_leavebuilding(game, false); // exit throttle | ||
1163 | 2067 | } | 2065 | } |
1164 | 2068 | 2066 | ||
1165 | 2069 | // We're on the flag, drop the ware and pause a little | 2067 | // We're on the flag, drop the ware and pause a little |
1166 | 2070 | if (upcast(Flag, flag, location)) { | 2068 | if (upcast(Flag, flag, location)) { |
1168 | 2071 | if (flag->has_capacity_for_ware(*ware)) { | 2069 | if (flag->has_capacity()) { |
1169 | 2072 | flag->add_ware(game, *fetch_carried_ware(game)); | 2070 | flag->add_ware(game, *fetch_carried_ware(game)); |
1170 | 2073 | 2071 | ||
1171 | 2074 | set_animation(game, descr().get_animation("idle")); | 2072 | set_animation(game, descr().get_animation("idle")); |
1172 | @@ -2148,11 +2146,9 @@ | |||
1173 | 2148 | 2146 | ||
1174 | 2149 | // The ware has decided that it doesn't want to go to us after all | 2147 | // The ware has decided that it doesn't want to go to us after all |
1175 | 2150 | // In order to return to the warehouse, we're switching to State_DropOff | 2148 | // In order to return to the warehouse, we're switching to State_DropOff |
1176 | 2151 | Flag& flag = dynamic_cast<Flag&>(*location); | ||
1177 | 2152 | if (WareInstance* const ware = | 2149 | if (WareInstance* const ware = |
1179 | 2153 | flag.fetch_pending_ware(game, flag.find_pending_ware(employer))) { | 2150 | dynamic_cast<Flag&>(*location).fetch_pending_ware(game, employer)) { |
1180 | 2154 | set_carried_ware(game, ware); | 2151 | set_carried_ware(game, ware); |
1181 | 2155 | flag.ware_departing(game); | ||
1182 | 2156 | } | 2152 | } |
1183 | 2157 | 2153 | ||
1184 | 2158 | set_animation(game, descr().get_animation("idle")); | 2154 | set_animation(game, descr().get_animation("idle")); |
1185 | @@ -2215,15 +2211,25 @@ | |||
1186 | 2215 | static_cast<Bob::Ptr>(&Worker::waitforcapacity_pop), true}; | 2211 | static_cast<Bob::Ptr>(&Worker::waitforcapacity_pop), true}; |
1187 | 2216 | 2212 | ||
1188 | 2217 | /** | 2213 | /** |
1191 | 2218 | * Pushes a wait task and | 2214 | * Checks the capacity of the flag. |
1192 | 2219 | * adds the worker to the flag's wait queue. | 2215 | * |
1193 | 2216 | * If there is none, a wait task is pushed, and the worker is added to the | ||
1194 | 2217 | * flag's wait queue. The function returns true in this case. | ||
1195 | 2218 | * If the flag still has capacity, the function returns false and doesn't | ||
1196 | 2219 | * act at all. | ||
1197 | 2220 | */ | 2220 | */ |
1199 | 2221 | void Worker::start_task_waitforcapacity(Game& game, Flag& flag) { | 2221 | bool Worker::start_task_waitforcapacity(Game& game, Flag& flag) { |
1200 | 2222 | if (flag.has_capacity()) { | ||
1201 | 2223 | return false; | ||
1202 | 2224 | } | ||
1203 | 2225 | |||
1204 | 2222 | push_task(game, taskWaitforcapacity); | 2226 | push_task(game, taskWaitforcapacity); |
1205 | 2223 | 2227 | ||
1206 | 2224 | top_state().objvar1 = &flag; | 2228 | top_state().objvar1 = &flag; |
1207 | 2225 | 2229 | ||
1208 | 2226 | flag.wait_for_capacity(game, *this); | 2230 | flag.wait_for_capacity(game, *this); |
1209 | 2231 | |||
1210 | 2232 | return true; | ||
1211 | 2227 | } | 2233 | } |
1212 | 2228 | 2234 | ||
1213 | 2229 | void Worker::waitforcapacity_update(Game& game, State&) { | 2235 | void Worker::waitforcapacity_update(Game& game, State&) { |
1214 | 2230 | 2236 | ||
1215 | === modified file 'src/logic/map_objects/tribes/worker.h' | |||
1216 | --- src/logic/map_objects/tribes/worker.h 2018-09-14 08:46:36 +0000 | |||
1217 | +++ src/logic/map_objects/tribes/worker.h 2018-11-26 06:43:43 +0000 | |||
1218 | @@ -163,7 +163,7 @@ | |||
1219 | 163 | void start_task_releaserecruit(Game&, Worker&); | 163 | void start_task_releaserecruit(Game&, Worker&); |
1220 | 164 | void start_task_fetchfromflag(Game&); | 164 | void start_task_fetchfromflag(Game&); |
1221 | 165 | 165 | ||
1223 | 166 | void start_task_waitforcapacity(Game&, Flag&); | 166 | bool start_task_waitforcapacity(Game&, Flag&); |
1224 | 167 | void start_task_leavebuilding(Game&, bool changelocation); | 167 | void start_task_leavebuilding(Game&, bool changelocation); |
1225 | 168 | void start_task_fugitive(Game&); | 168 | void start_task_fugitive(Game&); |
1226 | 169 | 169 |
Continuous integration builds have changed state:
Travis build 4272. State: errored. Details: https:/ /travis- ci.org/ widelands/ widelands/ builds/ 458903460. /ci.appveyor. com/project/ widelands- dev/widelands/ build/_ widelands_ dev_widelands_ remove_ anti_congestion _algorithm- 4066.
Appveyor build 4066. State: success. Details: https:/