예제 #1
0
        private void FindAndAttackTarget( )
        {
            var fromPos = CurrentCharacter.Position + GetWeaponOffset();

            using var objectsNearby = CurrentCharacter.PhysicsBody.PhysicsSpace
                                      .TestCircle(position: fromPos,
                                                  radius: GetCurrentWeaponRange(),
                                                  collisionGroup: CollisionGroups.HitboxMelee);
            var objectOfInterest = objectsNearby.AsList()
                                   ?.Where(t => EnabledEntityList.Contains(t.PhysicsBody?.AssociatedWorldObject?.ProtoGameObject))
                                   .ToList();

            if (objectOfInterest == null || objectOfInterest.Count == 0)
            {
                return;
            }

            foreach (var obj in objectOfInterest)
            {
                var testWorldObject = obj.PhysicsBody.AssociatedWorldObject as IStaticWorldObject;
                if (ValidateTarget(testWorldObject, out Vector2D targetPoint))
                {
                    AttackTarget(testWorldObject, targetPoint);
                    return;
                }
            }
        }
예제 #2
0
        protected override void CheckInteractionQueue()
        {
            if (!readyForInteraction)
            {
                return;
            }

            // Remove from queue while it have object and they in our whitelist if:
            //  - object is destroyed
            //  - if object is container that we already have looted
            //  - if object not IProtoObjectGatherable
            //  - if we can not interact with object right now
            //  - if we can not gather anything from object
            while (interactionQueue.Count != 0 && EnabledEntityList.Contains(interactionQueue[0].ProtoGameObject) &&
                   (interactionQueue[0].IsDestroyed ||
                    (lastActionState != null &&
                     lastActionState.TargetWorldObject == interactionQueue[0] &&
                     lastActionState.IsCompleted &&
                     !lastActionState.IsCancelled &&
                     !lastActionState.IsCancelledByServer) ||
                    !(interactionQueue[0].ProtoGameObject is IProtoObjectPlant protoPlant) ||
                    !protoPlant.SharedCanInteract(CurrentCharacter, interactionQueue[0], false)))
            {
                interactionQueue.RemoveAt(0);
            }

            if (interactionQueue.Count == 0)
            {
                return;
            }

            var  request = new ItemWorldActionRequest(CurrentCharacter, interactionQueue[0], SelectedItem);
            bool result  = WateringSystem.Instance.SharedStartAction(request);
        }
예제 #3
0
 protected virtual void FillInteractionQueue()
 {
     using (var objectsInCharacterInteractionArea = InteractionCheckerSystem
                                                    .SharedGetTempObjectsInCharacterInteractionArea(CurrentCharacter))
     {
         if (objectsInCharacterInteractionArea == null)
         {
             return;
         }
         var objectOfInterest = objectsInCharacterInteractionArea
                                .Where(t => EnabledEntityList.Contains(t.PhysicsBody?.AssociatedWorldObject?.ProtoGameObject))
                                .ToList();
         if (!(objectOfInterest?.Count > 0))
         {
             return;
         }
         foreach (var obj in objectOfInterest)
         {
             var testObject = obj.PhysicsBody.AssociatedWorldObject as IStaticWorldObject;
             if (TestObject(testObject))
             {
                 if (!interactionQueue.Contains(testObject))
                 {
                     interactionQueue.Add(testObject);
                 }
             }
         }
     }
 }
예제 #4
0
        private void FindAndAttackTarget( )
        {
            var fromPos = CurrentCharacter.Position + GetWeaponOffset();

            using (var objectsNearby = CurrentCharacter.PhysicsBody.PhysicsSpace
                                       .TestCircle(position: fromPos,
                                                   radius: GetCurrentWeaponRange(),
                                                   collisionGroup: CollisionGroups.HitboxMelee))
            {
                if (objectsNearby == null)
                {
                    targetFound = false;
                    return; // do we need this?
                }
                var objectOfInterest = objectsNearby
                                       .Where(t => EnabledEntityList.Contains(t.PhysicsBody?.AssociatedWorldObject?.ProtoGameObject))
                                       .ToList();
                if (!(objectOfInterest?.Count > 0))
                {
                    targetFound = false;
                    return;
                }
                foreach (var obj in objectOfInterest)
                {
                    var testWorldObject = obj.PhysicsBody.AssociatedWorldObject as IStaticWorldObject;
                    if (CheckForObstacles(testWorldObject, fromPos + obj.Penetration))
                    {
                        targetFound = true;
                        AttackTarget(testWorldObject, fromPos + obj.Penetration);
                        attackInProgress = true;
                        return;
                    }
                }
            }
        }
