public void Pack(BinaryWriter writer) { writer.Write((uint)SkillUsed); NotSalvagable.Pack(writer); SalvageResults.Pack(writer); writer.Write(AugBonus); }
public void Unpack(BinaryReader reader) { SkillUsed = (SkillID)reader.ReadUInt32(); NotSalvagable.Unpack(reader); SalvageResults.Unpack(reader); AugBonus = reader.ReadInt32(); }
public int GetStructure(WorldObject salvageItem, SalvageResults salvageResults, ref SalvageMessage message) { // By default, salvaging uses either a tinkering skill, or your salvaging skill that would yield the greatest amount of material. // Tinkering skills can only yield at most the workmanship number in units of salvage. // The salvaging skill can produce more units than workmanship. // You can also significantly increase the amount of material returned by training the Ciandra's Fortune augmentation. // This augmentation can be trained 4 times, each time providing an additional 25% bonus to the amount of material returned. // is this a bag of salvage? // if so, return its existing structure if (salvageItem.ItemType == ItemType.TinkeringMaterial) { return(salvageItem.Structure.Value); } var workmanship = salvageItem.Workmanship ?? 1.0f; var stackSize = salvageItem.StackSize ?? 1; // should this be getting the highest tinkering skill, // or the tinkering skill for the material? var salvageSkill = GetCreatureSkill(Skill.Salvaging).Current; var highestTinkeringSkill = GetMaxSkill(TinkeringSkills); var highestTrainedTinkeringSkill = highestTinkeringSkill.AdvancementClass >= SkillAdvancementClass.Trained ? highestTinkeringSkill.Current : 0; var salvageMultiplier = Math.Max(0.6f, salvageSkill / 225.0f); var tinkeringMultiplier = Math.Max(0.6f, highestTrainedTinkeringSkill / 225.0f); // take augs into account for salvaging only var augMod = 1.0f; if (AugmentationBonusSalvage > 0) { augMod += AugmentationBonusSalvage * 0.25f; } var fSalvageAmount = workmanship * salvageMultiplier * stackSize * augMod; var fTinkeringAmount = workmanship * tinkeringMultiplier * stackSize; var salvageAmount = fSalvageAmount.Round(); var tinkeringAmount = Math.Min(fTinkeringAmount.Round(), (int)Math.Round(salvageItem.Workmanship ?? 1.0f)); // choose the best one var addStructure = Math.Max(salvageAmount, tinkeringAmount); var skill = salvageAmount > tinkeringAmount ? Skill.Salvaging : GetMaxSkill(TinkeringSkills).Skill; message = salvageResults.GetMessage(salvageItem.MaterialType ?? ACE.Entity.Enum.MaterialType.Unknown, skill); message.Amount += (uint)addStructure; if (skill == Skill.Salvaging && augMod > 1.0f) { message.AugBonus += (int)Math.Round(fSalvageAmount - fSalvageAmount / augMod); } return(addStructure); }
public void HandleSalvaging(List <uint> salvageItems) { var salvageBags = new List <WorldObject>(); var salvageResults = new SalvageResults(); foreach (var itemGuid in salvageItems) { var item = GetInventoryItem(itemGuid); if (item == null) { log.Debug($"[CRAFTING] {Name}.HandleSalvaging({itemGuid:X8}): couldn't find inventory item"); continue; } if (item.MaterialType == null) { log.Warn($"{Name}.HandleSalvaging({item.Name}): no material type"); continue; } if (IsTrading && ItemsInTradeWindow.Contains(item.Guid)) { SendWeenieError(WeenieError.YouCannotSalvageItemsInTrading); continue; } if (item.Workmanship == null || item.Retained) { continue; } AddSalvage(salvageBags, item, salvageResults); // can any salvagable items be stacked? TryConsumeFromInventoryWithNetworking(item); } // add salvage bags foreach (var salvageBag in salvageBags) { TryCreateInInventoryWithNetworking(salvageBag); } // send network messages if (!SquelchManager.Squelches.Contains(this, ChatMessageType.Salvaging)) { foreach (var kvp in salvageResults.GetMessages()) { Session.Network.EnqueueSend(new GameEventSalvageOperationsResult(Session, kvp.Key, kvp.Value)); } } }
public void AddSalvage(List <WorldObject> salvageBags, WorldObject item, SalvageResults salvageResults) { var materialType = (MaterialType)item.MaterialType; // determine the amount of salvage produced (structure) SalvageMessage message = null; var amountProduced = GetStructure(item, salvageResults, ref message); var remaining = amountProduced; while (remaining > 0) { // get the destination salvage bag // if there are no existing salvage bags for this material type, // or all of the salvage bags for this material type are full, // this will create a new salvage bag, and adds it to salvageBags var salvageBag = GetSalvageBag(materialType, salvageBags); var added = TryAddSalvage(salvageBag, item, remaining); remaining -= added; // https://asheron.fandom.com/wiki/Salvaging/Value_Pre2013 // increase value of salvage bag - salvage skill is a factor, // if bags aren't being combined here var valueFactor = (float)added / amountProduced; if (item.ItemType != ItemType.TinkeringMaterial) { valueFactor *= GetCreatureSkill(Skill.Salvaging).Current / 387.0f * (1.0f + 0.25f * AugmentationBonusSalvage); } int addedValue = (int)Math.Round((item.Value ?? 0) * valueFactor); ACE.Server.GameplayAddons.MUSalvageValue.ModifySalvageOuputValue(ref addedValue); salvageBag.Value = Math.Min((salvageBag.Value ?? 0) + addedValue, 75000); // a bit different here, since ACE handles overages if (message != null) { message.Workmanship += item.ItemWorkmanship ?? 0.0f; message.NumItemsInMaterial++; } } }
public void HandleSalvaging(List <uint> salvageItems) { var salvageBags = new List <WorldObject>(); var salvageResults = new SalvageResults(); foreach (var itemGuid in salvageItems) { var item = GetInventoryItem(itemGuid); if (item == null) { log.Warn($"{Name}.HandleSalvaging({itemGuid:X8}): couldn't find inventory item"); continue; } if (item.MaterialType == null) { log.Warn($"{Name}.HandleSalvaging({item.Name}): no material type"); continue; } if (item.Workmanship == null || (item.Retained ?? false)) { continue; } AddSalvage(salvageBags, item, salvageResults); // can any salvagable items be stacked? TryConsumeFromInventoryWithNetworking(item); } // add salvage bags foreach (var salvageBag in salvageBags) { TryCreateInInventoryWithNetworking(salvageBag); } // send network messages foreach (var kvp in salvageResults.GetMessages()) { Session.Network.EnqueueSend(new GameEventSalvageOperationsResult(Session, kvp.Key, kvp.Value)); } }
public void AddSalvage(List <WorldObject> salvageBags, WorldObject item, SalvageResults salvageResults) { var materialType = (MaterialType)item.MaterialType; // determine the amount of salvage produced (structure) SalvageMessage message = null; var amountProduced = GetStructure(item, salvageResults, ref message); var remaining = amountProduced; while (remaining > 0) { // get the destination salvage bag // if there are no existing salvage bags for this material type, // or all of the salvage bags for this material type are full, // this will create a new salvage bag, and adds it to salvageBags var salvageBag = GetSalvageBag(materialType, salvageBags); var added = TryAddSalvage(salvageBag, item, remaining); remaining -= added; // increase value of salvage bag - salvage skill is a factor, // if bags aren't being combined here var valueFactor = (float)added / amountProduced; if (item.WeenieType != WeenieType.CraftTool) { valueFactor *= GetCreatureSkill(Skill.Salvaging).Current / 387.0f; // TODO: take augs into account } var addedValue = (int)Math.Round((item.Value ?? 0) * valueFactor); salvageBag.Value = Math.Min((salvageBag.Value ?? 0) + addedValue, 75000); // a bit different here, since ACE handles overages if (message != null) { message.Workmanship += item.GetProperty(PropertyInt.ItemWorkmanship) ?? 0.0f; message.NumItemsInMaterial++; } } }