public XmlNode GetGarrisonGuards(int iValue, bool GuardContainsRandomResources, eMonsterStrength Strength, XmlNode xndGuard) { //such low values are rediculus its a fix for someone that doesn't use the object set right iValue = Math.Max(iValue, 2500); iValue = (int)(iValue * KOEFF_GROW); /* увеличиваем охрану на 4х недельный прирост*/ int iStrengthFactor = (int)Strength; //dwp. в гарнизоне будет приоритет на 3 и 4 стека в охране int iGuardNumber = GetRandomWeightedGuardNumber(IGUARDNUMBERWEIGHT2); double[] dblarrLevelWeightList; // Random Randomizer.rnd = new Random(); int iCurrMin = 0; int iMaxValue = iValue; int iGuardLevel = 0; int iRandomSplitValue = iValue; int iRandomSplitDifference; ComboArmyBuilder ca_builder = new ComboArmyBuilder(ca_parser_, m_parser_, iGuardNumber); ca_builder.Power = iValue; //define alignment: //mixed army: 15% //allied creatures: 50% //all creatures from one town: 35% //dwp использовать в охране только одну фракцию? if (Settings.Default.SingleFactionGuards) // ƒј { ca_builder.Alignment = ArmyAlignment.Town; } else // Ќ≈“, то есть по старому { ca_builder.Alignment = (ArmyAlignment)Randomizer.Choice(new double[] { 15, 50, 35 }, 100); } #region First Assaign first monster allocation , then add other monsters as additional guards // dwp. еще улучшаем алгоритм генерации охраны состо¤щей из нескольких стеков dblarrLevelWeightList = GetLevelWeightList(iValue); // взвешиваем левелы по всей силе охраны iGuardLevel = DrawRandomGuardLevel(dblarrLevelWeightList, iValue); if (iGuardNumber > 1) { //split it , from min value to max value //dwp fixed bug //iRandomSplitValue = Randomizer.rnd.Next(BaseLevelValue[iGuardLevel] * 4, iMaxValue); //dwp делаем разбитие на куски по силе зависимой от количества стеков iRandomSplitValue = Randomizer.rnd.Next(iMaxValue / iGuardNumber, iMaxValue / (iGuardNumber - 1)); } iGuardLevel = AddLevelWithCap(iGuardLevel, iStrengthFactor); //add first random monster to army ca_builder.AddRandomMonster(iGuardLevel + 1, iRandomSplitValue, false); iCurrMin = iRandomSplitValue; #endregion //on 75% chance all monsters will be of the same alignments if (Randomizer.rnd.NextDouble() < 0.75) { //here pick a same alignment of guards //go over all guards (the number was randomly drawn - can be 1 only ) the last one is the reminder for (int i = 1; i < iGuardNumber - 1; i++) { if (iCurrMin + ARMY_POWER_GAP < iMaxValue - ARMY_POWER_GAP) { iRandomSplitValue = Randomizer.rnd.Next(iCurrMin + ARMY_POWER_GAP, iMaxValue); } else { break; //not enough to keep spliting } iRandomSplitDifference = iRandomSplitValue - iCurrMin; dblarrLevelWeightList = GetLevelWeightList(iRandomSplitDifference); //gets a list of weight for each level according to the value iGuardLevel = DrawRandomGuardLevel(dblarrLevelWeightList, iRandomSplitDifference); //returns random g lvl iGuardLevel = AddLevelWithCap(iGuardLevel, iStrengthFactor); ca_builder.AddRandomMonster(iGuardLevel + 1, iRandomSplitDifference, false); ///AddNewAdditionalGuard(xndAdditionalStacks, iGuardLevel + 1, iRandomSplitDifference,true); iCurrMin = iRandomSplitValue; } //add reminder iRandomSplitDifference = iValue - iCurrMin; //if reminder is some guards if (iRandomSplitDifference > BaseLevelValue[0]) { dblarrLevelWeightList = GetLevelWeightList(iRandomSplitDifference); //gets a list of weight for each level according to the value iGuardLevel = DrawRandomGuardLevel(dblarrLevelWeightList, iRandomSplitDifference); //returns random g lvl iGuardLevel = AddLevelWithCap(iGuardLevel, iStrengthFactor); ///AddNewAdditionalGuard(xndAdditionalStacks, iGuardLevel + 1, iRandomSplitDifference,true); ca_builder.AddRandomMonster(iGuardLevel + 1, iRandomSplitDifference, false); } } else { //here pick random alignment //go over all guards (the number was randomly drawn - can be 1 only ) the last one is the reminder for (int i = 1; i < iGuardNumber - 1; i++) { if (iCurrMin + ARMY_POWER_GAP < iMaxValue - ARMY_POWER_GAP) { iRandomSplitValue = Randomizer.rnd.Next(iCurrMin + ARMY_POWER_GAP, iMaxValue); } else { break; //not enough to keep spliting } iRandomSplitDifference = iRandomSplitValue - iCurrMin; dblarrLevelWeightList = GetLevelWeightList(iRandomSplitDifference); //gets a list of weight for each level according to the value iGuardLevel = DrawRandomGuardLevel(dblarrLevelWeightList, iRandomSplitDifference); //returns random g lvl iGuardLevel = AddLevelWithCap(iGuardLevel, iStrengthFactor); ca_builder.AddRandomMonster(iGuardLevel + 1, iRandomSplitDifference, false); ///AddNewAdditionalGuard(xndAdditionalStacks, iGuardLevel + 1, iRandomSplitDifference); iCurrMin = iRandomSplitValue; } //add reminder iRandomSplitDifference = iValue - iCurrMin; //if reminder is some guards if (iRandomSplitDifference > BaseLevelValue[0]) { dblarrLevelWeightList = GetLevelWeightList(iRandomSplitDifference); //gets a list of weight for each level according to the value iGuardLevel = DrawRandomGuardLevel(dblarrLevelWeightList, iRandomSplitDifference); //returns random g lvl iGuardLevel = AddLevelWithCap(iGuardLevel, iStrengthFactor); ///AddNewAdditionalGuard(xndAdditionalStacks, iGuardLevel + 1, iRandomSplitDifference); ca_builder.AddRandomMonster(iGuardLevel + 1, iRandomSplitDifference, false); } } ca_builder.SaveGarrison(xndGuard); //save garrison army Guards.strAligment = null; return(xndGuard); }
//todo: check if there is different levels of destribution when guard is mixed , if yes algorithem ok , if no need to check when difference in strangth is too big need to remove insagnificant guards //pos and id can be set when using the set object with object writer. public XmlNode GetRandomGuards(int iValue, bool GuardContainsRandomResources, eMonsterStrength Strength) { //such low values are rediculus its a fix for someone that doesn't use the object set right bool fl_no_grow = false; if (iValue < 0) /* охрана не должна расти на карте */ { iValue = (int)(-iValue * KOEFF_GROW); /* увеличиваем охрану на 4х недельный прирост*/ fl_no_grow = true; } iValue = Math.Max(iValue, 2500); int iStrengthFactor = (int)Strength; int iGuardNumber = GetRandomWeightedGuardNumber(IGUARDNUMBERWEIGHT); double[] dblarrLevelWeightList; // Random Randomizer.rnd = new Random(); int iCurrMin = 0; int iMaxValue = iValue; XmlNode xndRandomGuard = GetGeneralRandomXML().Clone(); int iGuardLevel = 0; int iRandomSplitValue = iValue; int iRandomSplitDifference; ComboArmyBuilder ca_builder = new ComboArmyBuilder(ca_parser_, m_parser_, iGuardNumber); ca_builder.Power = iValue; //define alignment: //mixed army: 15% //allied creatures: 50% //all creatures from one town: 35% //dwp использовать в охране только одну фракцию? if (Settings.Default.SingleFactionGuards) // ƒј { ca_builder.Alignment = ArmyAlignment.Town; } else // Ќ≈“, то есть по старому { ca_builder.Alignment = (ArmyAlignment)Randomizer.Choice(new double[] { 15, 50, 35 }, 100); } #region First Assaign first monster allocation , then add other monsters as additional guards // dwp. улучшаем алгоритм разбивание охраны на стеки // теперь дл¤ первого стека охраны выбираетс¤ адекватна¤ 1¤ часть, в соответсвии с общей силой охраны dblarrLevelWeightList = GetLevelWeightList(iValue); // взвешиваем левелы по всей силе охраны iGuardLevel = DrawRandomGuardLevel(dblarrLevelWeightList, iValue); if (iGuardNumber > 1) { //split it , from min value to max value //dwp fixed bug //iRandomSplitValue = Randomizer.rnd.Next(BaseLevelValue[iGuardLevel] * 4, iMaxValue); //dwp делаем разбитие на куски по силе зависимой от количества стеков iRandomSplitValue = Randomizer.rnd.Next(iMaxValue / iGuardNumber, iMaxValue / (iGuardNumber - 1)); } iGuardLevel = AddLevelWithCap(iGuardLevel, iStrengthFactor); #if (DEBUG) // { ca_tester_.PreBuildAnalyze(ca_builder); #endif //DEBUG } //add first random monster to army ca_builder.AddRandomMonster(iGuardLevel + 1, iRandomSplitValue, false); //dmitrik: first monster in not random as well as additionals ///XmlNode xndAdditionalStacks = AddPrimaryGuard(xndRandomGuard, iGuardLevel + 1, iRandomSplitValue); //XmlNode xndAdditionalStacks = SetPrimaryRandomLevel(xndRandomGuard , iGuardLevel+1 , iRandomSplitValue / BaseLevelValue[iGuardLevel]); iCurrMin = iRandomSplitValue; #endregion //on 75% chance all monsters will be of the same alignments if (Randomizer.rnd.NextDouble() < 0.75) { //here pick a same alignment of guards //go over all guards (the number was randomly drawn - can be 1 only ) the last one is the reminder for (int i = 1; i < iGuardNumber - 1; i++) { if (iCurrMin + ARMY_POWER_GAP < iMaxValue - ARMY_POWER_GAP) { iRandomSplitValue = Randomizer.rnd.Next(iCurrMin + ARMY_POWER_GAP, iMaxValue); } else { break; //not enough to keep spliting } iRandomSplitDifference = iRandomSplitValue - iCurrMin; dblarrLevelWeightList = GetLevelWeightList(iRandomSplitDifference); //gets a list of weight for each level according to the value iGuardLevel = DrawRandomGuardLevel(dblarrLevelWeightList, iRandomSplitDifference); //returns random g lvl iGuardLevel = AddLevelWithCap(iGuardLevel, iStrengthFactor); ca_builder.AddRandomMonster(iGuardLevel + 1, iRandomSplitDifference, false); ///AddNewAdditionalGuard(xndAdditionalStacks, iGuardLevel + 1, iRandomSplitDifference,true); iCurrMin = iRandomSplitValue; } //add reminder iRandomSplitDifference = iValue - iCurrMin; //if reminder is some guards if (iRandomSplitDifference > BaseLevelValue[0]) { dblarrLevelWeightList = GetLevelWeightList(iRandomSplitDifference); //gets a list of weight for each level according to the value iGuardLevel = DrawRandomGuardLevel(dblarrLevelWeightList, iRandomSplitDifference); //returns random g lvl iGuardLevel = AddLevelWithCap(iGuardLevel, iStrengthFactor); ///AddNewAdditionalGuard(xndAdditionalStacks, iGuardLevel + 1, iRandomSplitDifference,true); ca_builder.AddRandomMonster(iGuardLevel + 1, iRandomSplitDifference, false); } } else { //here pick random alignment //go over all guards (the number was randomly drawn - can be 1 only ) the last one is the reminder for (int i = 1; i < iGuardNumber - 1; i++) { if (iCurrMin + ARMY_POWER_GAP < iMaxValue - ARMY_POWER_GAP) { iRandomSplitValue = Randomizer.rnd.Next(iCurrMin + ARMY_POWER_GAP, iMaxValue); } else { break; //not enough to keep spliting } iRandomSplitDifference = iRandomSplitValue - iCurrMin; dblarrLevelWeightList = GetLevelWeightList(iRandomSplitDifference); //gets a list of weight for each level according to the value iGuardLevel = DrawRandomGuardLevel(dblarrLevelWeightList, iRandomSplitDifference); //returns random g lvl iGuardLevel = AddLevelWithCap(iGuardLevel, iStrengthFactor); ca_builder.AddRandomMonster(iGuardLevel + 1, iRandomSplitDifference, false); ///AddNewAdditionalGuard(xndAdditionalStacks, iGuardLevel + 1, iRandomSplitDifference); iCurrMin = iRandomSplitValue; } //add reminder iRandomSplitDifference = iValue - iCurrMin; //if reminder is some guards if (iRandomSplitDifference > BaseLevelValue[0]) { dblarrLevelWeightList = GetLevelWeightList(iRandomSplitDifference); //gets a list of weight for each level according to the value iGuardLevel = DrawRandomGuardLevel(dblarrLevelWeightList, iRandomSplitDifference); //returns random g lvl iGuardLevel = AddLevelWithCap(iGuardLevel, iStrengthFactor); ///AddNewAdditionalGuard(xndAdditionalStacks, iGuardLevel + 1, iRandomSplitDifference); ca_builder.AddRandomMonster(iGuardLevel + 1, iRandomSplitDifference, false); } } //remove first dummy additional stack ///xndAdditionalStacks.RemoveChild(xndAdditionalStacks.ChildNodes[0]); ca_builder.Save(xndRandomGuard); //save army #if (DEBUG) // { ca_tester_.PostBuildAnalyze(ca_builder); #endif //DEBUG } //set a random mood int iRandomMood = Randomizer.rnd.Next(4); xndRandomGuard.SelectSingleNode(".//Mood").InnerText = ((eMood)iRandomMood).ToString(); //dmitrik: no joining at all :) xndRandomGuard.SelectSingleNode(".//Courage").InnerText = eCourage.MONSTER_COURAGE_ALWAYS_FIGHT.ToString(); if (fl_no_grow) /* выключаем прирост на карте */ { xndRandomGuard.SelectSingleNode(".//DoesNotGrow").InnerText = "true"; xndRandomGuard.SelectSingleNode(".//DoesNotDependOnDifficulty").InnerText = "true"; } //on rare occations set a random courge //double dRandomCourageChange = Randomizer.rnd.NextDouble(); //if (dRandomCourageChange < 0.05) //{ // //set random courage // int iRandomCourage = Randomizer.rnd.Next(3); // if ( iValue < IMAXJOININGVALUE) // xndRandomGuard.SelectSingleNode(".//Courage").InnerText = ((eCourage)iRandomCourage).ToString(); //} Guards.strAligment = null; return(xndRandomGuard); }