Exemple #1
0
        public static Gem Base(int Color)
        {
            Gem b = new Gem();
            b.Grade = 0;
            b.Cost = 1;
            b.damage = 0; // gems that needs damage will have that properly setted (dmg_yellow=1)

            if (Color == COLOR_BLACK)
            {
                b.damage = 1.186168;
                b.blood = 1.0;
            }
            else if (Color == COLOR_KILLGEM)
            {
                b.damage = 1.0;
                b.critMult = 1.0;
                b.blood = 1.0;
            }
            else if (Color == COLOR_MANAGEM)
            {
                b.leech = 1.0;
                b.blood = 1.0;
            }
            else if (Color == COLOR_ORANGE)
                b.leech = 1.0;
            else if (Color == COLOR_YELLOW)
            {
                b.damage = 1.0;
                b.critMult = 1.0;
            }
            else if (Color == COLOR_RED)
                b.damage = 0.909091;

            return b;
        }
Exemple #2
0
		/// <summary>Initializes a new instance of the <see cref="Preset"/> class from the files specified in the passed resource.resx, and adds the information to the presets.</summary>
		/// <param name="letters">The list of letters that go into the gem (e.g., "obr").</param>
		/// <param name="name">The friendly name of the group, for display purposes.</param>
		/// <param name="embeddedResourceFullName">Full path to the embedded assembly resource file containing the schemes</param>
		public Preset(string letters, string name, string embeddedResourceFullName)
		{
			ThrowNull(letters, nameof(letters));
			ThrowNull(name, nameof(name));
			ThrowNull(embeddedResourceFullName, nameof(embeddedResourceFullName));

			this.Name = name;
			using (ResourceReader resourceReader = new ResourceReader(assembly.GetManifestResourceStream(embeddedResourceFullName)))
			{
				var dict = resourceReader.GetEnumerator();
				while (dict.MoveNext())
				{
					var gemCombines = new List<Instruction>();
					using (MemoryStream memoryStream = new MemoryStream((byte[])dict.Value))
					using (BinaryReader binaryStream = new BinaryReader(memoryStream))
					{
						while (memoryStream.Position < memoryStream.Length)
						{
							gemCombines.Add(Instruction.NewFromStream(binaryStream));
						}
					}

					List<Gem> gems = new List<Gem>();
					gems.Add(null);
					for (int i = 0; i < gemCombines[0].From; i++)
					{
						gems.Add(new Gem(letters[i]));
					}

					Gem lastGem = null;
					for (int i = 1; i < gemCombines.Count; i++)
					{
						var combine = gemCombines[i];
						Gem c1 = gems[combine.From];
						Gem c2 = gems[combine.To];
						lastGem = new Gem(c1, c2);
						gems.Add(lastGem);
					}

					this.Entries.Add(lastGem);
				}
			}
		}
        private void SetGems(string str)
        {
            combined.Clear();
            useCount.Clear();

            // Add baseGems to combined, and add values for their useage count.
            combined.Add(null);
            useCount.Add(-1);
            for (int i = 0; i < baseGems.Count; i++)
            {
                combined.Add(baseGems[i]);
                combined[i + 1].strID = (i + 1).ToString();
                useCount.Add(0);
            }

            do
            { // Get the first set of parenthesis and replace with incrementing id.
                int close = str.IndexOf(')');
                if (close == -1)
                    break;
                int open = str.LastIndexOf('(', close);
                string thisCombine = str.Substring(open + 1, close - open - 1);
                string[] cGems = thisCombine.Split('+');

                int gem1 = Convert.ToInt32(cGems[0]);
                int gem2 = Convert.ToInt32(cGems[1]);
                str = str.Replace("(" + gem1 + "+" + gem2 + ")", combined.Count.ToString());

                // Internal combines
                resultGem = Gem.Combine(combined[gem1], combined[gem2]);
                resultGem.strID = combined.Count.ToString();
                combined.Add(resultGem);

                useCount.Add(0); // Have to track times each gem is used.
                useCount[gem1]++; useCount[gem2]++;

            } while (true);
            // final combine
            if (str.Contains('+'))
            {  // if scheme was surrounded by parenthesis (e.g. ((1+1)+1)) this step is not required, was already done in loop.
                string[] lastGems = str.Split('+');

                int fgem1 = Convert.ToInt32(lastGems[0]);
                int fgem2 = Convert.ToInt32(lastGems[1]);

                resultGem = Gem.Combine(combined[fgem1], combined[fgem2]);
                resultGem.strID = combined.Count.ToString();
                combined.Add(resultGem);
                useCount.Add(0);
                useCount[fgem1]++; useCount[fgem2]++;
            }

            orderedCombined = new List<Gem>();
            orderedCombined.AddRange(combined);
        }
 private int GetEmpty(Gem[] a)
 {
     for (int i = 0; i < a.Length; i++)
     {
         if (a[i] == null)
             return i;
     }
     return -1;
 }
        private void CreateInstructions()
        {
            inst.Clear(); // Instructions list

            Gem[] inventory = new Gem[136]; // Array of what is in each of your inventory slots (Over 36 because this is before slot compression.)

            int[] slots = new int[combined.Count]; // Which slot each gem is in
            for (int i = 0; i < slots.Length; i++)
                slots[i] = -2;

            // Place baseGems in inventory slots
            for (int i = 0; i < baseGems.Count; i++)
            {
                inventory[i] = combined[i + 1];
                slots[i + 1] = i;
            }

            Slots_Required = 0;

            // All oneUse stuff is for slot compression. (This part of slot compression works.)
            List<int> oneUse = new List<int>();

            int startAt = baseGems.Count + 1; // Don't try to give instructinos for placing the base gems.
            for (int i = startAt; i < combined.Count; i++)
            {
                Gem g = combined[i];
                int c1 = Convert.ToInt32(g.Component1.strID);
                int c2 = Convert.ToInt32(g.Component2.strID);
                int slot1 = slots[c1];
                int slot2 = slots[c2];

                if (c1 == c2)
                { // Upgrade gem
                    useCount[c2] -= 2;
                    if (useCount[c2] > 0)
                    {
                        // DUPE
                        inst.Add(new Point(slot1, INST_DUPE));
                        slots[c1] = GetEmpty(inventory);
                        inventory[slots[c1]] = g.Component1;
                        CheckSlotReq(slots[c1]);
                    }
                    inst.Add(new Point(slot1, INST_UPGR));
                    inventory[slot1] = g;
                    slots[Convert.ToInt32(g.strID)] = slot1;
                }
                else
                {
                    if (useCount[c1] > 1)
                    { // DUPE
                        inst.Add(new Point(slot1, INST_DUPE));
                        slots[c1] = GetEmpty(inventory);
                        inventory[slots[c1]] = g.Component1;
                        CheckSlotReq(slots[c1]);
                    }
                    if (useCount[c2] > 1)
                    { // DUPE (repetitive code :/)
                        inst.Add(new Point(slot2, INST_DUPE));
                        slots[c2] = GetEmpty(inventory);
                        inventory[slots[c2]] = g.Component1;
                        CheckSlotReq(slots[c2]);
                    }
                    useCount[c1] -= 1;
                    useCount[c2] -= 1;
                    if (useCount[c1] == 1)
                        oneUse.Add(c1);
                    if (useCount[c2] == 1)
                        oneUse.Add(c2);

                    inst.Add(new Point(slot1, slot2));
                    inventory[slot1] = null;
                    inventory[slot2] = g;
                    slots[Convert.ToInt32(g.strID)] = slot2;
                    // None remaining? (Did not dupe)
                    // useCount[c1] == 0 should work here?
                    if (slots[c1] == slot1)
                        slots[c1] = -1;
                    if (slots[c2] == slot2)
                        slots[c2] = -1;

                    // Check oneUse combines
                    for (int iU = i + 2; iU < combined.Count; iU++)
                    {
                        Gem gU = combined[iU];
                        int c1U = Convert.ToInt32(gU.Component1.strID);
                        int c2U = Convert.ToInt32(gU.Component2.strID);
                        int slot1U = slots[c1U];
                        int slot2U = slots[c2U];

                        int oneID1 = oneUse.IndexOf(c1U);
                        int oneID2 = oneUse.IndexOf(c2U);
                        if (oneID1 != -1 && oneID2 != -1)
                        { // Combine, by shifting position in combined list.
                            combined.Insert(i + 1, combined[iU]);
                            combined.RemoveAt(iU + 1);
                            oneUse.RemoveAt(oneID1);
                            oneUse.Remove(c2U);
                            iU -= 2;
                        }
                        else if (GetEmpty(inventory) < Slots_Required && oneID1 != -1 && slot2U > 0)
                        { // If only one of the two is a oneUse, combine it anyway, if doing so will not put it over the current Slots_Req
                            combined.Insert(i + 1, combined[iU]);
                            combined.RemoveAt(iU + 1);
                            oneUse.RemoveAt(oneID1); iU--;
                        }
                        else if (GetEmpty(inventory) < Slots_Required && oneID2 != -1 && slot1U > 0)
                        {
                            combined.Insert(i + 1, combined[iU]);
                            combined.RemoveAt(iU + 1);
                            oneUse.RemoveAt(oneID2); iU--;
                        }
                    }
                }
            }

            // REDUCE SLOT REQUIREMENT
            if (limitSlots && Slots_Required > 36)
            {
                inst = CondenseSlots(resultGem, inst, false, 36);
                inst.Insert(0, new Point(0, -36));
            }
        }
        // CondenseSlots seems to be messed up, I can't get the 262144-combine to work.
        private List<Point> CondenseSlots(Gem g, List<Point> bigInst, bool keepBase, int slotLimit)
        {
            // Get the combine INST for both components. (Will not include duplicating base gem.)
            // If the combine for a component exceeds the slotLimit, CondenseSlots to get new INST.
            //
            // Each component's combine INST must include placing the base gem in slot 0.
            // If I add the duplicate step to p1.inst, then the new condensed one will already have it.
            // To solve this, try: If the INST does not begin with duplicate step, add it.

            Gem c1 = g.Component1;
            Gem c2 = g.Component2;
            CombinePerformer p1 = new CombinePerformer(); p1.limitSlots = false;
            p1.SetMethod(c1.GetFullCombine()); p1.resultGem.strID = c1.strID;
            CombinePerformer p2 = new CombinePerformer(); p2.limitSlots = false;
            p2.SetMethod(c2.GetFullCombine()); p2.resultGem.strID = c2.strID;

            if (p1.Slots_Required > slotLimit - 1)
                p1.inst = CondenseSlots(c1, p1.inst, true, slotLimit);
            // Move result gem to highest open slot
            p1.inst.Add(new Point(p1.inst.Last().Y, -(slotLimit - 1))); // Move to 1st open space.
            if (p2.Slots_Required > slotLimit - 1)
                p2.inst = CondenseSlots(c2, p2.inst, false, slotLimit - 1);
            if (keepBase) // Is slot 36 used by baseGem?
                p2.inst.Add(new Point(p2.inst.Last().Y, -(slotLimit - 2))); // 2nd open (now 1st) space.
            else
                p2.inst.Add(new Point(p2.inst.Last().Y, -36));

            List<Point> newInst = new List<Point>();
            // Both combines require placing a base gem in slot 0 first.
            if (p1.inst[0].X != 35)
                newInst.Add(new Point(35, INST_DUPE));
            newInst.AddRange(p1.inst);

            if (keepBase || p2.Slots_Required > slotLimit - 1) // Duplicate base_gem
                newInst.Add(new Point(35, INST_DUPE));
            else // Move base_gem
                newInst.Add(new Point(35, -1));
            newInst.AddRange(p2.inst);

            // Combine the two resulting gems
            if (keepBase)
                newInst.Add(new Point((slotLimit - 3), (slotLimit - 2))); // Combine to the higher slot (shouldn't matter, last gem is moved later anyway)
            else
                newInst.Add(new Point((slotLimit - 2), 35));

            // Finally
            return newInst;
        }
