| 1 | // This stub must be already present when loading ResourceSupply.js as it is |
| 2 | // needed for the ResourceSupply schema definition which is built on load |
| 3 | Resources = |
| 4 | { |
| 5 | "BuildChoicesSchema" : function () { }, |
| 6 | "GetNames" : function () { return {"type1":{}}; }, |
| 7 | "GetResource" : |
| 8 | function () { |
| 9 | return { |
| 10 | "subtypes": {"type1" : {}} |
| 11 | }; |
| 12 | } |
| 13 | }; |
| 14 | |
| 15 | Engine.LoadComponentScript("interfaces/ResourceSupply.js"); |
| 16 | Engine.LoadComponentScript("ResourceSupply.js"); |
| 17 | |
| 18 | /** |
| 19 | * @summary Ensures consistent behavior of IsAvailable() for already-gathering units |
| 20 | * @description When a gatherer has been attached to a resource supply, IsAvailable() |
| 21 | * shall still return true for that gatherer, so a simple test of "max |
| 22 | * number of gatherers < actual number of gatherers" is not sufficient: |
| 23 | * The resource supply may be crowded up and don't accept any futher |
| 24 | * gatherers, but these already present may continue to work |
| 25 | * @param template {Object} DOM of the ResourceSupply template definition (as if loaded |
| 26 | * from XML files) |
| 27 | * @return undefined |
| 28 | */ |
| 29 | function entityGatheringCanContinue(template) { |
| 30 | ResetState(); |
| 31 | |
| 32 | AddMock(SYSTEM_ENTITY, IID_PlayerManager, { |
| 33 | GetNumPlayers: function() { return 1; } |
| 34 | }); |
| 35 | |
| 36 | var gathererId = 3; |
| 37 | var playerId = 1; |
| 38 | var treasureId = 2; |
| 39 | |
| 40 | var testSupply = ConstructComponent(treasureId, "ResourceSupply", template); |
| 41 | |
| 42 | TS_ASSERT(testSupply.IsAvailable(playerId)); |
| 43 | testSupply.AddGatherer(playerId, gathererId); |
| 44 | |
| 45 | TS_ASSERT_EQUALS(testSupply.GetNumGatherers(), 1); |
| 46 | TS_ASSERT_EQUALS(testSupply.GetMaxGatherers(), 1); |
| 47 | TS_ASSERT(testSupply.IsAvailable(playerId, gathererId)); |
| 48 | }; |
| 49 | |
| 50 | // Test cases to ensure that gatherers already working on a resource are granted |
| 51 | // subsequent access to it |
| 52 | entityGatheringCanContinue( |
| 53 | { |
| 54 | "Amount" : 100, |
| 55 | "MaxGatherers" : 1, |
| 56 | "Type" : "treasure.type1" |
| 57 | }); |
| 58 | entityGatheringCanContinue( |
| 59 | { |
| 60 | "Amount" : 100, |
| 61 | "MaxGatherers" : 1, |
| 62 | "Type" : "generic.type1" |
| 63 | }); |
| 64 | |
| 65 | /** |
| 66 | * @summary Ensures normal resource supplies allow only as many concurrent gatherers |
| 67 | * as defined in the template, not caring who they are. |
| 68 | * @return undefined |
| 69 | */ |
| 70 | function normalResourcesAllowOnlyMaxGatherersConcurrently() { |
| 71 | ResetState(); |
| 72 | |
| 73 | AddMock(SYSTEM_ENTITY, IID_PlayerManager, { |
| 74 | GetNumPlayers: function() { return 2; } |
| 75 | }); |
| 76 | |
| 77 | var gathererId1_Player1 = 3; |
| 78 | var gathererId2_Player1 = 5; |
| 79 | var gathererId_Player2 = 4; |
| 80 | var treasureId = 2; |
| 81 | |
| 82 | var testSupply = ConstructComponent(treasureId, "ResourceSupply", |
| 83 | { |
| 84 | "Amount" : 100, |
| 85 | "MaxGatherers" : 1, |
| 86 | "Type" : "generic.type1" |
| 87 | }); |
| 88 | // Player 1 approaches it |
| 89 | testSupply.AddGatherer(1, gathererId1_Player1); |
| 90 | // and no second gatherer from player 1 is allowed |
| 91 | TS_ASSERT(!testSupply.IsAvailable(1, gathererId2_Player1)); |
| 92 | // also, no other player may access it at the same time |
| 93 | TS_ASSERT(!testSupply.IsAvailable(1, gathererId_Player2)); |
| 94 | }; |
| 95 | |
| 96 | normalResourcesAllowOnlyMaxGatherersConcurrently(); |
| 97 | |
| 98 | /** |
| 99 | * @summary Ensures that treasures grant access to multiple players independently. |
| 100 | * @description Usual treasure max limit is 1 (since they are instant pick-up), so |
| 101 | * using the same gathering limits as for normal resources would allow |
| 102 | * a player to hold out a treasure of all other players while he tries |
| 103 | * to grab it. |
| 104 | * Instead, each player may send up to one gatherer to it and the fastest |
| 105 | * one wins. |
| 106 | * @return undefined |
| 107 | */ |
| 108 | function multiplePlayersMayHuntForSameTreasureConcurrently() { |
| 109 | ResetState(); |
| 110 | |
| 111 | AddMock(SYSTEM_ENTITY, IID_PlayerManager, { |
| 112 | GetNumPlayers: function() { return 2; } |
| 113 | }); |
| 114 | |
| 115 | var gathererId_Player1 = 3; |
| 116 | var gathererId_Player2 = 4; |
| 117 | var treasureId = 2; |
| 118 | |
| 119 | var testSupply = ConstructComponent(treasureId, "ResourceSupply", |
| 120 | { |
| 121 | "Amount" : 100, |
| 122 | "MaxGatherers" : 1, |
| 123 | "Type" : "treasure.type1" |
| 124 | }); |
| 125 | // Player 1 approaches it |
| 126 | testSupply.AddGatherer(1, gathererId_Player1); |
| 127 | // and player 2 is still allowed to try as well |
| 128 | TS_ASSERT(testSupply.IsAvailable(2, gathererId_Player2)); |
| 129 | }; |
| 130 | |
| 131 | multiplePlayersMayHuntForSameTreasureConcurrently(); |
| 132 | |