| 47 | |
| 48 | |
| 49 | // If target entity has inventory component, add carried goods to loot too: |
| 50 | var cmpTargetPlayer = QueryOwnerInterface(targetEntity, IID_Player); // To allow to remove the resources from the looted entity's owning player. |
| 51 | var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); // Alternatively see gui/session/session.js GetExtendedEntityState via the C++ Engine.GuiInterfaceCall("GetExtendedEntityState", entId). |
| 52 | var entityState = cmpGuiInterface.GetExtendedEntityState(cmpPlayer.playerID, targetEntity); |
| 53 | var targetEntityState = cmpGuiInterface.GetExtendedEntityState(cmpTargetPlayer.playerID, targetEntity); |
| 54 | // TODO perhaps merge EntityState and ExtendedEntityState like in gui/session/session.js ? |
| 55 | // Resource carrying |
| 56 | if (targetEntityState.resourceCarrying && targetEntityState.resourceCarrying.length) |
| 57 | { |
| 58 | var resourcesToAdd = {}; |
| 59 | // We should only be carrying one resource type at once, nevertheless we should be ready for multiple resources: |
| 60 | // => sum up all carried resources, grouped by resource type (as required to be able to add it to our player). |
| 61 | for each (var targetCarriedResource in targetEntityState.resourceCarrying) |
| 62 | { |
| 63 | // The GUI has not to be updated because the to be looted enemy unit won't be selected and even if, then details won't be shown if it's not an ally. |
| 64 | //Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = false; |
| 65 | //Engine.GetGUIObjectByName("resourceCarryingText").hidden = false; |
| 66 | //Engine.GetGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/resources/"+carriedResource.type+".png"; |
| 67 | //Engine.GetGUIObjectByName("resourceCarryingText").caption = sprintf(translate("%(amount)s / %(max)s"), { amount: carriedResource.amount, max: carriedResource.max }); |
| 68 | |
| 69 | // Move the resource amount: |
| 70 | // --------------------------------------- |
| 71 | // EITHER (directly add to the player) |
| 72 | if (!resourcesToAdd[targetCarriedResource.type]) |
| 73 | resourceToAdd[targetCarriedResource.type] = 0; |
| 74 | if (targetCarriedResource.amount) |
| 75 | resourcesToAdd[targetCarriedResource.type] += +targetCarriedResource.amount; |
| 76 | // Reset the looted unit's resource carrying: |
| 77 | targetCarriedResource.amount = 0; |
| 78 | // Note: The player get the resources removed and added respectively after the loop. |
| 79 | |
| 80 | // --------------------------------------- |
| 81 | // OR (make the looting unit carry the resources) |
| 82 | // Do we have enough resource capacity? |
| 83 | var carriedResourceWithCorrectType = undefined; |
| 84 | // find correct resource type: |
| 85 | if (entityState.resourceCarrying && entityState.resourceCarrying.length) |
| 86 | { |
| 87 | for each (var carriedResource in entityState.resourceCarrying) |
| 88 | { |
| 89 | if (carriedResource.type == targetCarriedResource.type) |
| 90 | { |
| 91 | carriedResourceWithCorrectType = carriedResource; |
| 92 | break; |
| 93 | } |
| 94 | } |
| 95 | } |
| 96 | var freeSpaceAmount = 0; // TODO Query template for the maximum resource gather count! |
| 97 | if (!carriedResourceWithCorrectType) |
| 98 | { |
| 99 | var template = GetTemplate(entityState.template); |
| 100 | //TODO freeSpaceAmount = template.; |
| 101 | //TODO carriedResourceWithCorrectType = ; |
| 102 | } |
| 103 | else |
| 104 | freeSpaceAmount = carriedResourceWithCorrectType.max - carriedResourceWithCorrectType.amount; |
| 105 | // Transfer the resource amount: |
| 106 | if (freeSpaceAmount > 0) |
| 107 | { |
| 108 | carriedResourceWithCorrectType.amount += freeSpaceAmount; |
| 109 | targetCarriedResource.amount -= freeSpaceAmount; |
| 110 | } |
| 111 | //else nothing to add and nothing to substract. => no carrying resource loot. |
| 112 | |
| 113 | |
| 114 | } |
| 115 | cmpPlayer.AddResources(resourcesToAdd); |
| 116 | cmpTargetPlayer.RemoveResources(resourcesToAdd); |
| 117 | |
| 118 | } |
| 119 | |
| 120 | |
| 121 | // TODO generalize GarrisonHolder to EntityHolder/Inventory (renaming is enough, but pick-up garrison (read: entity) option has to be added!). |
| 122 | var cmpTargetGarrisonHolder = Engine.QueryInterface(targetEntity, IID_GarrisonHolder); |
| 123 | if (cmpTargetGarrisonHolder) |
| 124 | { |
| 125 | // Is our looting entity allowed to Garrison the carried entity inside itself? |
| 126 | var targetNonEjectedCarriedEntities = cmpTargetGarrisonHolder.GetEntities(); |
| 127 | if (targetNonEjectedCarriedEntities) |
| 128 | { |
| 129 | // Own capacity is already full? |
| 130 | var freeGarrisonSpotCount = cmpGarrisonHolder.GetCapacity() - cmpGarrisonHolder.GetGarrisonedEntitiesCount(); |
| 131 | var targetNonEjectedCarriedEntities_index = -1; |
| 132 | while (freeGarrisonSpotCount > 0 && ++targetNonEjectedCarriedEntities_index < targetNonEjectedCarriedEntities.length) |
| 133 | { |
| 134 | var targetCarriedEntity = targetNonEjectedCarriedEntities[targetNonEjectedCarriedEntities_index]; |
| 135 | //if (carriedEntity.amount) TODO allow for grouping of equal entities. (see the GUI where a number is used to show how many entities of the same type are garrisoned.) |
| 136 | // Is this entity allowed to carry/garrison the entity class the other unit carried? |
| 137 | if (!cmpGarrisonHolder.AllowedToGarrison(targetCarriedEntity)) |
| 138 | continue; |
| 139 | |
| 140 | //else garrison: |
| 141 | var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); |
| 142 | if (!cmpOwnership) |
| 143 | break; |
| 144 | //warn('New Owner (looting entity): ' + cmpOwnership); |
| 145 | var cmpTargetEntityOwnership = Engine.QueryInterface(targetEntity, IID_Ownership); |
| 146 | var cmpCarriedEntityOwnership = Engine.QueryInterface(carriedEntity, IID_Ownership); |
| 147 | if (!cmpCarriedEntityOwnership) |
| 148 | break; |
| 149 | //warn('Old Owner : ' + cmpTargetOwnership); |
| 150 | |
| 151 | // 1) eject: |
| 152 | var is_forced = true; |
| 153 | cmpTargetGarrisonHolder.Eject(carriedEntity, is_forced); |
| 154 | |
| 155 | // 2) change garrisoned entity's ownership: |
| 156 | // Fully convert to a normal unit of your own, the original ethnicity still recognizable. |
| 157 | cmpTargetEntityOwnership.SetOwner(cmpOwnership.GetOwner()); |
| 158 | warn('The looting entity: ' + this.entity + ' (Owner: '+ cmpOwnership +') changed the ownership of the target entity: ' + carriedEntity + ' (Owner: '+ cmpCarriedEntityOwnership +' ).'); |
| 159 | // Because it might have been an target-entity-allied entity that was garrisoned inside the target entity. |
| 160 | var cmpCarriedEntityPlayer = QueryOwnerInterface(targetEntity, IID_Player); // To allow to remove the resources from the looted entity's owning player. |
| 161 | Engine.PostMessage(this.entity, MT_OwnershipChanged, { "entity": carriedEntity, |
| 162 | "from": cmpCarriedEntityPlayer.playerID, "to": cmpPlayer.playerID }); |
| 163 | |
| 164 | // 3) garrison entity inside our looting entity: |
| 165 | cmpGarrisonHolder.Garrison(carriedEntity); |
| 166 | } |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | |
| 171 | |
| 172 | |
| 173 | |
| 174 | |