Ejemplo n.º 1
0
    public override void UpdateSystem()
    {
        ComponentDataFromEntity <Store>        storeLookup        = GetComponentDataFromEntity <Store>();
        ComponentDataFromEntity <ResourceNode> resourceNodeLookup = GetComponentDataFromEntity <ResourceNode>();

        EntityCommandBuffer.ParallelWriter ecb = m_EndSimECBSystem.CreateCommandBuffer().AsParallelWriter();
        NativeQueue <ResourceTypeValuePair> .ParallelWriter resourceQueueParallel = m_resourcesQueue.AsParallelWriter();

        Dependency = Entities
                     .WithReadOnly(storeLookup)
                     .WithReadOnly(resourceNodeLookup)
                     .WithAll <MovingToDepositState>()
                     .ForEach((Entity entity, int entityInQueryIndex, ref Harvester harvester, ref CurrentTarget currentTarget, ref DynamicBuffer <Command> commandBuffer, in Translation translation, in PreviousTarget previousTarget) =>
        {
            Store storeComponent = storeLookup[currentTarget.targetData.targetEntity];

            float dist  = math.distance(translation.Value, currentTarget.targetData.targetPos);
            float range = storeComponent.depositRadius + harvester.harvestRange;

            //Are we close enough to deposit yet?
            if (dist <= range)
            {
                if (harvester.currentlyCarryingAmount == 0)
                {
                    Debug.Log(" Nothing to deposit, empty command queue will return us to Idle state");
                    return;
                }

                Debug.Log($"Deposited { harvester.currentlyCarryingAmount } of { harvester.currentlyCarryingType }");

                //Add stuff to global resources queue and empty inventory.
                resourceQueueParallel.Enqueue(new ResourceTypeValuePair {
                    resourceType = harvester.currentlyCarryingType, resourceValue = harvester.currentlyCarryingAmount
                });

                harvester.currentlyCarryingAmount = 0;
                harvester.currentlyCarryingType   = ResourceType.None;

                //Complete the command as this command doesn't have an execution phase.
                CommandProcessSystem.CompleteCommand(ref commandBuffer);

                if (resourceNodeLookup.HasComponent(previousTarget.targetData.targetEntity))
                {
                    CommandProcessSystem.QueueCommand(CommandType.Harvest, commandBuffer, previousTarget.targetData, true);
                    Debug.Log($"Requesting switch to MoveToHarvest state for previously harvested resource node {previousTarget.targetData.targetEntity} of type {previousTarget.targetData.targetType}");
                }
                else
                {
                    Debug.Log($"Previously harvested resource node {previousTarget.targetData.targetEntity} of type {previousTarget.targetData.targetType} no longer exists, queueing new harvest command.");

                    CommandProcessSystem.QueueCommand(CommandType.Harvest, commandBuffer, new TargetData {
                        targetType = previousTarget.targetData.targetType
                    }, true);
                }
            }
        }).ScheduleParallel(Dependency);
Ejemplo n.º 2
0
    public override void UpdateSystem()
    {
        EntityCommandBuffer.ParallelWriter ecb = m_endSimECBSystem.CreateCommandBuffer().AsParallelWriter();

        ComponentDataFromEntity <ResourceNode> resourceNodeLookup = GetComponentDataFromEntity <ResourceNode>();

        JobHandle movingToHarvestHandle = Entities
                                          .WithReadOnly(resourceNodeLookup)
                                          .WithAll <MovingToHarvestState>()
                                          .ForEach((Entity entity, int entityInQueryIndex, ref Harvester harvester, ref CurrentTarget currentTarget, ref DynamicBuffer <Command> commandBuffer, in Translation translation) =>
        {
            if (!resourceNodeLookup.TryGetComponentDataFromEntity(currentTarget.targetData.targetEntity, out ResourceNode resourceNode))
            {
                Debug.Log($"Harvest node {currentTarget.targetData.targetEntity} destroyed when moving to it, finding nearby resource node of type {currentTarget.targetData.targetType} instead");

                CommandProcessSystem.CompleteCommand(ref commandBuffer);

                CommandProcessSystem.QueueCommand(CommandType.Harvest, commandBuffer, new TargetData {
                    targetType = currentTarget.targetData.targetType
                }, true);
                return;
            }

            //Get harvestable radius
            float dist  = math.distance(translation.Value, currentTarget.targetData.targetPos);
            float range = resourceNode.harvestableRadius + harvester.harvestRange;

            //Are we close enough to harvest yet?
            if (dist <= range)
            {
                //Move the command onto the execution phase
                CommandProcessSystem.ExecuteCommand(ref commandBuffer);

                //Set type we are harvesting + empty inventory if type is different
                ResourceNode resource = GetComponent <ResourceNode>(currentTarget.targetData.targetEntity);
                if (harvester.currentlyCarryingType != resource.resourceType)
                {
                    Debug.Log($"Harvesting type { resource.resourceType } setting carry amount to 0");

                    harvester.currentlyCarryingAmount = 0;
                    harvester.currentlyCarryingType   = resource.resourceType;
                }
            }
        }).ScheduleParallel(Dependency);

        float dt = Time.DeltaTime;

        EntityCommandBuffer.ParallelWriter ecb2 = m_endSimECBSystem.CreateCommandBuffer().AsParallelWriter();

        Dependency = Entities
                     .WithReadOnly(resourceNodeLookup)
                     .WithAll <HarvestingState>()
                     .ForEach((Entity entity, int entityInQueryIndex, ref Harvester harvester, ref CurrentTarget currentTarget, ref DynamicBuffer <Command> commandBuffer) =>
        {
            if (!resourceNodeLookup.TryGetComponentDataFromEntity(currentTarget.targetData.targetEntity, out ResourceNode resourceNode))
            {
                Debug.Log($"Harvest node {currentTarget.targetData.targetEntity} destroyed while harvesting it, finding nearby resource node of type {currentTarget.targetData.targetType} instead");

                //Complete the harvest command.
                CommandProcessSystem.CompleteCommand(ref commandBuffer);

                CommandProcessSystem.QueueCommand(CommandType.Harvest, commandBuffer, new TargetData {
                    targetType = currentTarget.targetData.targetType
                }, true);
                return;
            }

            //If harvest is on cd
            if (harvester.harvestTickTimer > 0)
            {
                //Cooling down
                harvester.harvestTickTimer -= dt;
                return;
            }
            //Put harvest on cd
            harvester.harvestTickTimer = harvester.harvestTickCooldown;

            //Harvest the smallest amount between amount of resource, amount harvestable and inventory space
            int inventorySpace = harvester.carryCapacity - harvester.currentlyCarryingAmount;
            int harvestAmount  = math.min(math.min(resourceNode.resourceAmount, harvester.harvestAmount), inventorySpace);

            //Transfer resource from resource node to harvester
            Debug.Log($"Harvested { harvestAmount } of {resourceNode.resourceType}");
            harvester.currentlyCarryingAmount += harvestAmount;
            resourceNode.resourceAmount       -= harvestAmount;

            //If the resource is empty destroy it, we must do this before deciding whether to continue harvesting or go deposit
            if (resourceNode.resourceAmount <= 0)
            {
                Debug.Log("Fully harvested resource");
                ecb2.DestroyEntity(entityInQueryIndex, currentTarget.targetData.targetEntity);
            }
            else             //If the resource isn't being destroyed then update its values
            {
                ecb2.SetComponent(entityInQueryIndex, currentTarget.targetData.targetEntity, resourceNode);
            }

            //If we are at capacity go back to deposit
            if (harvester.currentlyCarryingAmount >= harvester.carryCapacity)
            {
                //Complete the harvest command.
                CommandProcessSystem.CompleteCommand(ref commandBuffer);

                CommandProcessSystem.QueueCommand(CommandType.Deposit, commandBuffer, new TargetData {
                    targetType = AITargetType.Store
                }, true);
                return;
            }

            //If the resource is empty find a new one
            if (resourceNode.resourceAmount <= 0)
            {
                //Complete the harvest command.
                CommandProcessSystem.CompleteCommand(ref commandBuffer);

                CommandProcessSystem.QueueCommand(CommandType.Harvest, commandBuffer, new TargetData {
                    targetType = currentTarget.targetData.targetType
                }, true);
                return;
            }
        }).ScheduleParallel(movingToHarvestHandle);

        m_endSimECBSystem.AddJobHandleForProducer(Dependency);
    }