public static int NewStaff(CLRScriptBase script, int maxValue)
{
#region Check if collections need to be loaded. Load them if so
if (FireSpells[IP_CONST_CASTSPELL_BURNING_HANDS_2] == 0)
{
FireSpells = convertToStaffPrice(FireSpells);
ColdSpells = convertToStaffPrice(ColdSpells);
AcidSpells = convertToStaffPrice(AcidSpells);
ElectricSpells = convertToStaffPrice(ElectricSpells);
SoundSpells = convertToStaffPrice(SoundSpells);
PhysicalAttackSpells = convertToStaffPrice(PhysicalAttackSpells);
ForceSpells = convertToStaffPrice(ForceSpells);
MoraleSpells = convertToStaffPrice(MoraleSpells);
AntimoraleSpells = convertToStaffPrice(AntimoraleSpells);
MindControlSpells = convertToStaffPrice(MindControlSpells);
PerceptionSpells = convertToStaffPrice(PerceptionSpells);
PhysicalSpells = convertToStaffPrice(PhysicalSpells);
MentalSpells = convertToStaffPrice(MentalSpells);
Transmutations = convertToStaffPrice(Transmutations);
AntiMagicSpells = convertToStaffPrice(AntiMagicSpells);
IllusionSpells = convertToStaffPrice(IllusionSpells);
DeathSpells = convertToStaffPrice(DeathSpells);
EvilSpells = convertToStaffPrice(EvilSpells);
GoodSpells = convertToStaffPrice(GoodSpells);
ProtectionSpells = convertToStaffPrice(ProtectionSpells);
HealingSpells = convertToStaffPrice(HealingSpells);
SummonSpells = convertToStaffPrice(SummonSpells);
}
#endregion
Dictionary<int, int> currentAvailableSpells = new Dictionary<int,int>();
List<string> possibleNames = new List<string>();
#region Get Starting Collections
switch (Generation.rand.Next(22))
{
case 0:
copyDictionary(FireSpells, currentAvailableSpells);
copyList(FireNames, possibleNames);
break;
case 1:
copyDictionary(ColdSpells, currentAvailableSpells);
copyList(ColdNames, possibleNames);
break;
case 2:
copyDictionary(AcidSpells, currentAvailableSpells);
copyList(AcidNames, possibleNames);
break;
case 3:
copyDictionary(ElectricSpells, currentAvailableSpells);
copyList(ElectricNames, possibleNames);
break;
case 4:
copyDictionary(SoundSpells, currentAvailableSpells);
copyList(SoundNames, possibleNames);
break;
case 5:
copyDictionary(PhysicalAttackSpells, currentAvailableSpells);
copyList(PhysicalAttackNames, possibleNames);
break;
case 6:
copyDictionary(ForceSpells, currentAvailableSpells);
copyList(ForceNames, possibleNames);
break;
case 7:
copyDictionary(MoraleSpells, currentAvailableSpells);
copyList(MoraleNames, possibleNames);
break;
case 8:
copyDictionary(AntimoraleSpells, currentAvailableSpells);
copyList(AntimoraleNames, possibleNames);
break;
case 9:
copyDictionary(MindControlSpells, currentAvailableSpells);
copyList(MindControlNames, possibleNames);
break;
case 10:
copyDictionary(PerceptionSpells, currentAvailableSpells);
copyList(PerceptionNames, possibleNames);
break;
case 11:
copyDictionary(PhysicalSpells, currentAvailableSpells);
copyList(PhysicalNames, possibleNames);
break;
case 12:
copyDictionary(MentalSpells, currentAvailableSpells);
copyList(MentalNames, possibleNames);
break;
case 13:
copyDictionary(Transmutations, currentAvailableSpells);
copyList(TransmutNames, possibleNames);
break;
case 14:
copyDictionary(AntiMagicSpells, currentAvailableSpells);
copyList(AntiMagicNames, possibleNames);
break;
case 15:
copyDictionary(IllusionSpells, currentAvailableSpells);
copyList(IllusionNames, possibleNames);
break;
case 16:
copyDictionary(DeathSpells, currentAvailableSpells);
copyList(DeathNames, possibleNames);
break;
case 17:
copyDictionary(EvilSpells, currentAvailableSpells);
copyList(EvilNames, possibleNames);
break;
case 18:
copyDictionary(GoodSpells, currentAvailableSpells);
copyList(GoodNames, possibleNames);
break;
case 19:
copyDictionary(ProtectionSpells, currentAvailableSpells);
copyList(ProtectionNames, possibleNames);
break;
case 20:
copyDictionary(HealingSpells, currentAvailableSpells);
copyList(HealingNames, possibleNames);
break;
case 21:
copyDictionary(SummonSpells, currentAvailableSpells);
copyList(SummonNames, possibleNames);
break;
}
if (currentAvailableSpells.Count == 0 || possibleNames.Count == 0)
{
return 0;
}
#endregion
#region Select Spells from Collections Based on Price
Dictionary<int, int> SelectedSpells = new Dictionary<int, int>();
List<int> SelectedPrices = new List<int>();
int currentCharges = 5;
int maxSpellValue = maxValue;
while (true)
{
List<int> spellsToRemove = new List<int>();
foreach (int spell in currentAvailableSpells.Keys)
{
if (((currentAvailableSpells[spell] * 50) / currentCharges) > maxValue ||
currentAvailableSpells[spell] > maxSpellValue)
{
spellsToRemove.Add(spell);
}
}
foreach (int spell in spellsToRemove)
{
currentAvailableSpells.Remove(spell);
}
if (currentAvailableSpells.Count == 0)
{
if(SelectedSpells.Count == 0)
{
return 0;
}
else
{
break;
}
}
List<int> spellOptions = new List<int>();
foreach (int key in currentAvailableSpells.Keys)
{
spellOptions.Add(key);
}
int spellSelection = spellOptions[Generation.rand.Next(spellOptions.Count)];
switch (currentCharges)
{
case 1:
SelectedSpells.Add(spellSelection, IP_CONST_CASTSPELL_NUMUSES_1_CHARGE_PER_USE);
SelectedPrices.Add(currentAvailableSpells[spellSelection] * 50);
currentCharges--;
break;
case 2:
SelectedSpells.Add(spellSelection, IP_CONST_CASTSPELL_NUMUSES_2_CHARGES_PER_USE);
SelectedPrices.Add(currentAvailableSpells[spellSelection] * 25);
maxSpellValue = currentAvailableSpells[spellSelection] - 1;
maxValue -= currentAvailableSpells[spellSelection] * 25;
currentCharges--;
break;
case 3:
SelectedSpells.Add(spellSelection, IP_CONST_CASTSPELL_NUMUSES_3_CHARGES_PER_USE);
SelectedPrices.Add(currentAvailableSpells[spellSelection] * 16);
maxSpellValue = currentAvailableSpells[spellSelection] - 1;
maxValue -= currentAvailableSpells[spellSelection] * 16;
currentCharges--;
break;
case 4:
SelectedSpells.Add(spellSelection, IP_CONST_CASTSPELL_NUMUSES_4_CHARGES_PER_USE);
SelectedPrices.Add(currentAvailableSpells[spellSelection] * 12);
maxSpellValue = currentAvailableSpells[spellSelection] - 1;
maxValue -= currentAvailableSpells[spellSelection] * 12;
currentCharges--;
break;
case 5:
SelectedSpells.Add(spellSelection, IP_CONST_CASTSPELL_NUMUSES_5_CHARGES_PER_USE);
SelectedPrices.Add(currentAvailableSpells[spellSelection] * 10);
maxSpellValue = currentAvailableSpells[spellSelection] - 1;
maxValue -= currentAvailableSpells[spellSelection] * 10;
currentCharges--;
break;
}
if (currentCharges == 0)
{
break;
}
}
#endregion
#region Sum Predicted Values of Properties
SelectedPrices.Sort();
int value = SelectedPrices[0];
if (SelectedPrices.Count > 1)
{
value += (SelectedPrices[1] * 3 / 4);
}
if (SelectedPrices.Count > 2)
{
value += (SelectedPrices[2] / 2);
}
if (SelectedPrices.Count > 3)
{
value += (SelectedPrices[3] / 2);
}
if (SelectedPrices.Count > 4)
{
value += (SelectedPrices[4] / 2);
}
#endregion
#region Build the Actual Staff
uint staff = script.CreateItemOnObject(GenerateWeapon.WeaponResrefs[BASE_ITEM_QUARTERSTAFF], script.OBJECT_SELF, 1, "", FALSE);
script.SetItemCharges(staff, 50);
List<int> classRestrictions = new List<int>();
foreach (KeyValuePair<int, int> Spell in SelectedSpells)
{
script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyCastSpell(Spell.Key, Spell.Value), staff, 0.0f);
if (ALFA.Shared.Modules.InfoStore.IPCastSpells[Spell.Key].Spell.BardLevel >= 0 &&
!classRestrictions.Contains(IP_CONST_CLASS_BARD))
{
script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyLimitUseByClass(IP_CONST_CLASS_BARD), staff, 0.0f);
classRestrictions.Add(IP_CONST_CLASS_BARD);
}
if (ALFA.Shared.Modules.InfoStore.IPCastSpells[Spell.Key].Spell.ClericLevel >= 0 &&
!classRestrictions.Contains(IP_CONST_CLASS_CLERIC))
{
script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyLimitUseByClass(IP_CONST_CLASS_CLERIC), staff, 0.0f);
script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyLimitUseByClass(IP_CONST_CLASS_FAVORED_SOUL), staff, 0.0f);
classRestrictions.Add(IP_CONST_CLASS_CLERIC);
}
if (ALFA.Shared.Modules.InfoStore.IPCastSpells[Spell.Key].Spell.DruidLevel >= 0 &&
!classRestrictions.Contains(IP_CONST_CLASS_DRUID))
{
script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyLimitUseByClass(IP_CONST_CLASS_DRUID), staff, 0.0f);
script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyLimitUseByClass(IP_CONST_CLASS_SPIRIT_SHAMAN), staff, 0.0f);
classRestrictions.Add(IP_CONST_CLASS_DRUID);
}
if (ALFA.Shared.Modules.InfoStore.IPCastSpells[Spell.Key].Spell.WizardLevel >= 0 &&
!classRestrictions.Contains(IP_CONST_CLASS_WIZARD))
{
script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyLimitUseByClass(IP_CONST_CLASS_WIZARD), staff, 0.0f);
script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyLimitUseByClass(IP_CONST_CLASS_SORCERER), staff, 0.0f);
classRestrictions.Add(IP_CONST_CLASS_WIZARD);
}
if (ALFA.Shared.Modules.InfoStore.IPCastSpells[Spell.Key].Spell.PaladinLevel >= 0 &&
!classRestrictions.Contains(IP_CONST_CLASS_PALADIN))
{
script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyLimitUseByClass(IP_CONST_CLASS_PALADIN), staff, 0.0f);
classRestrictions.Add(IP_CONST_CLASS_PALADIN);
}
if (ALFA.Shared.Modules.InfoStore.IPCastSpells[Spell.Key].Spell.RangerLevel >= 0 &&
!classRestrictions.Contains(IP_CONST_CLASS_RANGER))
{
script.AddItemProperty(DURATION_TYPE_PERMANENT, script.ItemPropertyLimitUseByClass(IP_CONST_CLASS_RANGER), staff, 0.0f);
classRestrictions.Add(IP_CONST_CLASS_RANGER);
}
}
script.SetFirstName(staff, String.Format(possibleNames[Generation.rand.Next(possibleNames.Count)], "Staff"));
Pricing.CalculatePrice(script, staff);
#endregion
return value;
}