public static void OnAcquireItem() { uint acquired = GetModuleItemAcquired(); uint by = GetModuleItemAcquiredBy(); uint from = GetModuleItemAcquiredFrom(); string name = GetName(acquired); string byName = GetName(by); from.PrintGPValue(); BiowareXP2.IPRemoveAllItemProperties(acquired, DurationType.Temporary); if (GetIsDM(by)) { return; } by.BarterFix(from); if (String.IsNullOrEmpty(name)) { by.SendMessageToAllPartyWithinDistance($"{byName} acquired Gold Pieces.", 40.0f); return; } //Stop spam to combat log upon login by.SendMessageToAllPartyWithinDistance($"{byName} acquired {name}.", 40.0f); }
public static void SetVisual(this uint pc, string[] chatArray) { var item = GetItemInSlot(InventorySlotType.RightHand, pc); if (GetIsObjectValid(item)) { BiowareXP2.IPRemoveMatchingItemProperties(item, ItemPropertyType.Visualeffect, DurationType.Permanent, -1); ItemProperty type; switch (chatArray[1]) { case "acid": type = ItemPropertyVisualEffect(ItemVisualType.Acid); break; case "cold": type = ItemPropertyVisualEffect(ItemVisualType.Cold); break; case "electric": type = ItemPropertyVisualEffect(ItemVisualType.Electrical); break; case "evil": type = ItemPropertyVisualEffect(ItemVisualType.Evil); break; case "fire": type = ItemPropertyVisualEffect(ItemVisualType.Fire); break; case "holy": type = ItemPropertyVisualEffect(ItemVisualType.Holy); break; case "sonic": type = ItemPropertyVisualEffect(ItemVisualType.Sonic); break; default: SendMessageToPC(pc, $"Cannot set weapon visual to {chatArray}."); throw new ArgumentException($"Name:{GetName(pc)} | BIC:{Player.GetBicFileName(pc)} failed to set weapon visual to {chatArray}."); } BiowareXP2.IPSafeAddItemProperty(item, type, 0.0f, AddItemPropertyPolicy.ReplaceExisting, true, true); } }
private static void AddOnHitProperty(NWItem oItem) { foreach (ItemProperty ip in oItem.ItemProperties) { if (_.GetItemPropertyType(ip) == ITEM_PROPERTY_ONHITCASTSPELL) { if (_.GetItemPropertySubType(ip) == IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER) { return; } } } // No item property found. Add it to the item. BiowareXP2.IPSafeAddItemProperty(oItem, _.ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 40), 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); }
/// <summary> /// Applies the OnHitCastSpell item property to a specified item. /// </summary> /// <param name="item"></param> private static void ApplyOnHitProperty(uint item) { for (var ip = GetFirstItemProperty(item); GetIsItemPropertyValid(ip); ip = GetNextItemProperty(item)) { if (GetItemPropertyType(ip) == ItemPropertyType.OnHitCastSpell) { if (GetItemPropertySubType(ip) == (int)OnHitCastSpell.ONHIT_UNIQUEPOWER) { return; } } } // No item property found. Add it to the item. BiowareXP2.IPSafeAddItemProperty(item, ItemPropertyOnHitCastSpell(OnHitCastSpell.ONHIT_UNIQUEPOWER, 40), 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); }
private static void AddOnHitProperty(NWItem oItem) { foreach (ItemProperty ip in oItem.ItemProperties) { if (GetItemPropertyType(ip) == ItemPropertyType.OnHitCastSpell) { if (GetItemPropertySubType(ip) == (int)OnHitCastSpellType.ONHIT_UNIQUEPOWER) { return; } } } // No item property found. Add it to the item. BiowareXP2.IPSafeAddItemProperty(oItem, ItemPropertyOnHitCastSpell(OnHitCastSpellType.ONHIT_UNIQUEPOWER, 40), 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); }
public void Apply(NWPlayer player, NWItem target, params string[] args) { int additionalAB = Convert.ToInt32(args[0]); int existingAB = GetExistingAB(target); int newValue = existingAB + additionalAB; if (newValue > MaxValue) { newValue = MaxValue; } ItemProperty ip = _.ItemPropertyAttackBonus(newValue); ip = _.TagItemProperty(ip, "RUNE_IP"); BiowareXP2.IPSafeAddItemProperty(target, ip, 0.0f, AddItemPropertyPolicy.ReplaceExisting, true, false); }
public void Apply(NWPlayer player, NWItem target, params string[] args) { int additionalEnhancementBonus = Convert.ToInt32(args[0]); int existingEnhancementBonus = GetExistingEnhancementBonus(target); int newValue = existingEnhancementBonus + additionalEnhancementBonus; if (newValue > 20) { newValue = 20; } ItemProperty ip = _.ItemPropertyEnhancementBonus(newValue); ip = _.TagItemProperty(ip, "RUNE_IP"); BiowareXP2.IPSafeAddItemProperty(target, ip, 0.0f, AddItemPropertyPolicy.ReplaceExisting, true, false); }
public static void ProcessVersion6RemoveACFromItem(NWItem item) { // Start by pulling the custom AC off the item and halving it. // Durability is +1 for every 2 AC on the item. int amount = item.CustomAC / 2; if (amount > 0) { float newMax = DurabilityService.GetMaxDurability(item) + amount; float newCurrent = DurabilityService.GetDurability(item) + amount; DurabilityService.SetMaxDurability(item, newMax); DurabilityService.SetDurability(item, newCurrent); } item.CustomAC = 0; // Check all item properties. If the IP is a component Armor Class Bonus, remove it and replace with an increase to durability. foreach (var ip in item.ItemProperties) { if (_.GetItemPropertyType(ip) == (int)CustomItemPropertyType.ComponentBonus) { // Check the sub-type. If it's AC, then do the replacement. if (GetItemPropertySubType(ip) == (int)ComponentBonusType.ACUp) { amount = GetItemPropertyCostTableValue(ip) / 2; // Grant the durability up property if amount > 0 if (amount > 0) { // Unpack the IP we're working with. Adjust its type and value, then reapply it. var unpacked = NWNXItemProperty.UnpackIP(ip); unpacked.SubType = (int)ComponentBonusType.DurabilityUp; unpacked.CostTableValue = amount; var packed = NWNXItemProperty.PackIP(unpacked); BiowareXP2.IPSafeAddItemProperty(item, packed, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true); } _.RemoveItemProperty(item, ip); } } } }
public void Run(NWObject target, params object[] args) { int retrievalRating = (int)args[0]; int highQualityChance = 10 * retrievalRating; int veryHighQualityChance = 2 * retrievalRating; int roll = RandomService.Random(0, 100); ResourceQuality quality = ResourceQuality.Normal; if (roll <= veryHighQualityChance) { quality = ResourceQuality.VeryHigh; } else if (roll <= highQualityChance) { quality = ResourceQuality.High; } var ip = ResourceService.GetRandomComponentBonusIP(quality); BiowareXP2.IPSafeAddItemProperty(target.Object, ip.Item1, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true); switch (ip.Item2) { case 0: target.Name = ColorTokenService.Green(target.Name); break; case 1: target.Name = ColorTokenService.Blue(target.Name); break; case 2: target.Name = ColorTokenService.Purple(target.Name); break; case 3: target.Name = ColorTokenService.Orange(target.Name); break; } }
public static void OnUnAcquireItem() { var unAcquired = NWScript.GetModuleItemLost(); var unAcquiredBy = NWScript.GetModuleItemLostBy(); unAcquired.PrintGPValue(); PlayerCharacter.Extensions.Save(unAcquiredBy); BiowareXP2.IPRemoveAllItemProperties(unAcquired, DurationType.Temporary); if (NWScript.GetIsDM(unAcquired)) { return; } //Hopefully temp fix for disarm feat if (NWScript.GetIsInCombat(unAcquiredBy) && !NWScript.GetStolenFlag(unAcquired) && NWScript.GetIsWeaponEffective(NWScript.GetLastAttacker(unAcquired))) { NWScript.CopyItem(unAcquired, unAcquiredBy, true); NWScript.DestroyObject(unAcquired, 0.2f); return; } }
public void Apply(NWPlayer player, NWItem target, params string[] args) { var data = ParseData(args); if (data.Item1 < 0) { return; } var existingValues = GetExistingIPInfo(target, data.Item1); int newValue = data.Item2 + existingValues.Item2; if (newValue > 12) { newValue = 12; } ItemProperty ip = _.ItemPropertyAbilityBonus(data.Item1, newValue); ip = _.TagItemProperty(ip, "RUNE_IP"); BiowareXP2.IPSafeAddItemProperty(target, ip, 0.0f, AddItemPropertyPolicy.ReplaceExisting, true, false); }
private static void ProcessVersion6_ComponentBonuses(NWItem item, ItemProperty ip) { // Component Bonuses if (_.GetItemPropertyType(ip) == ItemPropertyType.ComponentBonus) { // +AC Component Bonus if (GetItemPropertySubType(ip) == (int)ComponentBonusType.ACUp) { int amount = GetItemPropertyCostTableValue(ip) / 2; // Grant the durability up property if amount > 0 if (amount > 0) { // Unpack the IP we're working with. Adjust its type and value, then reapply it. var unpacked = NWNXItemProperty.UnpackIP(ip); unpacked.SubType = (int)ComponentBonusType.DurabilityUp; unpacked.CostTableValue = amount; var packed = NWNXItemProperty.PackIP(unpacked); BiowareXP2.IPSafeAddItemProperty(item, packed, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true); } _.RemoveItemProperty(item, ip); } } }
private static void ProcessVersion6ItemChanges(NWPlayer player) { List <SerializedObjectData> serializedItems = new List <SerializedObjectData>(); // Start with equipped items. foreach (var item in player.EquippedItems) { ProcessVersion6_DeflateItemStats(item); var data = ProcessVersion6LightsaberItem(item); if (data.Data != null) { serializedItems.Add(data); } } // Next do all inventory items. foreach (var item in player.InventoryItems) { ProcessVersion6_DeflateItemStats(item); var data = ProcessVersion6LightsaberItem(item); if (data.Data != null) { serializedItems.Add(data); } } // Deserialize all items onto the player now. foreach (var serialized in serializedItems) { var item = SerializationService.DeserializeItem(serialized.Data, player); BiowareXP2.IPRemoveAllItemProperties(item, DurationType.Permanent); foreach (var ip in serialized.ItemPropertiesToAdd) { BiowareXP2.IPSafeAddItemProperty(item, ip, 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); } } }
private int ProcessProperty(int amount, int maxBonuses, ComponentBonusType bonus, float levelsPerBonus = 1.0f) { string resref = _componentType.ReassembledResref; int penalty = 0; int luck = PerkService.GetPCPerkLevel(_player, PerkType.Lucky) + (_playerItemStats.Luck / 3); int xp = 0; ItemPropertyUnpacked bonusIP = new ItemPropertyUnpacked { Property = (int)CustomItemPropertyType.ComponentBonus, SubType = (int)bonus, CostTable = 62, CostTableValue = 0, Param1 = 255, Param1Value = 0, UsesPerDay = 255, ChanceToAppear = 100, IsUseable = true, SpellID = -1 }; while (amount > 0) { int chanceToTransfer = CraftService.CalculateReassemblyChance(_player, penalty); // Roll to see if the item can be created. bool success = RandomService.Random(0, 100) <= chanceToTransfer; // Do a lucky roll if we failed the first time. if (!success && luck > 0 && RandomService.Random(0, 100) <= luck) { _player.SendMessage("Lucky reassemble!"); success = true; } if (amount >= maxBonuses) { if (success) { int levelIncrease = (int)(maxBonuses * levelsPerBonus); // Roll succeeded. Create item. bonusIP.CostTableValue = maxBonuses; ItemProperty bonusIPPacked = NWNXItemProperty.PackIP(bonusIP); NWItem item = _.CreateItemOnObject(resref, _player); item.RecommendedLevel = levelIncrease; BiowareXP2.IPSafeAddItemProperty(item, bonusIPPacked, 0.0f, AddItemPropertyPolicy.ReplaceExisting, true, false); xp += (150 * maxBonuses + RandomService.Random(0, 5)); } else { _player.SendMessage(ColorTokenService.Red("You failed to create a component. (+" + maxBonuses + ")")); xp += (50 + RandomService.Random(0, 5)); } // Penalty to chance increases regardless if item was created or not. penalty += (maxBonuses * 5); amount -= maxBonuses; } else { if (success) { int levelIncrease = (int)(amount * levelsPerBonus); bonusIP.CostTableValue = amount; ItemProperty bonusIPPacked = NWNXItemProperty.PackIP(bonusIP); NWItem item = _.CreateItemOnObject(resref, _player); item.RecommendedLevel = levelIncrease; BiowareXP2.IPSafeAddItemProperty(item, bonusIPPacked, 0.0f, AddItemPropertyPolicy.ReplaceExisting, true, false); xp += (150 * amount + RandomService.Random(0, 5)); } else { _player.SendMessage(ColorTokenService.Red("You failed to create a component. (+" + amount + ")")); xp += (50 + RandomService.Random(0, 5)); } break; } } return(xp); }
public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData) { NWPlayer player = user.Object; ResourceQuality quality = (ResourceQuality)target.GetLocalInt("RESOURCE_QUALITY"); int tier = target.GetLocalInt("RESOURCE_TIER"); int remaining = target.GetLocalInt("RESOURCE_COUNT") - 1; string itemResref = target.GetLocalString("RESOURCE_RESREF"); int gemChance = ResourceService.CalculateChanceForComponentBonus(player, tier, quality); int roll = RandomService.Random(1, 100); int rank = SkillService.GetPCSkillRank(player, SkillType.Harvesting); if (item.RecommendedLevel < rank) { rank = item.RecommendedLevel; } int difficulty = (tier - 1) * 10 + ResourceService.GetDifficultyAdjustment(quality); int delta = difficulty - rank; int baseXP = 0; if (delta >= 6) { baseXP = 400; } else if (delta == 5) { baseXP = 350; } else if (delta == 4) { baseXP = 325; } else if (delta == 3) { baseXP = 300; } else if (delta == 2) { baseXP = 250; } else if (delta == 1) { baseXP = 225; } else if (delta == 0) { baseXP = 200; } else if (delta == -1) { baseXP = 150; } else if (delta == -2) { baseXP = 100; } else if (delta == -3) { baseXP = 50; } else if (delta == -4) { baseXP = 25; } int itemHarvestBonus = item.HarvestingBonus; int scanningBonus = user.GetLocalInt(target.GlobalID.ToString()); gemChance += itemHarvestBonus * 2 + scanningBonus * 2; baseXP = baseXP + scanningBonus * 5; // Spawn the normal resource. NWItem resource = CreateItemOnObject(itemResref, player); user.SendMessage("You harvest " + resource.Name + "."); // If player meets the chance to acquire a gem, create one and modify its properties. if (quality > ResourceQuality.Low && roll <= gemChance) { // Gemstone quality is determined by the quality of the vein. switch (quality) { case ResourceQuality.Normal: resource = CreateItemOnObject("flawed_gemstone", player); break; case ResourceQuality.High: resource = CreateItemOnObject("gemstone", player); break; case ResourceQuality.VeryHigh: resource = CreateItemOnObject("perfect_gemstone", player); break; } var ip = ResourceService.GetRandomComponentBonusIP(quality); BiowareXP2.IPSafeAddItemProperty(resource, ip.Item1, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true); switch (ip.Item2) { case 0: resource.Name = ColorTokenService.Green(resource.Name); break; case 1: resource.Name = ColorTokenService.Blue(resource.Name); break; case 2: resource.Name = ColorTokenService.Purple(resource.Name); break; case 3: resource.Name = ColorTokenService.Orange(resource.Name); break; case 4: resource.Name = ColorTokenService.LightPurple(resource.Name); break; case 5: resource.Name = ColorTokenService.Yellow(resource.Name); break; case 6: resource.Name = ColorTokenService.Red(resource.Name); break; case 7: resource.Name = ColorTokenService.Cyan(resource.Name); break; } user.SendMessage("You harvest " + resource.Name + "."); } float decayMinimum = 0.03f; float decayMaximum = 0.07f; if (delta > 0) { decayMinimum += delta * 0.1f; decayMaximum += delta * 0.1f; } DurabilityService.RunItemDecay(player, item, RandomService.RandomFloat(decayMinimum, decayMaximum)); int xp = baseXP; SkillService.GiveSkillXP(player, SkillType.Harvesting, xp); if (remaining <= 0) { NWPlaceable prop = target.GetLocalObject("RESOURCE_PROP_OBJ"); if (prop.IsValid) { prop.Destroy(); } target.Destroy(); user.DeleteLocalInt(target.GlobalID.ToString()); } else { target.SetLocalInt("RESOURCE_COUNT", remaining); } ApplyEffectAtLocation(DurationType.Instant, EffectVisualEffect(VisualEffect.Vfx_Fnf_Summon_Monster_3), target.Location); }
public static void ApplyComponentBonus(NWItem product, ItemProperty sourceIP) { ComponentBonusType bonusType = (ComponentBonusType)_.GetItemPropertySubType(sourceIP); int amount = _.GetItemPropertyCostTableValue(sourceIP); ItemProperty prop = null; string sourceTag = string.Empty; int attackBonus = 0; // A note about the sourceTags: // It's not currently possible to create custom item properties on items. To get around this, // we look in an inaccessible container which holds the custom item properties. Then, we get the // item that has the item property we want. From there we take that item property and copy it to // the crafted item. // This is a really roundabout way to do it, but it's the only option for now. Hopefully a feature to // directly add the item properties comes in to NWNX in the future. // 2019-06-12: Directly modifying item properties is possible now but I'm not going to do a refactor until later. // Anyone interested in working on this let me know and I can point you in the right direction. - Z for (int x = 1; x <= amount; x++) { switch (bonusType) { case ComponentBonusType.ModSocketRed: sourceTag = "rslot_red"; break; case ComponentBonusType.ModSocketBlue: sourceTag = "rslot_blue"; break; case ComponentBonusType.ModSocketGreen: sourceTag = "rslot_green"; break; case ComponentBonusType.ModSocketYellow: sourceTag = "rslot_yellow"; break; case ComponentBonusType.ModSocketPrismatic: sourceTag = "rslot_prismatic"; break; case ComponentBonusType.DurabilityUp: var maxDur = DurabilityService.GetMaxDurability(product) + amount; DurabilityService.SetMaxDurability(product, maxDur); DurabilityService.SetDurability(product, maxDur); break; case ComponentBonusType.ChargesUp: product.Charges += amount; break; case ComponentBonusType.ACUp: product.CustomAC += amount; break; case ComponentBonusType.HarvestingUp: product.HarvestingBonus += amount; break; case ComponentBonusType.CooldownRecoveryUp: product.CooldownRecovery += amount; break; case ComponentBonusType.ArmorsmithUp: product.CraftBonusArmorsmith += amount; break; case ComponentBonusType.WeaponsmithUp: product.CraftBonusWeaponsmith += amount; break; case ComponentBonusType.CookingUp: product.CraftBonusCooking += amount; break; case ComponentBonusType.EngineeringUp: product.CraftBonusEngineering += amount; break; case ComponentBonusType.FabricationUp: product.CraftBonusFabrication += amount; break; case ComponentBonusType.HPUp: product.HPBonus += amount; break; case ComponentBonusType.FPUp: product.FPBonus += amount; break; case ComponentBonusType.EnmityUp: product.EnmityRate += amount; break; case ComponentBonusType.EnmityDown: product.EnmityRate -= amount; break; case ComponentBonusType.LuckUp: product.LuckBonus += amount; break; case ComponentBonusType.MeditateUp: product.MeditateBonus += amount; break; case ComponentBonusType.RestUp: product.RestBonus += amount; break; case ComponentBonusType.MedicineUp: product.MedicineBonus += amount; break; case ComponentBonusType.HPRegenUp: product.HPRegenBonus += amount; break; case ComponentBonusType.FPRegenUp: product.FPRegenBonus += amount; break; case ComponentBonusType.BaseAttackBonusUp: product.BaseAttackBonus += amount; break; case ComponentBonusType.SneakAttackUp: product.SneakAttackBonus += amount; break; case ComponentBonusType.DamageUp: product.DamageBonus += amount; break; case ComponentBonusType.StructureBonusUp: product.StructureBonus += amount; break; case ComponentBonusType.StrengthUp: product.StrengthBonus += amount; break; case ComponentBonusType.DexterityUp: product.DexterityBonus += amount; break; case ComponentBonusType.ConstitutionUp: product.ConstitutionBonus += amount; break; case ComponentBonusType.WisdomUp: product.WisdomBonus += amount; break; case ComponentBonusType.IntelligenceUp: product.IntelligenceBonus += amount; break; case ComponentBonusType.CharismaUp: product.CharismaBonus += amount; break; case ComponentBonusType.AttackBonusUp: attackBonus += amount; break; case ComponentBonusType.DurationUp: product.DurationBonus += amount; break; case ComponentBonusType.ScanningUp: product.ScanningBonus += amount; break; case ComponentBonusType.ScavengingUp: product.ScavengingBonus += amount; break; case ComponentBonusType.PilotingUp: product.PilotingBonus += amount; break; default: throw new ArgumentOutOfRangeException(); } if (!string.IsNullOrWhiteSpace(sourceTag)) { prop = ItemService.GetCustomItemPropertyByItemTag(sourceTag); } if (prop == null) { return; } BiowareXP2.IPSafeAddItemProperty(product, prop, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true); } // Attack bonus is aggregated into one item property, ensuring that the amount doesn't go over 20. if (attackBonus > 0) { // Look for existing properties, get the value and add it. Then remove that item property. foreach (var ip in product.ItemProperties) { if (_.GetItemPropertyType(ip) == _.ITEM_PROPERTY_ATTACK_BONUS) { amount = _.GetItemPropertyCostTableValue(ip); attackBonus += amount; _.RemoveItemProperty(product, ip); } } // Clamp bonus to 20. if (attackBonus > 20) { attackBonus = 20; } // Time to add the new item property. prop = _.ItemPropertyAttackBonus(attackBonus); BiowareXP2.IPSafeAddItemProperty(product, prop, 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); } }
public void ApplyEffects(NWCreature user, NWItem item, NWObject target, Location targetLocation, CustomData customData) { NWPlayer player = user.Object; ResourceQuality quality = (ResourceQuality)target.GetLocalInt("RESOURCE_QUALITY"); int tier = target.GetLocalInt("RESOURCE_TIER"); int remaining = target.GetLocalInt("RESOURCE_COUNT") - 1; string itemResref = target.GetLocalString("RESOURCE_RESREF"); int ipBonusChance = ResourceService.CalculateChanceForComponentBonus(player, tier, quality); int roll = RandomService.Random(1, 100); int rank = SkillService.GetPCSkillRank(player, SkillType.Harvesting); if (item.RecommendedLevel < rank) { rank = item.RecommendedLevel; } int difficulty = (tier - 1) * 10 + ResourceService.GetDifficultyAdjustment(quality); int delta = difficulty - rank; int baseXP = 0; if (delta >= 6) { baseXP = 400; } else if (delta == 5) { baseXP = 350; } else if (delta == 4) { baseXP = 325; } else if (delta == 3) { baseXP = 300; } else if (delta == 2) { baseXP = 250; } else if (delta == 1) { baseXP = 225; } else if (delta == 0) { baseXP = 200; } else if (delta == -1) { baseXP = 150; } else if (delta == -2) { baseXP = 100; } else if (delta == -3) { baseXP = 50; } else if (delta == -4) { baseXP = 25; } int itemHarvestBonus = item.HarvestingBonus; int scanningBonus = user.GetLocalInt(target.GlobalID.ToString()); ipBonusChance += itemHarvestBonus * 2 + scanningBonus * 2; baseXP = baseXP + scanningBonus * 5; NWItem resource = _.CreateItemOnObject(itemResref, player.Object); if (roll <= ipBonusChance) { var ip = ResourceService.GetRandomComponentBonusIP(quality); BiowareXP2.IPSafeAddItemProperty(resource, ip.Item1, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true); switch (ip.Item2) { case 0: resource.Name = ColorTokenService.Green(resource.Name); break; case 1: resource.Name = ColorTokenService.Blue(resource.Name); break; case 2: resource.Name = ColorTokenService.Purple(resource.Name); break; case 3: resource.Name = ColorTokenService.Orange(resource.Name); break; } } float decayMinimum = 0.03f; float decayMaximum = 0.07f; if (delta > 0) { decayMinimum += delta * 0.1f; decayMaximum += delta * 0.1f; } user.SendMessage("You harvest " + resource.Name + "."); DurabilityService.RunItemDecay(player, item, RandomService.RandomFloat(decayMinimum, decayMaximum)); int xp = baseXP; SkillService.GiveSkillXP(player, SkillType.Harvesting, xp); if (remaining <= 0) { NWPlaceable prop = target.GetLocalObject("RESOURCE_PROP_OBJ"); if (prop.IsValid) { prop.Destroy(); } target.Destroy(); user.DeleteLocalInt(target.GlobalID.ToString()); } else { target.SetLocalInt("RESOURCE_COUNT", remaining); } _.ApplyEffectAtLocation(DURATION_TYPE_INSTANT, _.EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3), target.Location); }
public static void ApplyComponentBonus(NWItem product, ItemProperty sourceIP) { ComponentBonusType bonusType = (ComponentBonusType)_.GetItemPropertySubType(sourceIP); int amount = _.GetItemPropertyCostTableValue(sourceIP); ItemProperty prop = null; string sourceTag = string.Empty; // A note about the sourceTags: // It's not currently possible to create custom item properties on items. To get around this, // we look in an inaccessible container which holds the custom item properties. Then, we get the // item that has the item property we want. From there we take that item property and copy it to // the crafted item. // This is a really roundabout way to do it, but it's the only option for now. Hopefully a feature to // directly add the item properties comes in to NWNX in the future. for (int x = 1; x <= amount; x++) { switch (bonusType) { case ComponentBonusType.ModSocketRed: sourceTag = "rslot_red"; break; case ComponentBonusType.ModSocketBlue: sourceTag = "rslot_blue"; break; case ComponentBonusType.ModSocketGreen: sourceTag = "rslot_green"; break; case ComponentBonusType.ModSocketYellow: sourceTag = "rslot_yellow"; break; case ComponentBonusType.ModSocketPrismatic: sourceTag = "rslot_prismatic"; break; case ComponentBonusType.DurabilityUp: var maxDur = DurabilityService.GetMaxDurability(product) + amount; DurabilityService.SetMaxDurability(product, maxDur); DurabilityService.SetDurability(product, maxDur); break; case ComponentBonusType.ChargesUp: product.Charges += amount; break; case ComponentBonusType.ACUp: product.CustomAC += amount; break; case ComponentBonusType.HarvestingUp: product.HarvestingBonus += amount; break; case ComponentBonusType.CastingSpeedUp: product.CastingSpeed += amount; break; case ComponentBonusType.ArmorsmithUp: product.CraftBonusArmorsmith += amount; break; case ComponentBonusType.WeaponsmithUp: product.CraftBonusWeaponsmith += amount; break; case ComponentBonusType.CookingUp: product.CraftBonusCooking += amount; break; case ComponentBonusType.EngineeringUp: product.CraftBonusEngineering += amount; break; case ComponentBonusType.FabricationUp: product.CraftBonusFabrication += amount; break; case ComponentBonusType.HPUp: product.HPBonus += amount; break; case ComponentBonusType.FPUp: product.FPBonus += amount; break; case ComponentBonusType.EnmityUp: product.EnmityRate += amount; break; case ComponentBonusType.EnmityDown: product.EnmityRate -= amount; break; case ComponentBonusType.DarkPotencyUp: product.DarkPotencyBonus += amount; break; case ComponentBonusType.LightPotencyUp: product.LightPotencyBonus += amount; break; case ComponentBonusType.MindPotencyUp: product.MindPotencyBonus += amount; break; case ComponentBonusType.LuckUp: product.LuckBonus += amount; break; case ComponentBonusType.MeditateUp: product.MeditateBonus += amount; break; case ComponentBonusType.RestUp: product.RestBonus += amount; break; case ComponentBonusType.MedicineUp: product.MedicineBonus += amount; break; case ComponentBonusType.HPRegenUp: product.HPRegenBonus += amount; break; case ComponentBonusType.FPRegenUp: product.FPRegenBonus += amount; break; case ComponentBonusType.BaseAttackBonusUp: product.BaseAttackBonus += amount; break; case ComponentBonusType.SneakAttackUp: product.SneakAttackBonus += amount; break; case ComponentBonusType.DamageUp: product.DamageBonus += amount; break; case ComponentBonusType.DarkPotencyDown: product.DarkPotencyBonus -= amount; break; case ComponentBonusType.LightPotencyDown: product.LightPotencyBonus -= amount; break; case ComponentBonusType.StructureBonusUp: product.StructureBonus += amount; break; case ComponentBonusType.StrengthUp: product.StrengthBonus += amount; break; case ComponentBonusType.DexterityUp: product.DexterityBonus += amount; break; case ComponentBonusType.ConstitutionUp: product.ConstitutionBonus += amount; break; case ComponentBonusType.WisdomUp: product.WisdomBonus += amount; break; case ComponentBonusType.IntelligenceUp: product.IntelligenceBonus += amount; break; case ComponentBonusType.CharismaUp: product.CharismaBonus += amount; break; case ComponentBonusType.AttackBonusUp: prop = _.ItemPropertyAttackBonus(amount); break; case ComponentBonusType.DurationUp: product.DurationBonus += amount; break; case ComponentBonusType.ScanningUp: product.ScanningBonus += amount; break; case ComponentBonusType.ScavengingUp: product.ScavengingBonus += amount; break; case ComponentBonusType.MindPotencyDown: product.MindPotencyBonus -= amount; break; case ComponentBonusType.ElectricalPotencyUp: product.ElectricalPotencyBonus += amount; break; case ComponentBonusType.ElectricalPotencyDown: product.ElectricalPotencyBonus -= amount; break; case ComponentBonusType.ForcePotencyUp: product.ForcePotencyBonus += amount; break; case ComponentBonusType.ForcePotencyDown: product.ForcePotencyBonus -= amount; break; case ComponentBonusType.ForceAccuracyUp: product.ForceAccuracyBonus += amount; break; case ComponentBonusType.ForceAccuracyDown: product.ForceAccuracyBonus -= amount; break; case ComponentBonusType.ForceDefenseUp: product.ForceDefenseBonus += amount; break; case ComponentBonusType.ForceDefenseDown: product.ForceDefenseBonus -= amount; break; case ComponentBonusType.ElectricalDefenseUp: product.ElectricalDefenseBonus += amount; break; case ComponentBonusType.ElectricalDefenseDown: product.ElectricalDefenseBonus -= amount; break; case ComponentBonusType.MindDefenseUp: product.MindDefenseBonus += amount; break; case ComponentBonusType.MindDefenseDown: product.MindDefenseBonus -= amount; break; case ComponentBonusType.LightDefenseUp: product.LightDefenseBonus += amount; break; case ComponentBonusType.LightDefenseDown: product.LightDefenseBonus -= amount; break; case ComponentBonusType.DarkDefenseUp: product.DarkDefenseBonus += amount; break; case ComponentBonusType.DarkDefenseDown: product.DarkDefenseBonus -= amount; break; case ComponentBonusType.PilotingUp: product.PilotingBonus += amount; break; default: throw new ArgumentOutOfRangeException(); } if (!string.IsNullOrWhiteSpace(sourceTag)) { prop = ItemService.GetCustomItemPropertyByItemTag(sourceTag); } if (prop == null) { return; } BiowareXP2.IPSafeAddItemProperty(product, prop, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true); } }
private static void ProcessVersion1LightsaberItem(NWItem item) { // Lightsaber appearances have changed because they're now considered training foils. // Depending on the type of lightsaber, modify the name, appearance and other details of the item. int baseItemType; // Appearance strings were built by running NWNXItem.GetEntireItemAppearance on the new design. // Then the result was copied over to here. Unfortunately, setting each individual part's graphic didn't work // so I used this instead. string appearanceString; switch (item.Resref) { // Blue lightsabers case "lightsaber_b": case "lightsaber_1": case "lightsaber_2": case "lightsaber_3": case "lightsaber_4": baseItemType = 1; // 1 = Longsword appearanceString = "000000000000FBFBD300000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; break; // Red Lightsabers case "lightsaber_r_b": case "lightsaber_r_1": case "lightsaber_r_2": case "lightsaber_r_3": case "lightsaber_r_4": baseItemType = 1; // 1 = Longsword appearanceString = "000000000000FBFBD500000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; break; // Green Lightsabers case "lightsaber_g_b": case "lightsaber_g_1": case "lightsaber_g_2": case "lightsaber_g_3": case "lightsaber_g_4": baseItemType = 1; // 1 = Longsword appearanceString = "000000000000FBFBD400000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; break; // Yellow Lightsabers case "lightsaber_y_b": case "lightsaber_y_1": case "lightsaber_y_2": case "lightsaber_y_3": case "lightsaber_y_4": baseItemType = 1; // 1 = Longsword appearanceString = "000000000000FBFBB500000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; // Also give a VFX item property for yellow sabers. var ip = _.ItemPropertyVisualEffect(_.ITEM_VISUAL_HOLY); BiowareXP2.IPSafeAddItemProperty(item, ip, 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); break; default: return; } NWNXItem.SetBaseItemType(item, baseItemType); NWNXItem.RestoreItemAppearance(item, appearanceString); item.SetLocalInt("LIGHTSABER", _.TRUE); item.Name = item.Name.Replace("Lightsaber", "Training Foil").Replace("Saberstaff", "Training Foil Staff"); }
private void OnCompleteSmelt(OnCompleteSmelt data) { NWPlayer player = data.Player; string oreResref = data.OreResref; List <ItemProperty> itemProperties = data.ItemProperties; player.IsBusy = false; int rank = SkillService.GetPCSkillRank(player, SkillType.Harvesting); int level = CraftService.GetIngotLevel(oreResref); string ingotResref = CraftService.GetIngotResref(oreResref); if (level < 0 || string.IsNullOrWhiteSpace(ingotResref)) { return; } int delta = rank - level; int count = 2; if (delta > 2) { count = delta; } if (count > 4) { count = 4; } if (RandomService.Random(100) + 1 <= PerkService.GetCreaturePerkLevel(player, PerkType.Lucky)) { count++; } if (RandomService.Random(100) + 1 <= PerkService.GetCreaturePerkLevel(player, PerkType.ProcessingEfficiency) * 10) { count++; } for (int x = 1; x <= count; x++) { var item = (_.CreateItemOnObject(ingotResref, player.Object)); int chance; switch (x) { case 1: case 2: chance = 100; break; case 3: chance = 70; break; case 4: chance = 60; break; case 5: chance = 50; break; default: chance = 30; break; } foreach (var ip in itemProperties) { if (RandomService.D100(1) <= chance) { BiowareXP2.IPSafeAddItemProperty(item, ip, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true); } } } var effectiveStats = PlayerStatService.GetPlayerItemEffectiveStats(player); int harvestingSkill = SkillService.GetPCSkillRank(player, SkillType.Harvesting); int perkBonus = PerkService.GetCreaturePerkLevel(player, PerkType.StronidiumRefining) + 1; int stronidiumAmount = 10 + effectiveStats.Harvesting + harvestingSkill + RandomService.Random(1, 5); stronidiumAmount *= perkBonus; _.CreateItemOnObject("stronidium", player.Object, stronidiumAmount); int xp = (int)SkillService.CalculateRegisteredSkillLevelAdjustedXP(100, level, rank); SkillService.GiveSkillXP(player, SkillType.Harvesting, xp); }
private static void ApplyWeaponPenalties(NWPlayer oPC, NWItem oItem) { SkillType skillType = ItemService.GetSkillTypeForItem(oItem); if (skillType == SkillType.Unknown || skillType == SkillType.HeavyArmor || skillType == SkillType.LightArmor || skillType == SkillType.ForceArmor || skillType == SkillType.Shields) { return; } int skillID = (int)skillType; int rank = GetPCSkillRank(oPC, skillID); int recommendedRank = oItem.RecommendedLevel; if (rank >= recommendedRank) { return; } int delta = rank - recommendedRank; int penalty; if (delta <= -20) { penalty = 99; } else if (delta <= -16) { penalty = 5; } else if (delta <= -12) { penalty = 4; } else if (delta <= -8) { penalty = 3; } else if (delta <= -4) { penalty = 2; } else if (delta <= 0) { penalty = 1; } else { penalty = 99; } // No combat damage penalty if (penalty == 99) { ItemProperty noDamage = _.ItemPropertyNoDamage(); noDamage = _.TagItemProperty(noDamage, IPWeaponPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, noDamage, 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); penalty = 5; // Reset to 5 so that the following penalties apply. } // Decreased attack penalty ItemProperty ipPenalty = _.ItemPropertyAttackPenalty(penalty); ipPenalty = _.TagItemProperty(ipPenalty, IPWeaponPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, ipPenalty, 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); // Decreased damage penalty ipPenalty = _.ItemPropertyDamagePenalty(penalty); ipPenalty = _.TagItemProperty(ipPenalty, IPWeaponPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, ipPenalty, 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); // Decreased enhancement bonus penalty ipPenalty = _.ItemPropertyEnhancementPenalty(penalty); ipPenalty = _.TagItemProperty(ipPenalty, IPWeaponPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, ipPenalty, 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); oPC.SendMessage("A penalty has been applied to your weapon '" + oItem.Name + "' due to your skill being under the recommended level."); }
public bool Run(params object[] args) { NWPlaceable point = (Object.OBJECT_SELF); NWPlayer oPC = (_.GetLastOpenedBy()); if (!oPC.IsPlayer) { return(false); } var effectiveStats = PlayerStatService.GetPlayerItemEffectiveStats(oPC); const int baseChanceToFullyHarvest = 50; bool alwaysDestroys = point.GetLocalInt("SCAVENGE_POINT_ALWAYS_DESTROYS") == 1; bool hasBeenSearched = point.GetLocalInt("SCAVENGE_POINT_FULLY_HARVESTED") == 1; if (hasBeenSearched) { oPC.SendMessage("There's nothing left to harvest here..."); return(true); } // Not fully harvested but the timer hasn't counted down yet. int refillTick = point.GetLocalInt("SCAVENGE_POINT_REFILL_TICKS"); if (refillTick > 0) { oPC.SendMessage("You couldn't find anything new here. Check back later..."); return(true); } if (!oPC.IsPlayer && !oPC.IsDM) { return(false); } int rank = SkillService.GetPCSkillRank(oPC, SkillType.Scavenging); int lootTableID = point.GetLocalInt("SCAVENGE_POINT_LOOT_TABLE_ID"); int level = point.GetLocalInt("SCAVENGE_POINT_LEVEL"); int delta = level - rank; if (delta > 8) { oPC.SendMessage("You aren't skilled enough to scavenge through this. (Required Level: " + (level - 8) + ")"); oPC.AssignCommand(() => _.ActionInteractObject(point.Object)); return(true); } int dc = 6 + delta; if (dc <= 4) { dc = 4; } int searchAttempts = 1 + CalculateSearchAttempts(oPC); int luck = PerkService.GetPCPerkLevel(oPC, PerkType.Lucky) + effectiveStats.Luck; if (RandomService.Random(100) + 1 <= luck / 2) { dc--; } oPC.AssignCommand(() => _.ActionPlayAnimation(_.ANIMATION_LOOPING_GET_LOW, 1.0f, 2.0f)); for (int attempt = 1; attempt <= searchAttempts; attempt++) { int roll = RandomService.Random(20) + 1; if (roll >= dc) { oPC.FloatingText(ColorTokenService.SkillCheck("Search: *success*: (" + roll + " vs. DC: " + dc + ")")); ItemVO spawnItem = LootService.PickRandomItemFromLootTable(lootTableID); if (spawnItem == null) { return(false); } if (!string.IsNullOrWhiteSpace(spawnItem.Resref) && spawnItem.Quantity > 0) { NWItem resource = _.CreateItemOnObject(spawnItem.Resref, point.Object, spawnItem.Quantity); var componentIP = resource.ItemProperties.FirstOrDefault(x => _.GetItemPropertyType(x) == (int)CustomItemPropertyType.ComponentType); if (componentIP != null) { // Add properties to the item based on Scavenging skill. Similar logic to the resource harvester. var chance = RandomService.Random(1, 100) + PerkService.GetPCPerkLevel(oPC, PerkType.Lucky) + effectiveStats.Luck; ResourceQuality quality; if (chance < 50) { quality = ResourceQuality.Low; } else if (chance < 75) { quality = ResourceQuality.Normal; } else if (chance < 95) { quality = ResourceQuality.High; } else { quality = ResourceQuality.VeryHigh; } int ipBonusChance = ResourceService.CalculateChanceForComponentBonus(oPC, (level / 10 + 1), quality, true); if (RandomService.Random(1, 100) <= ipBonusChance) { var ip = ResourceService.GetRandomComponentBonusIP(ResourceQuality.Normal); BiowareXP2.IPSafeAddItemProperty(resource, ip.Item1, 0.0f, AddItemPropertyPolicy.IgnoreExisting, true, true); switch (ip.Item2) { case 0: resource.Name = ColorTokenService.Green(resource.Name); break; case 1: resource.Name = ColorTokenService.Blue(resource.Name); break; case 2: resource.Name = ColorTokenService.Purple(resource.Name); break; case 3: resource.Name = ColorTokenService.Orange(resource.Name); break; } } } } float xp = SkillService.CalculateRegisteredSkillLevelAdjustedXP(200, level, rank); SkillService.GiveSkillXP(oPC, SkillType.Scavenging, (int)xp); } else { oPC.FloatingText(ColorTokenService.SkillCheck("Search: *failure*: (" + roll + " vs. DC: " + dc + ")")); float xp = SkillService.CalculateRegisteredSkillLevelAdjustedXP(50, level, rank); SkillService.GiveSkillXP(oPC, SkillType.Scavenging, (int)xp); } dc += RandomService.Random(3) + 1; } // Chance to destroy the scavenge point. int chanceToFullyHarvest = baseChanceToFullyHarvest - (PerkService.GetPCPerkLevel(oPC, PerkType.CarefulScavenger) * 5); string growingPlantID = point.GetLocalString("GROWING_PLANT_ID"); if (!string.IsNullOrWhiteSpace(growingPlantID)) { Data.Entity.GrowingPlant growingPlant = FarmingService.GetGrowingPlantByID(new Guid(growingPlantID)); chanceToFullyHarvest = chanceToFullyHarvest - (growingPlant.LongevityBonus); } if (chanceToFullyHarvest <= 5) { chanceToFullyHarvest = 5; } if (alwaysDestroys || RandomService.Random(100) + 1 <= chanceToFullyHarvest) { point.SetLocalInt("SCAVENGE_POINT_FULLY_HARVESTED", 1); oPC.SendMessage("This resource has been fully harvested..."); } // Otherwise the scavenge point will be refilled in 10-20 minutes. else { point.SetLocalInt("SCAVENGE_POINT_REFILL_TICKS", 100 + RandomService.Random(100)); } point.SetLocalInt("SCAVENGE_POINT_DESPAWN_TICKS", 30); return(true); }
private static void ApplyEquipmentPenalties(NWPlayer oPC, NWItem oItem) { SkillType skill = ItemService.GetSkillTypeForItem(oItem); if (skill == SkillType.Unknown) { return; } int rank = GetPCSkillRank(oPC, skill); int delta = oItem.RecommendedLevel - rank; if (delta <= 0) { return; } int str = 0; int dex = 0; int con = 0; int wis = 0; int @int = 0; int cha = 0; int ab = 0; int eb = 0; foreach (var ip in oItem.ItemProperties) { int type = _.GetItemPropertyType(ip); int value = _.GetItemPropertyCostTableValue(ip); if (type == ITEM_PROPERTY_ABILITY_BONUS) { int abilityType = _.GetItemPropertySubType(ip); switch (abilityType) { case ABILITY_STRENGTH: str += value; break; case ABILITY_CONSTITUTION: con += value; break; case ABILITY_DEXTERITY: dex += value; break; case ABILITY_WISDOM: wis += value; break; case ABILITY_INTELLIGENCE: @int += value; break; case ABILITY_CHARISMA: cha += value; break; } } else if (type == ITEM_PROPERTY_DECREASED_ABILITY_SCORE) { int abilityType = _.GetItemPropertySubType(ip); switch (abilityType) { case ABILITY_STRENGTH: str -= value; break; case ABILITY_CONSTITUTION: con -= value; break; case ABILITY_DEXTERITY: dex -= value; break; case ABILITY_WISDOM: wis -= value; break; case ABILITY_INTELLIGENCE: @int -= value; break; case ABILITY_CHARISMA: cha -= value; break; } } else if (type == ITEM_PROPERTY_ATTACK_BONUS) { ab += value; } else if (type == ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER) { ab -= value; } else if (type == ITEM_PROPERTY_ENHANCEMENT_BONUS) { eb += value; } else if (type == ITEM_PROPERTY_DECREASED_ENHANCEMENT_MODIFIER) { eb -= value; } } // Apply penalties only if total value is greater than 0. Penalties don't scale. if (str > 0) { int newStr = 1 + delta / 5; if (newStr > str) { newStr = str; } ItemProperty ip = _.ItemPropertyDecreaseAbility(ABILITY_STRENGTH, newStr); ip = _.TagItemProperty(ip, IPEquipmentPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, ip, 0.0f, AddItemPropertyPolicy.IgnoreExisting, false, false); } if (dex > 0) { int newDex = 1 + delta / 5; if (newDex > dex) { newDex = dex; } ItemProperty ip = _.ItemPropertyDecreaseAbility(ABILITY_DEXTERITY, newDex); ip = _.TagItemProperty(ip, IPEquipmentPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, ip, 0.0f, AddItemPropertyPolicy.IgnoreExisting, false, false); } if (con > 0) { int newCon = 1 + delta / 5; if (newCon > con) { newCon = con; } ItemProperty ip = _.ItemPropertyDecreaseAbility(ABILITY_CONSTITUTION, newCon); ip = _.TagItemProperty(ip, IPEquipmentPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, ip, 0.0f, AddItemPropertyPolicy.IgnoreExisting, false, false); } if (@int > 0) { int newInt = 1 + delta / 5; if (newInt > @int) { newInt = @int; } ItemProperty ip = _.ItemPropertyDecreaseAbility(ABILITY_INTELLIGENCE, newInt); ip = _.TagItemProperty(ip, IPEquipmentPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, ip, 0.0f, AddItemPropertyPolicy.IgnoreExisting, false, false); } if (wis > 0) { int newWis = 1 + delta / 5; if (newWis > wis) { newWis = wis; } ItemProperty ip = _.ItemPropertyDecreaseAbility(ABILITY_WISDOM, newWis); ip = _.TagItemProperty(ip, IPEquipmentPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, ip, 0.0f, AddItemPropertyPolicy.IgnoreExisting, false, false); } if (cha > 0) { int newCha = 1 + delta / 5; if (newCha > cha) { newCha = cha; } ItemProperty ip = _.ItemPropertyDecreaseAbility(ABILITY_CHARISMA, newCha); ip = _.TagItemProperty(ip, IPEquipmentPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, ip, 0.0f, AddItemPropertyPolicy.IgnoreExisting, false, false); } if (ab > 0) { int newAB = 1 + delta / 5; if (newAB > ab) { newAB = ab; } ItemProperty ip = _.ItemPropertyAttackPenalty(newAB); ip = _.TagItemProperty(ip, IPEquipmentPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, ip, 0.0f, AddItemPropertyPolicy.IgnoreExisting, false, false); } if (eb > 0) { int newEB = 1 + delta / 5; if (newEB > eb) { newEB = eb; } ItemProperty ip = _.ItemPropertyEnhancementPenalty(newEB); ip = _.TagItemProperty(ip, IPEquipmentPenaltyTag); BiowareXP2.IPSafeAddItemProperty(oItem, ip, 0.0f, AddItemPropertyPolicy.IgnoreExisting, false, false); } }
void WildshapeCopyWeaponProperties(uint pc, uint oldWeapon, uint newWeapon) { if (GetIsObjectValid(oldWeapon) && GetIsObjectValid(newWeapon)) { ItemProperty ip = GetFirstItemProperty(oldWeapon); // If both are Melee Weapons if (!GetWeaponRanged(oldWeapon) && !GetWeaponRanged(newWeapon)) { while (GetIsItemPropertyValid(ip)) { AddItemProperty(DurationType.Permanent, ip, newWeapon); ip = GetNextItemProperty(oldWeapon); }// while } // If both are Ranged Weapons else if (GetWeaponRanged(oldWeapon) && GetWeaponRanged(newWeapon)) { bool unlimitedAmmoFound = false; ItemProperty ipNew; int oldMightyValue = 0; uint ammo; while (GetIsItemPropertyValid(ip)) { if (GetItemPropertyType(ip) == ItemPropertyType.UnlimitedAmmunition) // 61 = Unlimited Ammo { // For some reason, when removing/replacing an unlimited // ammo property, the corresponding missile type will get // dropped in the player's inventory, so we have to remove // that missile again to prevent abuse. unlimitedAmmoFound = true; ammo = GetItemInSlot(InventorySlotType.Arrows, pc); if (!GetIsObjectValid(ammo)) { ammo = GetItemInSlot(InventorySlotType.Bolts, pc); } if (!GetIsObjectValid(ammo)) { ammo = GetItemInSlot(InventorySlotType.Bullets, pc); } BiowareXP2.IPRemoveMatchingItemProperties(newWeapon, ItemPropertyType.UnlimitedAmmunition, DurationType.Permanent, -1); AddItemProperty(DurationType.Permanent, ip, newWeapon); DestroyObject(ammo); } else if (GetItemPropertyType(ip) == ItemPropertyType.Mighty) // 45 = Mighty { ipNew = GetFirstItemProperty(newWeapon); // Find the mighty value of the Polymorph's weapon while (GetIsItemPropertyValid(ipNew)) { if (GetItemPropertyType(ipNew) == ItemPropertyType.Mighty) { oldMightyValue = GetItemPropertyCostTableValue(ipNew); break; } ipNew = GetNextItemProperty(newWeapon); } // while // If new mighty value bigger, remove old one and add new one. if (GetItemPropertyCostTableValue(ip) > oldMightyValue) { RemoveItemProperty(newWeapon, ipNew); AddItemProperty(DurationType.Permanent, ip, newWeapon); } } else { AddItemProperty(DurationType.Permanent, ip, newWeapon); } ip = GetNextItemProperty(oldWeapon); } // while // Add basic unlimited ammo if necessary if (unlimitedAmmoFound == false && !GetItemHasItemProperty(newWeapon, ItemPropertyType.UnlimitedAmmunition)) { AddItemProperty(DurationType.Permanent, ItemPropertyUnlimitedAmmo(ItemPropertyUnlimitedType.Basic), newWeapon); } } } else if (GetWeaponRanged(newWeapon)) { // Add basic unlimited ammo if necessary if (!GetItemHasItemProperty(newWeapon, ItemPropertyType.UnlimitedAmmunition)) { AddItemProperty(DurationType.Permanent, ItemPropertyUnlimitedAmmo(ItemPropertyUnlimitedType.Basic), newWeapon); } } }
private Tuple <int, float> RunComponentBonusAttempt(NWPlayer player, NWItem component, float equipmentBonus, float chance, List <NWItem> itemSet) { int successAmount = 0; // Note - this line MUST be outside the foreach loop, as inspecting component properties will reset the component.ItemProperties counter. int componentLevel = component.LevelIncrease > 0 ? component.LevelIncrease : component.RecommendedLevel; if (componentLevel < 1) { componentLevel = 1; } foreach (var ip in component.ItemProperties) { int ipType = _.GetItemPropertyType(ip); if (ipType != (int)CustomItemPropertyType.ComponentBonus) { continue; } int bonusTypeID = _.GetItemPropertySubType(ip); int tlkID = Convert.ToInt32(_.Get2DAString("iprp_compbon", "Name", bonusTypeID)); int amount = _.GetItemPropertyCostTableValue(ip); string bonusName = _.GetStringByStrRef(tlkID) + " " + amount; float random = RandomService.RandomFloat() * 100.0f; float modifiedEquipmentBonus = equipmentBonus * 0.25f; if (random <= chance + modifiedEquipmentBonus) { foreach (var item in itemSet) { // If the target item is a component itself, we want to add the component bonuses instead of the // actual item property bonuses. // In other words, we want the custom item property "Component Bonus: AC UP" instead of the "AC Bonus" item property. var componentIP = item.ItemProperties.FirstOrDefault(x => _.GetItemPropertyType(x) == (int)CustomItemPropertyType.ComponentType); if (componentIP == null) { ComponentBonusService.ApplyComponentBonus(item, ip); } else { BiowareXP2.IPSafeAddItemProperty(item, ip, 0.0f, AddItemPropertyPolicy.IgnoreExisting, false, false); } } player.SendMessage(ColorTokenService.Green("Successfully applied component property: " + bonusName)); ComponentBonusType bonusType = (ComponentBonusType)_.GetItemPropertySubType(ip); if (bonusType != ComponentBonusType.DurabilityUp) { // Durability bonuses don't increase the penalty. Higher level components transfer multiple // properties more easily (to balance the fact that you can fit fewer of them on an item). int penalty; switch (componentLevel) { case 1: penalty = RandomService.Random(1, 19); break; case 2: penalty = RandomService.Random(1, 9); break; case 3: penalty = RandomService.Random(1, 6); break; case 4: penalty = RandomService.Random(1, 4); break; default: penalty = RandomService.Random(1, 3); break; } chance -= penalty; if (chance < 1) { chance = 1; } } successAmount++; } else { player.SendMessage(ColorTokenService.Red("Failed to apply component property: " + bonusName)); } } return(new Tuple <int, float>(successAmount, chance)); }