예제 #5
0
 private IEnumerable <IItem> GetAllFish()
 {
     return(CurrentCharacter.ProtoCharacter
            .SharedEnumerateAllContainers(CurrentCharacter, includeEquipmentContainer: false)
            .SelectMany(c => c.Items)
            .Where(i => EnabledEntityList.Contains(i.ProtoItem)));
 }
예제 #6
0
 private void CheckSelectedItem()
 {
     if (SelectedItem != null &&
         EnabledEntityList.Contains(SelectedItem.ProtoItem))
     {
         CheckItemDurability(SelectedItem);
     }
 }
예제 #7
0
        private bool CheckForObstacles(IWorldObject targetObject, Vector2D intersectionPoint)
        {
            // Check for obstacles in line between character and object
            var fromPos = CurrentCharacter.Position + GetWeaponOffset();
            // Normalize vector and set it length to weapon range
            var toPos = (fromPos - intersectionPoint).Normalized * GetCurrentWeaponRange();
            // Check if in range
            bool canReachObject = false;

            using var obstaclesOnTheWay = CurrentCharacter.PhysicsBody.PhysicsSpace
                                          .TestLine(fromPosition: fromPos,
                                                    toPosition: fromPos - toPos,
                                                    collisionGroup: CollisionGroups.HitboxMelee);
            foreach (var testResult in obstaclesOnTheWay.AsList())
            {
                var testResultPhysicsBody = testResult.PhysicsBody;
                if (testResultPhysicsBody.AssociatedProtoTile != null)
                {
                    if (testResultPhysicsBody.AssociatedProtoTile.Kind != TileKind.Solid)
                    {
                        // non-solid obstacle - skip
                        continue;
                    }
                    // tile on the way - blocking damage ray
                    break;
                }

                var testWorldObject = testResultPhysicsBody.AssociatedWorldObject;
                if (testWorldObject == CurrentCharacter)
                {
                    // ignore collision with self
                    continue;
                }

                if (!(testWorldObject.ProtoGameObject is IDamageableProtoWorldObject))
                {
                    // shoot through this object
                    continue;
                }

                if (testWorldObject == targetObject)
                {
                    canReachObject = true;
                    continue;
                }

                if (EnabledEntityList.Contains(testWorldObject.ProtoWorldObject))
                {
                    // Another object to harvest in line - fire it anyway
                    continue;
                }
                // another object on the way
                return(false);
            }

            return(canReachObject);
        }
예제 #8
0
 /// <summary>
 /// Called by client component on specific time interval.
 /// </summary>
 public override void Execute()
 {
     if (IsEnabled &&
         EnabledEntityList.Any())
     {
         CheckSelectedItem();
         CheckEquipment();
     }
 }
예제 #9
0
        protected override void CheckInteractionQueue()
        {
            if (openedLootContainer != null)
            {
                if (!openedLootContainer.SharedCanInteract(CurrentCharacter, interactionQueue[0], false))
                {
                    openedLootContainer = null;
                }
                else if (interactionQueue[0].ClientHasPrivateState)
                {
                    // Take all items from container.
                    var q = lastActionState.TargetWorldObject.GetPrivateState <LootContainerPrivateState>();
                    CurrentCharacter.ProtoCharacter.ClientTryTakeAllItems(CurrentCharacter, q.ItemsContainer, true);
                    InteractionCheckerSystem.CancelCurrentInteraction(CurrentCharacter);
                    openedLootContainer = null;
                }
                else
                {
                    return;
                }
            }

            if (!readyForInteraction)
            {
                return;
            }

            // Remove from queue while it have object and they in our whitelist if:
            //  - object is destroyed
            //  - if object is container that we already have looted
            //  - if object not IProtoObjectGatherable
            //  - if we can not interact with object right now
            //  - if we can not gather anything from object
            while (interactionQueue.Count != 0 && EnabledEntityList.Contains(interactionQueue[0].ProtoGameObject) &&
                   (interactionQueue[0].IsDestroyed ||
                    (lastActionState?.TargetWorldObject == interactionQueue[0] &&
                     lastActionState.IsCompleted &&
                     !lastActionState.IsCancelled &&
                     !lastActionState.IsCancelledByServer) ||
                    !(interactionQueue[0].ProtoGameObject is IProtoObjectGatherable protoGatherable) ||
                    !protoGatherable.SharedCanInteract(CurrentCharacter, interactionQueue[0], false) ||
                    !protoGatherable.SharedIsCanGather(interactionQueue[0])))
            {
                interactionQueue.RemoveAt(0);
            }

            if (interactionQueue.Count == 0)
            {
                return;
            }

            var request = new WorldActionRequest(CurrentCharacter, interactionQueue[0]);

            GatheringSystem.Instance.SharedStartAction(request);
        }
