Aura.Channel.Scripting.Scripts.NpcScript.Upgrade C# (CSharp) Метод

Upgrade() публичный Метод

Tries to upgrade item specified in the reply.
Only warn when something goes wrong, because problems can be caused by replies unknown to us or an outdated database. The NPCs don't have replies for failed upgrades, because the client disables invalid upgrades, you shouldn't be able to get a fail, unless you "hacked", modified client files, or Aura is outdated.
public Upgrade ( string upgradeReply ) : UpgradeResult
upgradeReply string
Результат UpgradeResult
		public UpgradeResult Upgrade(string upgradeReply)
		{
			var result = new UpgradeResult();

			// Example: @upgrade:22518872341757176:broad_sword_balance1
			var args = upgradeReply.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
			if (args.Length != 3 || !long.TryParse(args[1], out result.ItemEntityId))
			{
				Log.Warning("NpcScript.Upgrade: Player '{0:X16}' (Account: {1}) sent invalid reply.", this.Player.EntityId, this.Player.Client.Account.Id);
				return result;
			}

			// Get item
			result.Item = this.Player.Inventory.GetItem(result.ItemEntityId);
			if (result.Item == null || result.Item.OptionInfo.Upgraded == result.Item.OptionInfo.UpgradeMax)
			{
				Log.Warning("NpcScript.Upgrade: Player '{0:X16}' (Account: {1}) tried to upgrade invalid item.", this.Player.EntityId, this.Player.Client.Account.Id);
				return result;
			}

			// Get upgrade and check item and NPCs
			result.Upgrade = AuraData.ItemUpgradesDb.Find(args[2]);
			if (result.Upgrade == null)
			{
				Log.Warning("NpcScript.Upgrade: Player '{0:X16}' (Account: {1}) tried to apply an unknown upgrade ({2}).", this.Player.EntityId, this.Player.Client.Account.Id, args[2]);
				return result;
			}

			// Check upgrade and item
			if (!result.Item.Data.HasTag(result.Upgrade.Filter) || result.Item.Proficiency < result.Upgrade.Exp || !Math2.Between(result.Item.OptionInfo.Upgraded, result.Upgrade.UpgradeMin, result.Upgrade.UpgradeMax))
			{
				Log.Warning("NpcScript.Upgrade: Player '{0:X16}' (Account: {1}) tried to apply upgrade to invalid item.", this.Player.EntityId, this.Player.Client.Account.Id);
				return result;
			}
			if (!result.Upgrade.Npcs.Contains(this.NPC.Name.TrimStart('_').ToLower()))
			{
				Log.Warning("NpcScript.Upgrade: Player '{0:X16}' (Account: {1}) tried to apply upgrade '{2}' at an invalid NPC ({3}).", this.Player.EntityId, this.Player.Client.Account.Id, result.Upgrade.Ident, this.NPC.Name.TrimStart('_').ToLower());
				return result;
			}

			// Check for disabled Artisan
			// TODO: Feature check, once we do have Artisan.
			if (result.Upgrade.Effects.Any(a => a.Key == "Artisan"))
			{
				Send.MsgBox(this.Player, Localization.Get("Artisan upgrades aren't available yet."));
				return result;
			}

			// Check gold
			if (this.Gold < result.Upgrade.Gold)
				return result;

			// Take gold and exp
			result.Item.Proficiency -= result.Upgrade.Exp;
			this.Gold -= result.Upgrade.Gold;

			// Increase upgrade count
			result.Item.OptionInfo.Upgraded++;
			if (ChannelServer.Instance.Conf.World.UnlimitedUpgrades && result.Item.OptionInfo.Upgraded == result.Item.OptionInfo.UpgradeMax)
				result.Item.OptionInfo.Upgraded = 0;

			// Upgrade
			foreach (var effect in result.Upgrade.Effects)
			{
				switch (effect.Key)
				{
					case "MinAttack": result.Item.OptionInfo.AttackMin = (ushort)Math2.Clamp(1, result.Item.OptionInfo.AttackMax, result.Item.OptionInfo.AttackMin + effect.Value[0]); break;
					case "MaxAttack":
						result.Item.OptionInfo.AttackMax = (ushort)Math2.Clamp(1, ushort.MaxValue, result.Item.OptionInfo.AttackMax + effect.Value[0]);
						if (result.Item.OptionInfo.AttackMax < result.Item.OptionInfo.AttackMin)
							result.Item.OptionInfo.AttackMin = result.Item.OptionInfo.AttackMax;
						break;

					case "MinInjury": result.Item.OptionInfo.InjuryMin = (ushort)Math2.Clamp(0, result.Item.OptionInfo.InjuryMax, result.Item.OptionInfo.InjuryMin + effect.Value[0]); break;
					case "MaxInjury":
						result.Item.OptionInfo.InjuryMax = (ushort)Math2.Clamp(0, ushort.MaxValue, result.Item.OptionInfo.InjuryMax + effect.Value[0]);
						if (result.Item.OptionInfo.InjuryMax < result.Item.OptionInfo.InjuryMin)
							result.Item.OptionInfo.InjuryMin = result.Item.OptionInfo.InjuryMax;
						break;

					case "Balance": result.Item.OptionInfo.Balance = (byte)Math2.Clamp(0, byte.MaxValue, result.Item.OptionInfo.Balance + effect.Value[0]); break;
					case "Critical": result.Item.OptionInfo.Critical = (sbyte)Math2.Clamp(0, sbyte.MaxValue, result.Item.OptionInfo.Critical + effect.Value[0]); break;
					case "Defense": result.Item.OptionInfo.Defense = (int)Math2.Clamp(0, int.MaxValue, result.Item.OptionInfo.Defense + (long)effect.Value[0]); break;
					case "Protection": result.Item.OptionInfo.Protection = (short)Math2.Clamp(0, short.MaxValue, result.Item.OptionInfo.Protection + effect.Value[0]); break;
					case "AttackRange": result.Item.OptionInfo.EffectiveRange = (short)Math2.Clamp(0, short.MaxValue, result.Item.OptionInfo.EffectiveRange + effect.Value[0]); break;

					case "MaxDurability":
						result.Item.OptionInfo.DurabilityMax = (int)Math2.Clamp(1000, int.MaxValue, result.Item.OptionInfo.DurabilityMax + (long)(effect.Value[0] * 1000));
						if (result.Item.OptionInfo.DurabilityMax < result.Item.OptionInfo.Durability)
							result.Item.OptionInfo.Durability = result.Item.OptionInfo.DurabilityMax;
						break;

					case "MagicDefense":
						// MDEF:f:1.000000;MPROT:f:1.000000;MTWR:1:1;
						var mdef = result.Item.MetaData1.GetFloat("MDEF");
						result.Item.MetaData1.SetFloat("MDEF", Math2.Clamp(0, int.MaxValue, mdef + effect.Value[0]));
						break;

					case "MagicProtection":
						// MDEF:f:1.000000;MPROT:f:1.000000;MTWR:1:1;
						var mprot = result.Item.MetaData1.GetFloat("MPROT");
						result.Item.MetaData1.SetFloat("MPROT", Math2.Clamp(0, int.MaxValue, mprot + effect.Value[0]));
						break;

					case "ManaUse":
						// WU:s:00000003000000
						var manaUseWU = new WUUpgrades(result.Item.MetaData1.GetString("WU"));
						manaUseWU.ManaUse += (sbyte)effect.Value[0];
						result.Item.MetaData1.SetString("WU", manaUseWU.ToString());
						break;

					case "ManaBurn":
						var manaBurnWU = new WUUpgrades(result.Item.MetaData1.GetString("WU"));

						// Prior to G15S2 players lost all their Mana when
						// they unequipped a wand. This was removed via
						// feature, but before that this upgrade allowed
						// one to reduce the amount of Mana lost.
						// Afterwards the ManaBurn upgrade was turned into
						// a ManaUse automatically, but the bonus was halfed,
						// meaning if a ManaBurn upgrade gave -4% burn,
						// it gave -2% use after this update.
						if (!this.IsEnabled("ManaBurnRemove"))
							manaBurnWU.ManaBurn += (sbyte)effect.Value[0];
						else
							manaBurnWU.ManaUse += (sbyte)(effect.Value[0] / 2);

						result.Item.MetaData1.SetString("WU", manaBurnWU.ToString());
						break;

					case "ChainCasting":
						// Chain Casting: +4, Magic Attack: +21
						// EHLV:4:5;MTWR:1:1;OWNER:s:username;WU:s:30201400000015;
						var chainCastWU = new WUUpgrades(result.Item.MetaData1.GetString("WU"));
						chainCastWU.ChainCastSkillId = (ushort)effect.Value[0];
						chainCastWU.ChainCastLevel = (byte)effect.Value[1];
						result.Item.MetaData1.SetString("WU", chainCastWU.ToString());
						break;

					case "MagicDamage":
						// Charging Speed: +12%, MA: +16
						// EHLV:4:5;MTWR:1:1;OWNER:s:username;WU:s:00000000000c10;
						var magicDmgWU = new WUUpgrades(result.Item.MetaData1.GetString("WU"));
						magicDmgWU.MagicDamage += (sbyte)effect.Value[0];
						result.Item.MetaData1.SetString("WU", magicDmgWU.ToString());
						break;

					case "CastingSpeed":
						// Charging Speed: +12%, MA: +16
						// EHLV:4:5;MTWR:1:1;OWNER:s:username;WU:s:00000000000c10;
						var castingSpeedWU = new WUUpgrades(result.Item.MetaData1.GetString("WU"));
						castingSpeedWU.CastingSpeed += (sbyte)effect.Value[0];
						result.Item.MetaData1.SetString("WU", castingSpeedWU.ToString());
						break;

					case "MusicBuffBonus":
						// MBB:4:8;MBD:4:10;MTWR:1:2;OTU:1:1;SPTEC:1:1;
						var musicBuff = result.Item.MetaData1.GetInt("MBB");
						result.Item.MetaData1.SetInt("MBB", musicBuff + (int)effect.Value[0]);
						break;

					case "MusicBuffDuration":
						// MBB:4:8;MBD:4:10;MTWR:1:2;OTU:1:1;SPTEC:1:1;
						var musicBuffDur = result.Item.MetaData1.GetInt("MBD");
						result.Item.MetaData1.SetInt("MBD", musicBuffDur + (int)effect.Value[0]);
						break;

					case "CollectionBonus":
						// CTBONUS:2:40;CTSPEED:4:750;MTWR:1:1;
						var collectionBonusBuff = result.Item.MetaData1.GetShort("CTBONUS");
						result.Item.MetaData1.SetShort("CTBONUS", (short)(collectionBonusBuff + effect.Value[0]));
						break;

					case "CollectionBonusProduct":
						// CTBONUSPT:4:64004;CTBONUS:2:20;
						result.Item.MetaData1.SetInt("CTBONUSPT", (int)effect.Value[0]);
						break;

					case "CollectionSpeed":
						// CTBONUS:2:40;CTSPEED:4:750;MTWR:1:1;
						var collectionSpeedBuff = result.Item.MetaData1.GetInt("CTSPEED");
						result.Item.MetaData1.SetInt("CTSPEED", collectionSpeedBuff + (int)effect.Value[0]);
						break;

					case "LancePiercing":
						// EHLV:4:5;LKUP:8:262244;LP:1:4;LP_E:1:0;OWNER:s:character;SPTRP:1:1;   << Piercing Level 4
						// LP:1:1;QUAL:4:70;   << Piercing Level 1
						var lancePiercingBuff = result.Item.MetaData1.GetByte("LP");
						result.Item.MetaData1.SetByte("LP", (byte)(lancePiercingBuff + effect.Value[0]));
						break;

					case "SplashRadius":
						// SP_DMG:f:0.250000;SP_RAD:4:70;
						var splashRadiusBuff = result.Item.MetaData1.GetInt("SP_RAD");
						result.Item.MetaData1.SetInt("SP_RAD", splashRadiusBuff + (int)effect.Value[0]);
						break;

					case "SplashDamage":
						// SP_DMG:f:0.250000;SP_RAD:4:70;
						var splashDamageBuff = result.Item.MetaData1.GetFloat("SP_DMG");
						result.Item.MetaData1.SetFloat("SP_DMG", splashDamageBuff + effect.Value[0]);
						break;

					case "ImmuneMelee":
						// IM_MGC:f:0.050000;IM_MLE:f:0.050000;IM_RNG:f:0.050000;MDEF:f:2.000000;MPROT:f:3.000000;OTU:1:1;
						var immuneMeleeBuff = result.Item.MetaData1.GetFloat("IM_MLE");
						result.Item.MetaData1.SetFloat("IM_MLE", immuneMeleeBuff + effect.Value[0]);
						break;

					case "ImmuneRanged":
						// IM_MGC:f:0.050000;IM_MLE:f:0.050000;IM_RNG:f:0.050000;MDEF:f:2.000000;MPROT:f:3.000000;OTU:1:1;
						var immuneRangedBuff = result.Item.MetaData1.GetFloat("IM_RNG");
						result.Item.MetaData1.SetFloat("IM_RNG", immuneRangedBuff + effect.Value[0]);
						break;

					case "ImmuneMagic":
						// IM_MGC:f:0.050000;IM_MLE:f:0.050000;IM_RNG:f:0.050000;MDEF:f:2.000000;MPROT:f:3.000000;OTU:1:1;
						var immuneMagicBuff = result.Item.MetaData1.GetFloat("IM_MGC");
						result.Item.MetaData1.SetFloat("IM_MGC", immuneMagicBuff + effect.Value[0]);
						break;

					// TODO:
					// - MaxBullets
					// - Artisan

					default:
						Log.Unimplemented("Item upgrade '{0}'", effect.Key);
						break;
				}
			}

			// Personalization
			if (result.Upgrade.Personalize)
			{
				result.Item.OptionInfo.Flags |= ItemFlags.Personalized;
				result.Item.MetaData1.SetString("OWNER", this.Player.Name);
			}

			// Update item
			Send.ItemUpdate(this.Player, result.Item);

			// Send result
			Send.ItemUpgradeResult(this.Player, result.Item, result.Upgrade.Ident);

			result.Success = true;

			this.Player.Keywords.Give("ExperienceUpgrade");

			return result;
		}