Exemple #7
0
		private static string GetListName(Gem gem) => GetColorName(gem.Color) + " " + gem.SpecWord;
Exemple #8
0
		private void BuildGem(Gem gem, InstructionCollection instructions, bool doPostScan)
		{
			if (gem == null || !gem.IsNeeded || instructions.SlotsRequired > SlotLimit)
			{
				return;
			}

			var gem1 = gem.Component1;
			var gem2 = gem.Component2;
			this.BuildGem(gem1, instructions, true);
			this.BuildGem(gem2, instructions, true);

			// Re-check if gem is needed in case gem was already built during optimization routine for component gems.
			if (gem.IsNeeded && instructions.SlotsRequired <= SlotLimit)
			{
				gem1.UseCount--;
				gem2.UseCount--;
				doPostScan &= gem.IsUpgrade ? instructions.Upgrade(gem) : instructions.Combine(gem);

				while (doPostScan && instructions.SlotsRequired <= SlotLimit)
				{
					doPostScan = this.OptimizeLastGems(instructions) || this.OptimizeSingleUseGems(instructions);
				}
			}
		}
Exemple #9
0
		private Combiner(Gem parentGem, IReadOnlyList<Gem> gemList, bool lastRun)
		{
			ThrowNull(parentGem, nameof(parentGem));
			ThrowNull(gemList, nameof(gemList));
			this.Gem = parentGem;

			// Only update UseCount for gems actually used in this combiner.
			// First, determine which gems are actually part of this combine. Hijacking UseCount as a marker, since we're going to be resetting it right after this anyway (and those in the base list don't matter anymore).
			foreach (var gem in gemList)
			{
				gem.UseCount = 0;
			}

			this.Gem.UseCount = -1;
			bool changesMade;
			do
			{
				changesMade = false;
				for (int i = gemList.Count - 1; i >= 0; i--)
				{
					var gem = gemList[i];
					if (gem.UseCount == -1 && !(gem is BaseGem))
					{
						foreach (var component in gem)
						{
							if (component.UseCount != -1)
							{
								changesMade = true;
								component.UseCount = -1;
							}
						}
					}
				}
			}
			while (changesMade);

			this.gems = new List<Gem>();
			foreach (var gem in gemList)
			{
				if (gem.UseCount == -1)
				{
					this.gems.Add(gem);
				}
			}

			this.ResetUseCount(!lastRun);
		}
