Beispiel #1
0
        public static void Load()
        {
            BuildSets.Clear();
            Houses.Clear();
            Guardlines.Clear();

            FileInfo[] files  = _definitionsPath.GetFiles("*.txt").Where(s => !_ignored.Contains(s.Name)).ToArray();
            Bitmap[]   images = new Bitmap[files.Length];

            FileInfo[] icons = _iconsPath.GetFiles("*.png");

            for (int i = 0; i < files.Length; i++)
            {
                FileInfo definition = files[i];
                FileInfo icon       = icons.FirstOrDefault(s => s.Name.Contains(Path.GetFileNameWithoutExtension(definition.Name)));

                if (icon == null)
                {
                    continue;               // found an icon
                }
                Image img = Image.FromFile(icon.FullName);
                images[i] = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppPArgb);

                using (Graphics g = Graphics.FromImage(images[i]))
                {
                    g.PageUnit          = GraphicsUnit.Pixel;
                    g.InterpolationMode = InterpolationMode.NearestNeighbor;
                    g.PixelOffsetMode   = PixelOffsetMode.HighQuality;
                    g.SmoothingMode     = SmoothingMode.AntiAlias;
                    g.DrawImage(img, 0, 0, img.Width, img.Height);
                }

                string   setName  = Path.GetFileNameWithoutExtension(definition.Name);
                BuildSet buildSet = new BuildSet(setName, images[i], !_smarts.Contains(setName));
                bool     istown   = setName.ToLower() == "town";

                using (StreamReader reader = new StreamReader(definition.OpenRead()))
                {
                    while (!reader.EndOfStream)
                    {
                        string line = reader.ReadLine();

                        if (string.IsNullOrEmpty(line))
                        {
                            continue;
                        }

                        string[] parts = line.Split('\t');

                        if (parts.Length >= 5)
                        {
                            bool     enabled     = parts[0] == "+";
                            string   description = parts[1].TrimEnd().TrimStart();
                            Position position    = Position.Parse(parts[2] + "." + parts[3]);
                            int      map         = parts[4].ToInt();

                            BuildingEntry entry = new BuildingEntry(buildSet, description, position, map)
                            {
                                IsEnabled = enabled, IsTown = istown
                            };


                            if (parts.Length >= 6)
                            {
                                entry.ShowName = parts[5] == "true";
                            }

                            buildSet.Entries.Add(entry);
                        }
                    }
                }

                BuildSets.Add(buildSet);
            }

            // patch for towns
            BuildSet townSet = BuildSets.FirstOrDefault(s => s.Name.ToLower() == "town");

            if (townSet != null)
            {
                BuildSets.Remove(townSet);
                BuildSets.Add(townSet);
            }
            // end patch

            // load houses
            FileInfo housesDef = _definitionsPath.GetFiles().FirstOrDefault(s => s.Name == _ignored[1]);

            if (housesDef != null)
            {
                using (StreamReader reader = new StreamReader(housesDef.FullName))
                {
                    while (!reader.EndOfStream)
                    {
                        string line = reader.ReadLine();
                        if (string.IsNullOrEmpty(line))
                        {
                            continue;
                        }

                        string[] data = line.Split('\t');
                        if (data.Length <= 0 || data.Length < 5)
                        {
                            continue;
                        }


                        if (!ushort.TryParse(data[0], out ushort graphic))
                        {
                            graphic = ushort.Parse(data[0], NumberStyles.HexNumber);
                        }

                        Position loc   = Position.Parse(data[1] + "." + data[2]);
                        Size     size  = new Size(data[3].ToInt(), data[4].ToInt());
                        int      map   = data[5].ToInt();
                        string   descr = data[6];

                        HouseEntry house = new HouseEntry(descr, graphic, loc, size, map);

                        Houses.Add(house);
                    }
                }
            }
            else
            {
                new FileInfo(Path.Combine(_definitionsPath.FullName, _ignored[1])).Create().Close();
            }

            // load guardlines
            FileInfo guardlinesDef = _definitionsPath.GetFiles().FirstOrDefault(s => s.Name == _ignored[0]);

            if (guardlinesDef != null)
            {
                using (StreamReader reader = new StreamReader(guardlinesDef.FullName))
                {
                    while (!reader.EndOfStream)
                    {
                        string line = reader.ReadLine();
                        if (string.IsNullOrEmpty(line))
                        {
                            continue;
                        }

                        string[] data = line.Split('\t');
                        if (data.Length <= 0 || data.Length < 5)
                        {
                            continue;
                        }

                        if (data[0].StartsWith("#"))
                        {
                            continue;
                        }

                        Position loc = Position.Parse(data[0] + "." + data[1]);
                        // ignore data[2]
                        Size size = new Size(data[3].ToInt(), data[4].ToInt());
                        int  map  = data[5].ToInt();

                        GuardlineEntry guardline = new GuardlineEntry(loc, size, map);

                        Guardlines.Add(guardline);
                    }
                }
            }
            else
            {
                new FileInfo(Path.Combine(_definitionsPath.FullName, _ignored[0])).Create().Close();
            }


            ParseUOAM();
        }
