Ticket #2732: extend_looter_to_transfer_carried_resources_and_in_the_looted_entity_garrisoned_entities.diff

File extend_looter_to_transfer_carried_resources_and_in_the_looted_entity_garrisoned_entities.diff, 7.1 KB (added by Radagast, 10 years ago)
  • binaries/data/mods/public/simulation/components/Looter.js

    diff --git a/binaries/data/mods/public/simulation/components/Looter.js b/binaries/data/mods/public/simulation/components/Looter.js
    index 87577e9..fe98468 100644
    a b Looter.prototype.Collect = function(targetEntity)  
    4444            cmpPlayer.AddResources(resourcesToAdd);
    4545        }
    4646    }
     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 targetCarriedEntities_index = -1;
     132            while (freeGarrisonSpotCount > 0 && ++targetCarriedEntities_index < targetNonEjectedCarriedEntities.length)
     133            {
     134                var targetCarriedEntity = targetNonEjectedCarriedEntities[targetCarriedEntities_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                var carriedEntityClasses = carriedEntity.GetClassesList();
     138                if (carriedEntityClasses.length)
     139                {   
     140                    // Is one of the by the target carried entity's classes allowed to garrison inside our looting unit?
     141                    for each (var carriedEntityClass in carriedEntityClasses)
     142                    {
     143                        if (cmpGarrisonHolder.GetAllowedClasses().indexOf(carriedEntityClass) === -1)
     144                            continue;
     145                       
     146                        var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
     147                        if (!cmpOwnership)
     148                            break;
     149                        //warn('New Owner (looting entity): ' + cmpOwnership);
     150                        var cmpTargetEntityOwnership = Engine.QueryInterface(targetEntity, IID_Ownership);
     151                        var cmpCarriedEntityOwnership = Engine.QueryInterface(carriedEntity, IID_Ownership);
     152                        if (!cmpCarriedEntityOwnership)
     153                            break;
     154                        //warn('Old Owner : ' + cmpTargetOwnership);
     155                       
     156                        // 1) eject:
     157                        var is_forced = true;
     158                        cmpTargetGarrisonHolder.Eject(carriedEntity, is_forced);
     159                        // 2) change garrisoned entity's ownership:
     160                        // Fully convert to a normal unit of your own, the original ethnicity still recognizable.
     161                        cmpTargetEntityOwnership.SetOwner(cmpOwnership.GetOwner());
     162                        warn('The looting entity: ' + this.entity + ' (Owner: '+ cmpOwnership +') changed the ownership of the target entity: ' + carriedEntity + ' (Owner: '+ cmpCarriedEntityOwnership +' ).');
     163                        // Because it might have been an target-entity-allied entity that was garrisoned inside the target entity.
     164                        var cmpCarriedEntityPlayer = QueryOwnerInterface(targetEntity, IID_Player); // To allow to remove the resources from the looted entity's owning player.
     165                        Engine.PostMessage(this.entity, MT_OwnershipChanged, { "entity": carriedEntity,
     166            "from": cmpCarriedEntityPlayer.playerID, "to": cmpPlayer.playerID });
     167);
     168                        // 3) garrison entity inside our looting entity:
     169                        cmpGarrisonHolder.Garrison(carriedEntity);
     170                    }
     171                }                   
     172            }
     173        }
     174    }
     175
     176
     177
     178
     179
     180
    47181}
    48182
    49183Engine.RegisterComponentType(IID_Looter, "Looter", Looter);