예제 #10
0
 /// <summary>
 /// Called by client component on specific time interval.
 /// </summary>
 public override void Execute()
 {
     if (IsEnabled &&
         EnabledEntityList.Any())
     {
         foreach (var fish in GetAllFish())
         {
             fish.ProtoItem.ClientItemUseStart(fish);
             fish.ProtoItem.ClientItemUseFinish(fish);
         }
     }
 }
예제 #11
0
        private void CheckEquipment()
        {
            var equimpentItems = CurrentCharacter
                                 .SharedGetPlayerContainerEquipment()
                                 .Items.Where(item => EnabledEntityList.Contains(item.ProtoItem)).ToList();

            foreach (var item in equimpentItems)
            {
                if (item is null)
                {
                    continue;
                }
                CheckItemDurability(item);
            }
        }
예제 #12
0
        protected override void CheckInteractionQueue()
        {
            if (openedLootContainer != null)
            {
                if (InteractionCheckerSystem.SharedHasInteraction(CurrentCharacter, openedLootContainer, true))
                {
                    // We get container private state, now take all items from container.
                    var q      = openedLootContainer.GetPrivateState <LootContainerPrivateState>();
                    var result =
                        CurrentCharacter.ProtoCharacter.ClientTryTakeAllItems(CurrentCharacter, q.ItemsContainer, true);
                    if (result.MovedItems.Count > 0)
                    {
                        NotificationSystem.ClientShowItemsNotification(
                            itemsChangedCount: result.MovedItems
                            .GroupBy(p => p.Key.ProtoItem)
                            .ToDictionary(p => p.Key, p => p.Sum(v => v.Value)));
                    }
                    InteractionCheckerSystem.CancelCurrentInteraction(CurrentCharacter);
                }
                else if (openedLootContainer.ProtoWorldObject
                         .SharedCanInteract(CurrentCharacter, openedLootContainer, false))
                {
                    // Waiting for container private state from server.
                    return;
                }
                openedLootContainer = null;
                readyForInteraction = true;
            }

            if (!readyForInteraction)
            {
                return;
            }

            // Remove from queue while it have object and they in our whitelist if:
            //  - object is destroyed
            //  - if object is container that we already have looted
            //  - if object not IProtoObjectGatherable
            //  - if we can not interact with object right now
            //  - if we can not gather anything from object
            while (interactionQueue.Count != 0 && EnabledEntityList.Contains(interactionQueue[0].ProtoGameObject) &&
                   (interactionQueue[0].IsDestroyed ||
                    (lastActionState != null &&
                     lastActionState.TargetWorldObject == interactionQueue[0] &&
                     lastActionState.IsCompleted &&
                     !lastActionState.IsCancelled &&
                     !lastActionState.IsCancelledByServer) ||
                    !(interactionQueue[0].ProtoGameObject is IProtoObjectGatherable protoGatherable) ||
                    !protoGatherable.SharedCanInteract(CurrentCharacter, interactionQueue[0], false) ||
                    !protoGatherable.SharedIsCanGather(interactionQueue[0])))
            {
                interactionQueue.RemoveAt(0);
            }

            if (interactionQueue.Count == 0)
            {
                return;
            }

            var request = new WorldActionRequest(CurrentCharacter, interactionQueue[0]);

            GatheringSystem.Instance.SharedStartAction(request);
        }