Beispiel #2
0
        public static bool ParseUOAM()
        {
            DirectoryInfo dir = new DirectoryInfo("Definitions");

            FileInfo[] files = dir.GetFiles("*.map");

            Regex regex = new Regex("^([\\+-])(.*):\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(.*)$");

            foreach (FileInfo file in files)
            {
                using (StreamReader reader = new StreamReader(File.OpenRead(file.FullName)))
                {
                    while (!reader.EndOfStream)
                    {
                        string line = reader.ReadLine();
                        if (string.IsNullOrEmpty(line))
                        {
                            continue;
                        }

                        Match match = regex.Match(line);

                        if (match.Success)
                        {
                            string type  = match.Groups[2].ToString();
                            int    x     = match.Groups[3].ToString().ToInt();
                            int    y     = match.Groups[4].ToString().ToInt();
                            int    map   = match.Groups[5].ToString().ToInt();
                            string descr = match.Groups[6].ToString();

                            switch (type)
                            {
                            case "Minax's Fortress":
                            case "point of interest":
                                type = "POINT";
                                break;

                            case "marble patio":
                                type = "MARPATIO";
                                break;

                            case "theater":
                                type = "THEATRE";
                                break;

                            case "teleporter":
                                type = "TELEPORT";
                                break;
                            }

                            bool ok = true;
                            foreach (BuildSet s in BuildSets)
                            {
                                if (s.Entries.FirstOrDefault(j => j.Location.X == x && j.Location.Y == y) != null)
                                {
                                    ok = false;
                                    break;
                                }
                            }

                            if (!ok)
                            {
                                continue;
                            }

                            BuildSet set = BuildSets.FirstOrDefault(s => s.Name.ToLower().Contains(type.Replace(" ", "").ToLower()));
                            if (set != null)
                            {
                                set.Entries.Add(new BuildingEntry(set, descr, new Position((short)x, (short)y), map)
                                {
                                    IsUOAM = true
                                });
                            }
                        }
                    }
                }
            }

            return(true);
        }
		public void GenRunes(Save save) {
			if (save?.Runes == null)
				return;

			if (!getRunningHandle())
				return;
			try {

				if (Type == BuildType.Lock) {
					foreach (var r in Mon.Current.Runes) {
						if (r != null) {
							if (r.Locked)
								runes[r.Slot - 1] = new Rune[0];
							else
								runes[r.Slot - 1] = new Rune[] { r };
						}
					}
					return;
				}

				if (Type == BuildType.Link && LinkBuild == null) {
					for (int i = 0; i < 6; i++)
						runes[i] = new Rune[0];
					return;
				}

				// todo: less .ToArray-ing
				ParallelQuery<Rune> rsGlobal = save.Runes.AsParallel();

				// if not saving stats, cull unusable here
				if (!BuildSaveStats) {
					// Only using 'inventory' or runes on mon
					// also, include runes which have been unequipped (should only look above)
					if (!RunesUseEquipped || RunesOnlyFillEmpty)
						rsGlobal = rsGlobal.Where(r => r.IsUnassigned || r.AssignedId == Mon.Id || r.Swapped);
					// only if the rune isn't currently locked for another purpose
					if (!RunesUseLocked)
						rsGlobal = rsGlobal.Where(r => !r.Locked);
					rsGlobal = rsGlobal.Where(r => !BannedRuneId.Any(b => b == r.Id) && !BannedRunesTemp.Any(b => b == r.Id));
				}

				if ((BuildSets.Any() || RequiredSets.Any()) && BuildSets.All(s => Rune.SetRequired(s) == 4) && RequiredSets.All(s => Rune.SetRequired(s) == 4)) {
					// if only include/req 4 sets, include all 2 sets autoRuneSelect && ()
					rsGlobal = rsGlobal.Where(r => BuildSets.Contains(r.Set) || RequiredSets.Contains(r.Set) || Rune.SetRequired(r.Set) == 2);
				}
				else if (BuildSets.Any() || RequiredSets.Any()) {
					rsGlobal = rsGlobal.Where(r => BuildSets.Contains(r.Set) || RequiredSets.Contains(r.Set));
					// Only runes which we've included
				}

				if (BuildSaveStats) {
					foreach (Rune r in rsGlobal) {
						r.manageStats.AddOrUpdate("currentBuildPoints", 0, (k, v) => 0);
						if (!BuildGoodRunes)
							r.manageStats.AddOrUpdate("Set", 1, (s, d) => { return d + 1; });
						else
							r.manageStats.AddOrUpdate("Set", 0.001, (s, d) => { return d + 0.001; });
					}
				}

				int?[] slotFakes = new int?[6];
				bool[] slotPred = new bool[6];
				getPrediction(slotFakes, slotPred);

				// Set up each runeslot
				for (int i = 0; i < 6; i++) {
					// put the right ones in
					runes[i] = rsGlobal.Where(r => r.Slot == i + 1).ToArray();

					// makes sure that the primary stat type is in the selection
					if (i % 2 == 1 && SlotStats[i].Count > 0) // actually evens because off by 1
					{
						runes[i] = runes[i].AsParallel().Where(r => SlotStats[i].Contains(r.Main.Type.ToForms())).ToArray();
					}

					if (BuildSaveStats) {
						foreach (Rune r in runes[i]) {
							if (!BuildGoodRunes)
								r.manageStats.AddOrUpdate("TypeFilt", 1, (s, d) => { return d + 1; });
							else
								r.manageStats.AddOrUpdate("TypeFilt", 0.001, (s, d) => { return d + 0.001; });
						}
						// cull here instead
						if (!RunesUseEquipped || RunesOnlyFillEmpty)
							runes[i] = runes[i].AsParallel().Where(r => r.IsUnassigned || r.AssignedId == Mon.Id || r.Swapped).ToArray();
						if (!RunesUseLocked)
							runes[i] = runes[i].AsParallel().Where(r => !r.Locked).ToArray();

					}
				}

				// clean out runes which won't make complete sets
				cleanBroken();

				// clean out runes which won't pass the minimum
				cleanMinimum();

				if (AutoRuneSelect) {
					// TODO: triple pass: start at needed for min, but each pass reduce the requirements by the average of the chosen runes for that pass, increase it by build scoring

					var needed = NeededForMin(slotFakes, slotPred);
					if (needed == null)
						AutoRuneSelect = false;

					if (AutoRuneSelect) {
						var needRune = new Stats(needed) / 6;

						// Auto-Rune select picking N per RuneSet should be fine to pick more because early-out should keep times low.
						// reduce number of runes to 10-15

						// odds first, then evens
						foreach (int i in new int[] { 0, 2, 4, 5, 3, 1 }) {
							Rune[] rr = new Rune[0];
							foreach (var rs in RequiredSets) {
								rr = rr.Concat(runes[i].AsParallel().Where(r => r.Set == rs).OrderByDescending(r => runeVsStats(r, needRune) * 10 + runeVsStats(r, Sort)).Take(AutoRuneAmount / 2).ToArray()).ToArray();
							}
							if (rr.Length < AutoRuneAmount)
								rr = rr.Concat(runes[i].AsParallel().Where(r => !rr.Contains(r)).OrderByDescending(r => runeVsStats(r, needRune) * 10 + runeVsStats(r, Sort)).Take(AutoRuneAmount - rr.Length).ToArray()).Distinct().ToArray();

							runes[i] = rr;
						}

						cleanBroken();
					}
				}
				if (!AutoRuneSelect) {
					// TODO: Remove
#if BUILD_RUNE_LOGGING
					//var tmp = RuneLog.logTo;
					//using (var fs = new System.IO.FileStream("sampleselect.log", System.IO.FileMode.Create))
					//using (var sw = new System.IO.StreamWriter(fs)) {
						RuneLog.logTo = sw;
#else
					{
#endif
						// Filter each runeslot
						for (int i = 0; i < 6; i++) {
							// default fail OR
							Predicate<Rune> slotTest = MakeRuneScoring(i + 1, slotFakes[i] ?? 0, slotPred[i]);

							runes[i] = runes[i].AsParallel().Where(r => slotTest.Invoke(r)).OrderByDescending(r => r.manageStats.GetOrAdd("testScore", 0)).ToArray();
							var filt = LoadFilters(i + 1);
							if (filt.Count != null) {

								var tSets = RequiredSets.Count + BuildSets.Except(RequiredSets).Count();
								var perc = RequiredSets.Count / (float)tSets;
								var reqLoad = Math.Max(2,(int)((filt.Count ?? AutoRuneAmount ) * perc));

								var rr = runes[i].AsParallel().Where(r => RequiredSets.Contains(r.Set)).GroupBy(r => r.Set).SelectMany(r => r).Take(reqLoad).ToArray();

								var incLoad = (filt.Count ?? AutoRuneAmount) - rr.Count();
								runes[i] = rr.Concat(runes[i].AsParallel().Where(r => !RequiredSets.Contains(r.Set)).Take(incLoad)).ToArray();

								// TODO: pick 20% per required set
								// Then fill remaining with the best from included
								// Go around checking if there are enough runes from each set to complete it (if NonBroken)
								// Check if removing N other runes of SCORE will permit finishing set
								// Remove rune add next best in slot
							}

							if (BuildSaveStats) {
								foreach (Rune r in runes[i]) {
									if (!BuildGoodRunes)
										r.manageStats.AddOrUpdate("RuneFilt", 1, (s, d) => d + 1);
									else
										r.manageStats.AddOrUpdate("RuneFilt", 0.001, (s, d) => d + 0.001);
								}
							}
						}
					}
				}
				if (RunesDropHalfSetStat) {
					for (int i = 0; i < 6; i++) {
						double rmm = 0;
						var runesForSlot = runes[i];
						var outRunes = new List<Rune>();
						var runesBySet = runesForSlot.GroupBy(r => r.Set);
						foreach (var rsg in runesBySet) {
							var runesByMain = rsg.GroupBy(r => r.Main.Type);
							foreach (var rmg in runesByMain) {
								rmm = rmg.Max(r => r.manageStats.GetOrAdd("testScore", 0)) * 0.6;
								if (rmm > 0) {
									outRunes.AddRange(rmg.Where(r => r.manageStats.GetOrAdd("testScore", 0) > rmm));
								}
							}
						}
						if (rmm > 0)
							runes[i] = outRunes.ToArray();
					}
				}
				// if we are only to fill empty slots
				if (RunesOnlyFillEmpty) {
					for (int i = 0; i < 6; i++) {
						if (Mon.Current.Runes[i] != null && (!Mon.Current.Runes[i]?.Locked ?? false)) {
							runes[i] = new Rune[0];
						}
					}
				}
				// always try to put the current rune back in
				for (int i = 0; i < 6; i++) {
					var r = Mon.Current.Runes[i];
					if (r == null)
						continue;

					bool isGoodType = true;
					if (i % 2 == 1 && SlotStats[i].Count > 0) {
						isGoodType = SlotStats[i].Contains(r.Main.Type.ToForms());
					}
					if (!runes[i].Contains(r) && !r.Locked && isGoodType) {
						var tl = runes[i].ToList();
						tl.Add(r);
						runes[i] = tl.ToArray();
					}
				}

				grinds = runes.SelectMany(rg => rg.SelectMany(r => r.FilterGrinds(save.Crafts).Concat(r.FilterEnchants(save.Crafts)))).Distinct().ToArray();
			}
			finally {
				IsRunning = false;
			}
		}