Пример #1
0
    public override void UpdateSystem()
    {
        ComponentDataFromEntity <Translation> translationLookup = GetComponentDataFromEntity <Translation>();
        ComponentDataFromEntity <Health>      healthLookup      = GetComponentDataFromEntity <Health>();

        Entities.WithAll <MovingToAttackState>().ForEach((ref DynamicBuffer <Command> commandBuffer, ref UnitMove unitMove, ref PhysicsVelocity physicsVelocity, ref CurrentTarget currentTarget,
                                                          in Translation translation, in CombatUnit combatUnit) =>
        {
            Translation targetTranslation = translationLookup[currentTarget.targetData.targetEntity];

            //If our target has moved, update our target pos.
            if (!targetTranslation.Value.Equals(currentTarget.targetData.targetPos))
            {
                currentTarget.targetData.targetPos = targetTranslation.Value;
            }

            float distance = math.distance(translation.Value, currentTarget.targetData.targetPos);

            //We are in range, execute attack command.
            if (distance < combatUnit.attackRange)
            {
                CommandProcessSystem.ExecuteCommand(ref commandBuffer);

                unitMove.rotating      = false;
                physicsVelocity.Linear = 0;
            }
        }).ScheduleParallel();
Пример #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);
    }