public CreateItemResult Execute( DelegateSpawnDropItem delegateSpawnDropItem, DropItemContext dropItemContext, double probabilityMultiplier) { this.Freeze(); var result = new CreateItemResult() { IsEverythingCreated = true }; using var selectedEntries = Api.Shared.GetTempList <Entry>(); this.SelectRandomEntries(selectedEntries); // execute selected entries foreach (var entry in selectedEntries) { ExecuteEntry(entry, dropItemContext, out var entryResult, probabilityMultiplier, delegateSpawnDropItem); result.MergeWith(entryResult); } return(result); }
public bool ServerGather(IStaticWorldObject worldObject, ICharacter character) { //MOD PublicState publicState = GetPublicState(worldObject); var lootDroplist = publicState.ProtoCharacterMob.LootDroplist; var dropItemContext = new DropItemContext(character, worldObject); CreateItemResult dropItemResultFinal = new CreateItemResult(); var level = publicState.Level; for (int i = 0; i < level; i++) { CreateItemResult dropItemResult; var attemptRemains = 200; do { dropItemResult = lootDroplist.TryDropToCharacterOrGround(character, character.TilePosition, dropItemContext, out _); dropItemResultFinal.MergeWith(dropItemResult); } // ensure that at least something is spawned... // perhaps that's not a good idea, but we have an attempts limit while (dropItemResult.TotalCreatedCount == 0 && --attemptRemains > 0); } if (!dropItemResultFinal.IsEverythingCreated) { Logger.Warning("Not all loot items were provided by " + worldObject + " - there is not enough space in inventory and around the character"); } // probably the attempts limit exceeded and nothing is spawned // we don't consider this as an issue as the probability of this is too rare Logger.Info(worldObject + " was gathered", character); Server.World.DestroyObject(worldObject); NotificationSystem.ServerSendItemsNotification(character, dropItemResultFinal); character.ServerAddSkillExperience <SkillHunting>(SkillHunting.ExperienceForGather * level); return(true); }
public static CreateItemResult TrySpawnToContainer( IReadOnlyOutputItems outputItems, IItemsContainer toContainer) { var itemsService = Api.Server.Items; var result = new CreateItemResult() { IsEverythingCreated = true }; var character = toContainer.Owner as ICharacter; foreach (var outputItem in outputItems.Items) { var count = GenerateCount(outputItem); if (count == 0) { continue; } CreateItemResult createItemResult; if (character is not null) { createItemResult = itemsService.CreateItem(outputItem.ProtoItem, character, count); } else { createItemResult = itemsService.CreateItem(outputItem.ProtoItem, toContainer, count); } result.MergeWith(createItemResult); } return(result); }
private static TradingResult ServerExecuteTrade( TradingStationLot lot, IItemsContainerProvider sellerContainers, IItemsContainerProvider buyerContainers, bool isPlayerBuying) { // find items to buy by other party if (!SharedTryFindItemsOfType(sellerContainers, lot.ProtoItem, lot.LotQuantity, out var itemsToSell)) { return(isPlayerBuying ? TradingResult.ErrorNotEnoughItemsOnStation : TradingResult.ErrorNotEnoughItemsOnPlayer); } // try to find money to pay to other party var countCoinPenny = (uint)lot.PriceCoinPenny; var countCoinShiny = (uint)lot.PriceCoinShiny; if (!SharedTryFindItemsOfType(buyerContainers, ProtoItemCoinPenny.Value, countCoinPenny, out _) || !SharedTryFindItemsOfType(buyerContainers, ProtoItemCoinShiny.Value, countCoinShiny, out _)) { return(isPlayerBuying ? TradingResult.ErrorNotEnoughMoneyOnStation : TradingResult.ErrorNotEnoughMoneyOnPlayer); } // ensure there is enough space to store the sold items if (!ServerItems.CanCreateItem(buyerContainers, lot.ProtoItem, lot.LotQuantity)) { return(isPlayerBuying ? TradingResult.ErrorNotEnoughSpaceOnPlayerForPurchasedItem : TradingResult.ErrorNotEnoughSpaceOnStationForSoldItem); } // try create money in the source containers var sourceContainerResult = new CreateItemResult() { IsEverythingCreated = true }; if (lot.PriceCoinPenny > 0) { sourceContainerResult.MergeWith( ServerItems.CreateItem(ProtoItemCoinPenny.Value, sellerContainers, countCoinPenny)); } if (lot.PriceCoinShiny > 0) { sourceContainerResult.MergeWith( ServerItems.CreateItem(ProtoItemCoinShiny.Value, sellerContainers, countCoinShiny)); } if (!sourceContainerResult.IsEverythingCreated) { sourceContainerResult.Rollback(); // TODO: check this return(isPlayerBuying ? TradingResult.ErrorNotEnoughSpaceOnStationForSoldItem : TradingResult.ErrorNotEnoughSpaceOnPlayerForPurchasedItem); } // try moving (bought) items var itemsCountToDestroyRemains = (int)lot.LotQuantity; foreach (var item in itemsToSell) { if (itemsCountToDestroyRemains <= 0) { break; } ServerItems.MoveOrSwapItem(item, buyerContainers, out var movedCount, countToMove: (ushort)itemsCountToDestroyRemains); itemsCountToDestroyRemains -= movedCount; } if (itemsCountToDestroyRemains > 0) { // should be impossible Logger.Error( "Cannot move all sold items! But we've verified that the sellerContainers have them all..."); } if (countCoinPenny > 0) { ServerItems.DestroyItemsOfType(buyerContainers, ProtoItemCoinPenny.Value, countCoinPenny, out _); } if (countCoinShiny > 0) { ServerItems.DestroyItemsOfType(buyerContainers, ProtoItemCoinShiny.Value, countCoinShiny, out _); } Logger.Important($"Successfully completed trading transaction: {lot}"); return(TradingResult.Success); }
public override CreateItemResult ServerCreateItem( ICharacter character, IProtoItem protoItem, uint countToSpawn = 1) { if (character == null) { throw new ArgumentNullException(nameof(character)); } if (protoItem == null) { throw new ArgumentNullException(nameof(protoItem)); } if (countToSpawn == 0) { throw new Exception("Cannot add item to character: item count is 0"); } var countToSpawnRemains = countToSpawn; var privateState = GetPrivateState(character); var containerHotbar = privateState.ContainerHotbar; var containerInventory = privateState.ContainerInventory; var serverItemsService = Server.Items; var result = new CreateItemResult(); // define a function for spawning item at specified container bool TrySpawnItem(IItemsContainer container, bool onlyToExistingStacks) { var createItemResult = serverItemsService.CreateItem( protoItem, container, countToSpawnRemains, slotId: null, onlyAddToExistingStacks: onlyToExistingStacks); if (createItemResult.TotalCreatedCount == 0) { // cannot create item return(false); } // something created (perhaps all) result.MergeWith(createItemResult); countToSpawnRemains = (ushort)(countToSpawnRemains - createItemResult.TotalCreatedCount); var isEverythingCreated = countToSpawnRemains == 0; return(isEverythingCreated); } // 1. Try to add to existing stacks in hotbar. // 3. Try to add to existing stacks or spawn as new stacks in inventory. // 3. Try to spawn as new stacks in hotbar. // TODO: 4. Try to spawn on the ground. (actually implemented separately via scripting) if (TrySpawnItem(containerHotbar, onlyToExistingStacks: true) || TrySpawnItem(containerInventory, onlyToExistingStacks: false) || TrySpawnItem(containerHotbar, onlyToExistingStacks: false)) { // all items are created! result.IsEverythingCreated = true; } return(result); }