public static void ServerDespawnDrone(IDynamicWorldObject objectDrone, bool isReturnedToPlayer) { var privateState = objectDrone.GetPrivateState <DronePrivateState>(); var publicState = objectDrone.GetPublicState <DronePublicState>(); publicState.ResetTargetPosition(); if (privateState.IsDespawned) { return; } var droneItem = privateState.AssociatedItem; var protoItemDrone = (IProtoItemDrone)droneItem.ProtoItem; var characterOwner = privateState.CharacterOwner; var world = Server.World; var protoDrone = protoItemDrone.ProtoDrone; protoDrone.ServerOnDroneDroppedOrReturned(objectDrone, characterOwner, isReturnedToPlayer); // recreate physics (as despawned drone doesn't have any physics) privateState.IsDespawned = true; world.StopPhysicsBody(objectDrone.PhysicsBody); objectDrone.ProtoWorldObject.SharedCreatePhysics(objectDrone); world.SetPosition(objectDrone, ServerCharacterDeathMechanic.ServerGetGraveyardPosition().ToVector2D()); privateState.CharacterOwner = null; ServerOnDroneControlRemoved(characterOwner, objectDrone); var currentDurability = (int)(objectDrone.GetPublicState <DronePublicState>().StructurePointsCurrent / protoItemDrone.DurabilityToStructurePointsConversionCoefficient); if (currentDurability <= 1) { currentDurability = 0; } var deltaDurabilility = (int)(ItemDurabilitySystem.SharedGetDurabilityValue(droneItem) - currentDurability); if (deltaDurabilility <= 0) { return; } ItemDurabilitySystem.ServerModifyDurability(droneItem, -deltaDurabilility); if (droneItem.IsDestroyed) { // drone item degraded to 100%, notify the player ItemDurabilitySystem.Instance.CallClient(characterOwner, _ => _.ClientRemote_ItemBroke(droneItem.ProtoItem)); } }
public static IItem ClientSelectNextDrone(List <IItem> exceptItems) { IItem selectedItem = null; var selectedItemOrder = int.MinValue; var privateState = ClientCurrentCharacterHelper.PrivateState; // find a drone item with the highest order number foreach (var item in privateState.ContainerHotbar.Items) { if (IsValidDroneItem(item, out var order) && order >= selectedItemOrder) { selectedItem = item; selectedItemOrder = order; } } foreach (var item in privateState.ContainerInventory.Items) { if (IsValidDroneItem(item, out var order) && order >= selectedItemOrder) { selectedItem = item; selectedItemOrder = order; } } return(selectedItem); bool IsValidDroneItem(IItem item, out int order) { if (item.ProtoItem is IProtoItemDrone protoItemDrone && ItemDurabilitySystem.SharedGetDurabilityValue(item) > 0 && !exceptItems.Contains(item)) { order = protoItemDrone.SelectionOrder; return(true); } order = int.MinValue; return(false); } }
public void ServerRemote_StartDrone(IItem itemDrone, Vector2Ushort worldPosition) { var character = ServerRemoteContext.Character; if (itemDrone.Container.Owner != character) { Logger.Info("Player don't own the drone: " + itemDrone, character); return; } if (!(itemDrone.ProtoItem is IProtoItemDrone protoItemDrone)) { // not a drone item Logger.Warning("Not a drone item: " + itemDrone, character); return; } var itemDroneControl = character.SharedGetPlayerSelectedHotbarItem(); if (!(itemDroneControl.ProtoItem is IProtoItemDroneControl)) { Logger.Info("Don't have a drone remote control selected", character); return; } if (SharedIsMaxDronesToControlNumberExceeded(character)) { Logger.Info("Exceeded max numbers of drones to control simultaneously", character); return; } if (SharedIsTargetAlreadyScheduledForAnyActiveDrone(character, worldPosition, logError: true)) { return; } if (character.GetPublicState <ICharacterPublicState>() .IsDead) { // dead player cannot start a drone return; } var protoDrone = protoItemDrone.ProtoDrone; if (!SharedIsValidStartLocation(character, worldPosition, out _)) { Logger.Info("Too far to start a drone or has obstacles", character); return; } var objectDrone = itemDrone.GetPrivateState <ItemDronePrivateState>().WorldObjectDrone; if (!ServerIsMiningAllowed(worldPosition, objectDrone)) { Logger.Info("Cannot mine there as it's already mined by another drone: " + worldPosition, character); return; } var targetObject = SharedGetCompatibleTarget(character, worldPosition, out _, out _); if (targetObject is null) { Logger.Info("Nothing to mine there: " + worldPosition, character); return; } var durabilityValue = ItemDurabilitySystem.SharedGetDurabilityValue(itemDrone); if (durabilityValue == 0) { Logger.Warning("Cannot start a drone with 0 durability: " + itemDrone, character); return; } var dronePublicState = objectDrone.GetPublicState <DronePublicState>(); var droneStructurePoints = durabilityValue * protoItemDrone.DurabilityToStructurePointsConversionCoefficient; dronePublicState.StructurePointsCurrent = (float)droneStructurePoints; var controlledDrones = character.SharedGetCurrentlyControlledDrones(); controlledDrones.Add(objectDrone); Logger.Info("Drone control started: " + objectDrone); // move drone from player inventory to its own storage items container var isFromHotbarContainer = itemDrone.Container == character.SharedGetPlayerContainerHotbar(); var fromSlotIndex = itemDrone.ContainerSlotId; Server.Items.MoveOrSwapItem(itemDrone, protoDrone.ServerGetStorageItemsContainer(objectDrone), out _); //Logger.Dev($"Drone start moving: {itemDrone} to {worldPosition}"); protoDrone.ServerStartDrone(objectDrone, character, isFromHotbarContainer, fromSlotIndex); protoDrone.ServerSetDroneTarget(objectDrone, targetObject, fromStartPosition: character.Position); ServerItemUseObserver.NotifyItemUsed(character, itemDroneControl); }