public void UseUpgradeScroll(short nScrollPOS, short nEquipPOS, bool bWhiteScroll) { if (Parent.Stats.nHP <= 0) { return; } var pScrollTemplate = InventoryManipulator.GetItem(Parent, InventoryType.Consume, nScrollPOS).Template as ConsumeItemTemplate; var pEquip = InventoryManipulator.GetItem(Parent, InventoryType.Equip, nEquipPOS) as GW_ItemSlotEquip; var nWhiteScrollPOS = InventoryManipulator.GetAnyItem(Parent, InventoryType.Consume, ItemConstants.WhiteScroll).Item1; if (pEquip == null || pScrollTemplate == null) { return; } if (pEquip.CashItem) { return; } if (pEquip.RemainingUpgradeCount <= 0 && pScrollTemplate.Recover <= 0) { return; } var bSuccess = pScrollTemplate.ScrollSuccess(Constants.Rand); var bDestroy = !bSuccess && pScrollTemplate.ScrollDestroy(Constants.Rand); bWhiteScroll = bWhiteScroll && nWhiteScrollPOS > 0; if (!ItemConstants.is_correct_upgrade_equip(pScrollTemplate.TemplateId, pEquip.nItemID)) // PE, validated client-side { return; } if (bSuccess) { if (pScrollTemplate.Recover > 0) { pEquip.RemainingUpgradeCount += (byte)pScrollTemplate.Recover; } else { if (pScrollTemplate.PreventSlip) { pEquip.nAttribute |= ItemAttributeFlags.Spikes; } else if (pScrollTemplate.WarmSupport) { pEquip.nAttribute |= ItemAttributeFlags.Cold; } else if (pScrollTemplate.RandStat) { var randRange = 2 + (2 * pScrollTemplate.IncRandVol); var gX = new GaussianRandom(); if (pEquip.niSTR > 0) { pEquip.niSTR = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niSTR, randRange, false)); } if (pEquip.niLUK > 0) { pEquip.niLUK = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niLUK, randRange, false)); } if (pEquip.niINT > 0) { pEquip.niINT = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niINT, randRange, false)); } if (pEquip.niDEX > 0) { pEquip.niDEX = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niDEX, randRange, false)); } if (pEquip.niACC > 0) { pEquip.niACC = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niACC, randRange, false)); } if (pEquip.niEVA > 0) { pEquip.niEVA = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niEVA, randRange, false)); } if (pEquip.niMaxHP > 0) { pEquip.niMaxHP = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niMaxHP, randRange, false)); } if (pEquip.niMaxMP > 0) { pEquip.niMaxMP = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niMaxMP, randRange, false)); } if (pEquip.niPAD > 0) { pEquip.niPAD = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niPAD, randRange, false)); } if (pEquip.niMAD > 0) { pEquip.niMAD = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niMAD, randRange, false)); } if (pEquip.niPDD > 0) { pEquip.niPDD = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niPDD, randRange, false)); } if (pEquip.niMDD > 0) { pEquip.niMDD = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niMDD, randRange, false)); } if (pEquip.niSpeed > 0) { pEquip.niSpeed = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niSpeed, randRange, false)); } if (pEquip.niJump > 0) { pEquip.niJump = (short)Math.Max(0, gX.GaussianDistributionVariation(pEquip.niJump, randRange, false)); } } else { pEquip.niSTR += (short)pScrollTemplate.IncSTR; pEquip.niLUK += (short)pScrollTemplate.IncLUK; pEquip.niINT += (short)pScrollTemplate.IncINT; pEquip.niDEX += (short)pScrollTemplate.IncDEX; pEquip.niMaxHP += (short)pScrollTemplate.IncMHP; pEquip.niMaxMP += (short)pScrollTemplate.IncMMP; pEquip.niPAD += (short)pScrollTemplate.IncPAD; // watk pEquip.niMAD += (short)pScrollTemplate.IncMAD; // matk pEquip.niPDD += (short)pScrollTemplate.IncPDD; // wdef pEquip.niMDD += (short)pScrollTemplate.IncMDD; // mdef pEquip.niACC += (short)pScrollTemplate.IncACC; // accuracy pEquip.niEVA += (short)pScrollTemplate.IncEVA; // avoid pEquip.niCraft += (short)pScrollTemplate.IncCraft; // still not sure wtf this is pEquip.niSpeed += (short)pScrollTemplate.IncSpeed; pEquip.niJump += (short)pScrollTemplate.IncJump; } } } if (bDestroy) { InventoryManipulator.RemoveFrom(Parent, InventoryType.Equip, nEquipPOS); } else // success or fail { if (pScrollTemplate.Recover <= 0) // not an upgrade count recovery scroll { pEquip.RemainingUpgradeCount -= 1; // reduce remaining upgrade count if no white scroll if (bSuccess) { pEquip.CurrentUpgradeCount += 1; // increase upgrade count } else if (bWhiteScroll) { pEquip.RemainingUpgradeCount += 1; } if (bWhiteScroll) { InventoryManipulator.RemoveFrom(Parent, InventoryType.Consume, nWhiteScrollPOS); } } Parent.Modify.Inventory(ctx => { ctx.UpdateEquipInformation(pEquip, nEquipPOS); }); } InventoryManipulator.RemoveFrom(Parent, InventoryType.Consume, nScrollPOS); Parent.StatisticsTracker.IncrementScrollUse(pScrollTemplate.TemplateId, bSuccess, bDestroy); Parent.Field.Broadcast(pEquip.ShowItemUpgradeEffect(Parent, bSuccess, bDestroy, bWhiteScroll)); }