diff -r c6737ac88e8f binaries/data/mods/public/simulation/components/ResourceGatherer.js
a
|
b
|
|
58 | 58 | |
59 | 59 | ResourceGatherer.prototype.Init = function() |
60 | 60 | { |
61 | | this.carrying = {}; // { type: integer amount currently carried } |
| 61 | this.carrying = {}; // { generic type: integer amount currently carried } |
62 | 62 | // (Note that this component supports carrying multiple types of resources, |
63 | 63 | // each with an independent capacity, but the rest of the game currently |
64 | 64 | // ensures and assumes we'll only be carrying one type at once) |
… |
… |
|
86 | 86 | }; |
87 | 87 | |
88 | 88 | /** |
89 | | * Returns the type of one particular resource this unit is |
| 89 | * Returns the generic type of one particular resource this unit is |
90 | 90 | * currently carrying, or undefined if none. |
91 | 91 | */ |
92 | 92 | ResourceGatherer.prototype.GetMainCarryingType = function() |
diff -r c6737ac88e8f binaries/data/mods/public/simulation/components/UnitAI.js
a
|
b
|
|
425 | 425 | }, |
426 | 426 | |
427 | 427 | "GATHER": { |
| 428 | "enter": function() { |
| 429 | // Remember the position of our target, if any, in case it disappears |
| 430 | // later and we want to head to its last known position |
| 431 | // (TODO: if the target moves a lot (e.g. it's an animal), maybe we |
| 432 | // need to update this lastPos regularly rather than just on enter?) |
| 433 | var cmpTargetPosition = Engine.QueryInterface(this.order.data.target, IID_Position); |
| 434 | if (cmpTargetPosition && cmpTargetPosition.IsInWorld()) |
| 435 | this.order.data.lastPos = cmpTargetPosition.GetPosition(); |
| 436 | }, |
| 437 | |
428 | 438 | "APPROACHING": { |
429 | | "enter": function () { |
| 439 | "enter": function() { |
430 | 440 | this.SelectAnimation("move"); |
431 | 441 | }, |
432 | 442 | |
… |
… |
|
500 | 510 | // return to the nearest dropsite |
501 | 511 | if (status.filled) |
502 | 512 | { |
503 | | var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); |
504 | | |
505 | | // Find dropsites owned by this unit's player |
506 | | var players = []; |
507 | | var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); |
508 | | if (cmpOwnership) |
509 | | players.push(cmpOwnership.GetOwner()); |
510 | | |
511 | | var dropsites = cmpRangeManager.ExecuteQuery(this.entity, 0, -1, players, IID_ResourceDropsite); |
512 | | |
513 | | // Try to find the first (nearest) dropsite which supports this resource type |
514 | | for each (var dropsite in dropsites) |
| 513 | var nearby = this.FindNearestDropsite(this.order.data.type.generic); |
| 514 | if (nearby) |
515 | 515 | { |
516 | | var cmpDropsite = Engine.QueryInterface(dropsite, IID_ResourceDropsite); |
517 | | if (!cmpDropsite.AcceptsType(this.order.data.type.generic)) |
518 | | continue; |
519 | | |
520 | | // This dropsite is okay - return our resources to it |
521 | | this.PushOrderFront("ReturnResource", { "target": dropsite }); |
| 516 | // (Keep this Gather order on the stack so we'll |
| 517 | // continue gathering after returning) |
| 518 | this.PushOrderFront("ReturnResource", { "target": nearby }); |
522 | 519 | return; |
523 | 520 | } |
524 | 521 | |
525 | | // Oh no, couldn't find any drop sites. |
526 | | // Give up and stand here like a lemon. |
| 522 | // Oh no, couldn't find any drop sites. Give up on gathering. |
| 523 | this.FinishOrder(); |
527 | 524 | } |
528 | 525 | } |
529 | 526 | else |
530 | 527 | { |
531 | | // Try to follow it |
| 528 | // Try to follow the target |
532 | 529 | if (this.MoveToTargetRange(this.order.data.target, IID_ResourceGatherer)) |
533 | 530 | { |
534 | 531 | this.SetNextState("APPROACHING"); |
| 532 | return; |
535 | 533 | } |
536 | | else |
| 534 | |
| 535 | // Can't reach the target, or it doesn't exist any more |
| 536 | |
| 537 | // We want to carry on gathering resources in the same area as |
| 538 | // the old one. So try to get close to the old resource's |
| 539 | // last known position |
| 540 | |
| 541 | if (this.order.data.lastPos && |
| 542 | this.MoveToPointRange(this.order.data.lastPos.x, this.order.data.lastPos.z, |
| 543 | IID_ResourceGatherer)) |
537 | 544 | { |
538 | | // Save the current order's type in case we need it later |
539 | | var oldType = this.order.data.type; |
| 545 | this.SetNextState("APPROACHING"); |
| 546 | return; |
| 547 | } |
540 | 548 | |
541 | | // Can't reach it, or it doesn't exist any more - give up on this order |
542 | | if (this.FinishOrder()) |
543 | | return; |
| 549 | // We're already in range, or can't get anywhere near it. |
544 | 550 | |
545 | | // No remaining orders - pick a useful default behaviour |
| 551 | // Save the current order's type in case we need it later |
| 552 | var oldType = this.order.data.type; |
546 | 553 | |
547 | | // Try to find a nearby target of the same type |
| 554 | // Give up on this order and try our next queued order |
| 555 | if (this.FinishOrder()) |
| 556 | return; |
548 | 557 | |
549 | | var nearby = this.FindNearbyResource(oldType); |
550 | | if (nearby) |
551 | | { |
552 | | this.Gather(nearby, true); |
553 | | return; |
554 | | } |
| 558 | // No remaining orders - pick a useful default behaviour |
555 | 559 | |
556 | | // Nothing else to gather - just give up |
| 560 | // Try to find a new resource of the same type near our current position: |
| 561 | |
| 562 | var nearby = this.FindNearbyResource(oldType); |
| 563 | if (nearby) |
| 564 | { |
| 565 | this.Gather(nearby, true); |
| 566 | return; |
557 | 567 | } |
| 568 | |
| 569 | // Nothing else to gather - if we're carrying anything then we should |
| 570 | // drop it off, and if not then we might as well head to the dropsite |
| 571 | // anyway because that's a nice enough place to congregate and idle |
| 572 | |
| 573 | var nearby = this.FindNearestDropsite(oldType.generic); |
| 574 | if (nearby) |
| 575 | { |
| 576 | this.PushOrderFront("ReturnResource", { "target": nearby }); |
| 577 | return; |
| 578 | } |
| 579 | |
| 580 | // No dropsites - just give up |
558 | 581 | } |
559 | 582 | }, |
560 | 583 | }, |
… |
… |
|
577 | 600 | }, |
578 | 601 | |
579 | 602 | "MoveCompleted": function() { |
580 | | var cmpResourceDropsite = Engine.QueryInterface(this.order.data.target, IID_ResourceDropsite); |
581 | | if (cmpResourceDropsite) |
| 603 | // Check the dropsite really is in range |
| 604 | // (we didn't get stopped before reaching it) |
| 605 | if (this.CheckTargetRange(this.order.data.target, IID_ResourceGatherer)) |
582 | 606 | { |
583 | | // TODO: check the dropsite really is in range |
584 | | // (we didn't get stopped before reaching it) |
| 607 | var cmpResourceDropsite = Engine.QueryInterface(this.order.data.target, IID_ResourceDropsite); |
| 608 | if (cmpResourceDropsite) |
| 609 | { |
| 610 | // Dump any resources we can |
| 611 | var dropsiteTypes = cmpResourceDropsite.GetTypes(); |
585 | 612 | |
586 | | var dropsiteTypes = cmpResourceDropsite.GetTypes(); |
| 613 | var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); |
| 614 | cmpResourceGatherer.CommitResources(dropsiteTypes); |
587 | 615 | |
588 | | var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); |
589 | | cmpResourceGatherer.CommitResources(dropsiteTypes); |
590 | | } |
591 | | else |
592 | | { |
593 | | // The dropsite was destroyed or something. |
594 | | // TODO: We ought to look for a new one, probably. |
| 616 | // Our next order should always be a Gather, |
| 617 | // so just switch back to that order |
| 618 | this.FinishOrder(); |
| 619 | return; |
| 620 | } |
595 | 621 | } |
596 | 622 | |
| 623 | // The dropsite was destroyed, or we couldn't reach it. |
| 624 | // Look for a new one. |
| 625 | |
| 626 | var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer); |
| 627 | var genericType = cmpResourceGatherer.GetMainCarryingType(); |
| 628 | var nearby = this.FindNearestDropsite(genericType); |
| 629 | if (nearby) |
| 630 | { |
| 631 | this.FinishOrder(); |
| 632 | this.PushOrderFront("ReturnResource", { "target": nearby }); |
| 633 | return; |
| 634 | } |
| 635 | |
| 636 | // Oh no, couldn't find any drop sites. Give up on returning. |
597 | 637 | this.FinishOrder(); |
598 | 638 | }, |
599 | 639 | }, |
… |
… |
|
989 | 1029 | }; |
990 | 1030 | |
991 | 1031 | /** |
| 1032 | * Returns the entity ID of the nearest resource dropsite that accepts the given |
| 1033 | * type, excluding the one with ID 'exclude', |
| 1034 | * or undefined if none can be found. |
| 1035 | */ |
| 1036 | UnitAI.prototype.FindNearestDropsite = function(genericType, exclude) |
| 1037 | { |
| 1038 | // Find dropsites owned by this unit's player |
| 1039 | var players = []; |
| 1040 | var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); |
| 1041 | if (cmpOwnership) |
| 1042 | players.push(cmpOwnership.GetOwner()); |
| 1043 | |
| 1044 | var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); |
| 1045 | var nearby = rangeMan.ExecuteQuery(this.entity, 0, -1, players, IID_ResourceDropsite); |
| 1046 | for each (var ent in nearby) |
| 1047 | { |
| 1048 | if (ent == exclude) |
| 1049 | continue; |
| 1050 | |
| 1051 | var cmpDropsite = Engine.QueryInterface(ent, IID_ResourceDropsite); |
| 1052 | if (!cmpDropsite.AcceptsType(genericType)) |
| 1053 | continue; |
| 1054 | |
| 1055 | return ent; |
| 1056 | } |
| 1057 | |
| 1058 | return undefined; |
| 1059 | }; |
| 1060 | |
| 1061 | /** |
992 | 1062 | * Play a sound appropriate to the current entity. |
993 | 1063 | */ |
994 | 1064 | UnitAI.prototype.PlaySound = function(name) |
… |
… |
|
1066 | 1136 | return cmpUnitMotion.MoveToPointRange(x, z, 0, 0); |
1067 | 1137 | }; |
1068 | 1138 | |
| 1139 | UnitAI.prototype.MoveToPointRange = function(x, z, iid, type) |
| 1140 | { |
| 1141 | var cmpRanged = Engine.QueryInterface(this.entity, iid); |
| 1142 | var range = cmpRanged.GetRange(type); |
| 1143 | |
| 1144 | var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); |
| 1145 | return cmpUnitMotion.MoveToPointRange(x, z, range.min, range.max); |
| 1146 | }; |
| 1147 | |
1069 | 1148 | UnitAI.prototype.MoveToTarget = function(target) |
1070 | 1149 | { |
1071 | 1150 | var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion); |