Exemple #10
0
 private string GetGemInfo(Gem g)
 {
     return "Grade +" + g.Grade + "\n" +
         ("Cost: " + g.Cost + "x\n") +
         //("Power: " + Math.Round(g.Power, 6) + "\n") +
         ("Growth: " + Math.Round(g.Growth, 6) + " "); // [ie] need accuracy to 6 for tests
         //("Damage: " + Math.Round(g.damage, 6) + "\n") +
         //("Leech: " + Math.Round(g.leech, 6) + "\n") +
         //("Crit: " + Math.Round(g.critMult, 6) + "\n") +
         //("Bbound: " + Math.Round(g.blood, 6) + "");
 }
 public InstructionCollection(InstructionCollection instructions1, InstructionCollection instructions2, Gem combine)
 {
     ThrowNull(instructions1, nameof(instructions1));
     ThrowNull(instructions2, nameof(instructions2));
     this.instructions.AddRange(instructions1);
     this.instructions.AddRange(instructions2);
     this.Combine(combine);
     this.SlotsRequired = instructions2.SlotsRequired > instructions1.SlotsRequired ? instructions2.SlotsRequired : instructions1.SlotsRequired;
 }
Exemple #12
0
        public static Gem Combine(Gem g1, Gem g2)
        {
            Gem ret = new Gem();

            if (g2.Cost > g1.Cost)
            {
                ret.Component1 = g2;
                ret.Component2 = g1;
            }
            else
            {
                ret.Component1 = g1;
                ret.Component2 = g2;
            }

            if (g1.Grade == g2.Grade)
            {
                ret.Grade = g1.Grade + 1;
                ret.damage = g1.damage > g2.damage ? 0.87 * g1.damage + 0.71 * g2.damage : 0.87 * g2.damage + 0.71 * g1.damage;
                ret.leech = g1.leech > g2.leech ? 0.88 * g1.leech + 0.50 * g2.leech : 0.88 * g2.leech + 0.50 * g1.leech;
                ret.blood = g1.blood > g2.blood ? 0.78 * g1.blood + 0.31 * g2.blood : 0.78 * g2.blood + 0.31 * g1.blood;
                ret.critMult = g1.critMult > g2.critMult ? 0.88 * g1.critMult + 0.50 * g2.critMult : 0.88 * g2.critMult + 0.50 * g1.critMult;
            }
            else if (g1.Grade == g2.Grade + 1)
            {
                ret.Grade = g1.Grade;
                ret.damage = g1.damage > g2.damage ? 0.86 * g1.damage + 0.70 * g2.damage : 0.86 * g2.damage + 0.70 * g1.damage;
                ret.leech = g1.leech > g2.leech ? 0.89 * g1.leech + 0.44 * g2.leech : 0.89 * g2.leech + 0.44 * g1.leech;
                ret.blood = g1.blood > g2.blood ? 0.79 * g1.blood + 0.29 * g2.blood : 0.79 * g2.blood + 0.29 * g1.blood;
                ret.critMult = g1.critMult > g2.critMult ? 0.88 * g1.critMult + 0.44 * g2.critMult : 0.88 * g2.critMult + 0.44 * g1.critMult;
            }
            else if (g1.Grade == g2.Grade - 1)
            {
                ret.Grade = g2.Grade;
                ret.damage = g1.damage > g2.damage ? 0.86 * g1.damage + 0.70 * g2.damage : 0.86 * g2.damage + 0.70 * g1.damage;
                ret.leech = g1.leech > g2.leech ? 0.89 * g1.leech + 0.44 * g2.leech : 0.89 * g2.leech + 0.44 * g1.leech;
                ret.blood = g1.blood > g2.blood ? 0.79 * g1.blood + 0.29 * g2.blood : 0.79 * g2.blood + 0.29 * g1.blood;
                ret.critMult = g1.critMult > g2.critMult ? 0.88 * g1.critMult + 0.44 * g2.critMult : 0.88 * g2.critMult + 0.44 * g1.critMult;
            }
            else
            {
                ret.Grade = g1.Grade;
                if (g2.Grade > g1.Grade)
                    ret.Grade = g2.Grade;

                ret.damage = g1.damage > g2.damage ? 0.85 * g1.damage + 0.69 * g2.damage : 0.85 * g2.damage + 0.69 * g1.damage;
                ret.leech = g1.leech > g2.leech ? 0.90 * g1.leech + 0.38 * g2.leech : 0.90 * g2.leech + 0.38 * g1.leech;
                ret.blood = g1.blood > g2.blood ? 0.80 * g1.blood + 0.27 * g2.blood : 0.80 * g2.blood + 0.27 * g1.blood;
                ret.critMult = g1.critMult > g2.critMult ? 0.88 * g1.critMult + 0.44 * g2.critMult : 0.88 * g2.critMult + 0.44 * g1.critMult;
            }

            ret.damage = Math.Max(ret.damage, g1.damage);
            ret.damage = Math.Max(ret.damage, g2.damage);
            ret.Cost = ret.Component1.Cost + ret.Component2.Cost;
            ret.Growth = Math.Log10(ret.Power) / Math.Log10(ret.Cost);

            return ret;
        }