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; } } }
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); }
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); } } } } }
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; } } } }
private IEnumerable <IItem> GetAllFish() { return(CurrentCharacter.ProtoCharacter .SharedEnumerateAllContainers(CurrentCharacter, includeEquipmentContainer: false) .SelectMany(c => c.Items) .Where(i => EnabledEntityList.Contains(i.ProtoItem))); }
private void CheckSelectedItem() { if (SelectedItem != null && EnabledEntityList.Contains(SelectedItem.ProtoItem)) { CheckItemDurability(SelectedItem); } }
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); }
/// <summary> /// Called by client component on specific time interval. /// </summary> public override void Execute() { if (IsEnabled && EnabledEntityList.Any()) { CheckSelectedItem(); CheckEquipment(); } }
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); }
/// <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); } } }
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); } }
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); }