public static BitmapSheet FromImage(string path, int scale, int pieceScale, int pieceSize, bool saveSheet, bool savePieces = false, bool animated = false)
        {
            var bs = new BitmapSheet {
                Bitmaps = new Dictionary <ushort, Bitmap>()
            };

            var bitmap      = AImage.FromFile(path);
            var totalBitmap = new Bitmap(bitmap.Width * scale, bitmap.Height * scale);

            var index = 0;

            for (var y = 0; y < bitmap.Height; y += pieceSize)
            {
                for (var x = 0; x < bitmap.Width; x += pieceSize)
                {
                    var crop  = new Crop(new Rectangle(x, y, pieceSize, pieceSize));
                    var piece = crop.Apply(bitmap);

                    var resizeW = System.Math.Min(32, pieceSize * 4);
                    var resizeH = System.Math.Min(32, pieceSize * 4);
                    var outW    = System.Math.Min(40, pieceSize * 5);
                    var outH    = System.Math.Min(40, pieceSize * 5);

                    var resize = new ResizeNearestNeighbor(resizeW, resizeH);
                    piece = resize.Apply(piece);

                    var outBitmap = new Bitmap(outW, outH);
                    outBitmap.Add(piece);

                    outBitmap = outBitmap.OutlineGlow(0, 0, .8, 1.4, 10);
                    if (savePieces)
                    {
                        outBitmap.Save($"{path} - 0x{index:x2}.png", ImageFormat.Png);
                    }

                    totalBitmap.Add(outBitmap, x * 5, y * 5);
                    bs.Bitmaps.Add((ushort)index, outBitmap);
                    index++;
                }
            }
            if (saveSheet)
            {
                totalBitmap.SavePng($"{path} - {(int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds}.png");
            }

            return(bs);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Encapsulates the entire parking lot state
 /// change, triggerd by Camera changes
 /// </summary>
 public void Update()
 {
     if (Baseline != null && Baseline.SameSize(Camera.CurrentImage))
     {
         lock (this)
         {
             // Reset percentDifferences to zero
             Annotations.ForEach(a => a.PercentDifference = 0);
             // Maps annotations to their area in pixels
             Dictionary <Annotation, int> annotationPixelAreas = Annotations.ToDictionary(a => a, a => 0);
             // Get the raw pixel difference (color sensitive)
             Bitmap baseline   = Baseline;
             Bitmap current    = Camera.CurrentImage;
             Bitmap difference = baseline.Difference(
                 current.Add(
                     // Adjust the current image by the average light difference
                     // between the baseline and current image
                     AverageDifference(
                         baseline,
                         current,
                         Annotations.Where(a =>
                                           a.Type == Annotation.AnnotationType.Constant
                                           )
                         )
                     )
                 );
             // Sum up difference percentage contained by each annotation
             for (int x = 0; x < difference.Width; x++)
             {
                 for (int y = 0; y < difference.Height; y++)
                 {
                     Vector2 pixelPoint = new Vector2((double)x / difference.Width, (double)y / difference.Height);
                     foreach (Annotation annotation in Annotations.Where(a => a.Contains(pixelPoint)))
                     {
                         annotationPixelAreas[annotation]++;
                         annotation.PercentDifference += difference.GetPixel(x, y).Value();
                     }
                 }
             }
             // Normalize the difference percentages by dividing out the total pixel area
             foreach (var pixelArea in annotationPixelAreas.Where(p => p.Value > 0))
             {
                 pixelArea.Key.PercentDifference /= pixelArea.Value;
             }
         }
     }
 }
Exemplo n.º 3
0
        private static void Main(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.White;

            /*  new epicHiveObjectsCXML(), new lostHallsObjectsCXML(), new oryxScribeObjectsCXML(),
             * new cnidarianReefObjectsCXML(), new gemLordObjectCXML(), new testAtrapperObjectCXML(), new stSorcAndHuntObjectsCXML(),
             * new bearCaveObjectCXML(), new goblinLairObjectCXML(), new KrathTestObjectsCXML(), new KrathMuTestObjectsCXML()];*/
            var objectXmlPaths = new[]
            {
                "projectiles.xml", "equip.xml", "skins.xml", "dungeons/testAtrapper/testAtrapperSkins.xml",
                "dungeons/stSorcAndHunt/stSorcAndHuntSkins.xml", "dyes.xml", "textiles.xml", "permapets.xml",
                "token.xml", "testing/willemTesting.xml", "testing/ttesting.xml", "testing/btesting.xml",
                "testing/stesting.xml", "testing/mtesting.xml", "testing/ktesting.xml", "players.xml", "containers.xml",
                "objects.xml", "portals.xml", "testingObjects.xml", "staticobjects.xml", "tutorial/tutorialObjects.xml",
                "tutorial/tutorialMonsters.xml", "allies.xml", "heroes.xml", "playersZombies.xml", "pets.xml",
                "npc.xml", "realm/shore.xml", "realm/low.xml", "realm/mid.xml", "realm/high.xml", "realm/mountains.xml",
                "encounters.xml", "arena.xml", "dungeons/oryxCastle.xml", "dungeons/tombOfTheAncients.xml",
                "dungeons/spriteWorld.xml", "dungeons/undeadLair.xml", "dungeons/oceanTrench.xml",
                "dungeons/forbiddenJungle.xml", "dungeons/oryxChamber.xml", "dungeons/oryxChickenChamber.xml",
                "dungeons/oryxWineCellar.xml", "dungeons/manorOfTheImmortals.xml", "dungeons/pirateCave.xml",
                "dungeons/snakePit.xml", "dungeons/spiderDen.xml", "dungeons/abyssOfDemons.xml",
                "dungeons/ghostShip.xml", "dungeons/madLab.xml", "dungeons/caveOfAThousandTreasures.xml",
                "dungeons/candyLand.xml", "dungeons/hauntedCemetery.xml", "dungeons/forestMaze.xml",
                "dungeons/epicForestMaze.xml", "dungeons/epicPirateCave.xml", "dungeons/epicSpiderDen.xml",
                "dungeons/nexusDestroyed.xml", "dungeons/miniDungeonHub.xml", "dungeons/lairOfDraconis.xml",
                "dungeons/lairOfShaitan.xml", "dungeons/shatters.xml", "dungeons/belladonna.xml",
                "dungeons/puppetMaster.xml", "dungeons/iceCave.xml", "dungeons/theHive.xml", "dungeons/toxicSewers.xml",
                "dungeons/puppetMasterEncore.xml", "dungeons/iceTomb.xml",
                "dungeons/parasiteDen/parasiteDenObjects.xml", "dungeons/stPatricks/stPatricksObjects.xml",
                "dungeons/buffedBunny/buffedBunnyObjects.xml", "dungeons/hanamiNexus/hanamiNexusObjects.xml",
                "dungeons/mountainTemple/mountainTempleObjects.xml", "dungeons/oryxHorde/oryxHordeObjects.xml",
                "dungeons/summerNexus/summerNexusObjects.xml", "dungeons/autumnNexus/autumnNexusObjects.xml",
                "dungeons/epicHive/epicHiveObjects.xml", "dungeons/lostHalls/lostHallsObjects.xml",
                "dungeons/oryxScribe/oryxScribeObjects.xml", "dungeons/cnidarianReef/cnidarianReefObjects.xml",
                "dungeons/magicWoods/magicWoodsObjects.xml", "dungeons/santaWorkshop/santaWorkshopObjects.xml",
                "dungeons/gemLord/gemLordObjects.xml", "dungeons/testAtrapper/testAtrapperObjects.xml",
                "dungeons/stSorcAndHunt/stSorcAndHuntObjects.xml", "dungeons/bearCave/bearCaveObjects.xml",
                "dungeons/goblinLair/goblinLairObjects.xml", "dungeons/krathTest/krathTestObjects.xml",
                "dungeons/krathTest/krathMuTestObjects.xml"
            };

            foreach (var file in objectXmlPaths.Select(o => new FileInfo($"xml/{o}")))
            {
                if (!file.Exists)
                {
                    Log($"ERROR: {file.FullName} doesn't exist");
                    continue;
                }
                load(file);
            }

            Log($"{items.Count} items");

            var rendersBitmap = new Bitmap(40 * 25, Math.Max(items.Count / 25, 1) * 40);

            Log(
                $"Output bitmap: {rendersBitmap.Width} * {rendersBitmap.Height} ({rendersBitmap.Width * rendersBitmap.Height}px)");

            var dict = new Dictionary <int, List <object> >
            {
                { -1, new List <object> {
                      "empty slot", 0, -1, 0, 0, 0, 0
                  } }
            };

            var bitmapSheetByName = new Dictionary <string, BitmapSheet>();
            var addedSprites      = new Dictionary <string, Dictionary <ushort, int> >();
            var index             = 1;

            foreach (var item in items)
            {
                var increment = true;

                var sheet = new FileInfo($"sheets/{item.Sheet}.png");
                if (!sheet.Exists)
                {
                    Log($"ERROR: sheet {sheet.Name} doesn't exist");
                    break;
                }

                var sheetBitmap = AImage.FromFile(sheet.FullName);
                if (!bitmapSheetByName.ContainsKey(item.Sheet))
                {
                    Log(
                        $"{item.Sheet} bitmap: {sheetBitmap.Width} * {sheetBitmap.Height} ({sheetBitmap.Width * sheetBitmap.Height}px)");

                    int  size;
                    bool animated;
                    switch (sheetBitmap.Width)
                    {
                    case 8 * 16:
                        size     = 8;
                        animated = false;
                        break;

                    case 8 * 7:
                        size     = 8;
                        animated = true;
                        break;

                    case 16 * 16:
                        size     = 16;
                        animated = false;
                        break;

                    case 16 * 7:
                        size     = 16;
                        animated = true;
                        break;

                    default:
                        Log($"ERROR: unknown width: {sheetBitmap.Width}");
                        continue;
                    }
                    bitmapSheetByName.Add(item.Sheet,
                                          BitmapSheet.FromImage(sheet.FullName, 5, 4, size, false, false, false));
                    Log(
                        $"{item.Sheet} - size {size} animated {animated} indexes {bitmapSheetByName[item.Sheet].Bitmaps.Keys.Max()}");
                }

                // Log($"{item.Id}: {item.Sheet}.{item.Index}");

                if (!addedSprites.ContainsKey(item.Sheet))
                {
                    addedSprites.Add(item.Sheet, new Dictionary <ushort, int>());
                }
                int x, y;
                if (!addedSprites[item.Sheet].ContainsKey(item.Index))
                {
                    addedSprites[item.Sheet].Add(item.Index, index);
                    indexToCoords(index, rendersBitmap.Width, out x, out y);
                    rendersBitmap.Add(
                        bitmapSheetByName[item.Sheet].Bitmaps[
                            item.Animated
                                ? (ushort)(item.Index * (item.Sheet.Contains("player") ? 21 : 7))
                                : item.Index], x, y);
                }
                else
                {
                    indexToCoords(addedSprites[item.Sheet][item.Index], rendersBitmap.Width, out x, out y);
                    increment = false;
                }

                dict.Add(item.Type, new List <object>
                {
                    item.Id,
                    item.SlotType,
                    item.Tier,
                    x,
                    y,
                    item.FameBonus,
                    item.FeedPower
                });
                if (increment)
                {
                    index++;
                }
            }
            rendersBitmap.SavePng("renders.png");
            rendersBitmap.Dispose();

            var classesDict = classes.ToDictionary <ClassData, int, List <object> >(classData => classData.Type,
                                                                                    classData => new List <object>
            {
                classData.Id ?? "",
                classData.Starts ?? new ushort[0],
                classData.Averages ?? new ushort[0],
                classData.Maxes ?? new ushort[0],
                classData.Slots ?? new ushort[0]
            });

            File.WriteAllText("constants.js",
                              $@"items = {
                        JsonConvert.SerializeObject(dict, new JsonSerializerSettings {Formatting = Formatting.Indented})
                    }

classes = {JsonConvert.SerializeObject(classesDict, new JsonSerializerSettings {Formatting = Formatting.Indented})}

skins = {{
{string.Join("\n", skins.Select(skin => $"  0x{skin.Type:x}: {skin.Index}, // {skin.Id}"))}
}}");

            var skinBitmap = new Bitmap(56, (skins.Count + 14) * 24);
            var maskBitmap = new Bitmap(56, (skins.Count + 14) * 24);

            addedSprites.Clear();
            index = 0;

            foreach (var classData in classes)
            {
                var sheet = new FileInfo($"sheets/{classData.Sheet}.png");
                if (!sheet.Exists)
                {
                    Log($"ERROR: sheet {sheet.Name} doesn't exist");
                    break;
                }
                var mask      = new FileInfo($"sheets/{classData.Sheet}Mask.png");
                var maskSheet = AImage.FromFile(mask.FullName);

                var sheetBitmap = AImage.FromFile(sheet.FullName);
                var crop        = new Crop(new Rectangle(0, classData.SheetIndex * 24, 56, 24));
                var piece       = crop.Apply(sheetBitmap);

                skinBitmap.Add(piece, 0, index * 24);

                crop  = new Crop(new Rectangle(0, classData.SheetIndex * 24, 56, 24));
                piece = crop.Apply(maskSheet);
                maskBitmap.Add(piece, 0, index * 24);

                index++;
            }
            index = 0;
            foreach (var skinData in skins.OrderBy(skin => skin.Index))
            {
                var sheet = new FileInfo($"sheets/{skinData.Sheet}.png");
                if (!sheet.Exists)
                {
                    Log($"ERROR: sheet {sheet.Name} doesn't exist");
                    break;
                }
                var mask      = new FileInfo($"sheets/{skinData.Sheet}Mask.png");
                var maskSheet = AImage.FromFile(mask.FullName);

                var sheetBitmap = AImage.FromFile(sheet.FullName);
                var crop        = new Crop(new Rectangle(0, skinData.SheetIndex * 24, 56, 24));
                var piece       = crop.Apply(sheetBitmap);

                skinBitmap.Add(piece, 0, (index + 14) * 24);

                crop  = new Crop(new Rectangle(0, skinData.SheetIndex * 24, 56, 24));
                piece = crop.Apply(maskSheet);
                maskBitmap.Add(piece, 0, (index + 14) * 24);

                index++;
            }
            using (var ms = new MemoryStream())
            {
                skinBitmap.Save(ms, ImageFormat.Png);
                File.WriteAllText("sheets-skin.js", $"data:image/png;base64,{Convert.ToBase64String(ms.ToArray())}");
            }
            using (var ms = new MemoryStream())
            {
                maskBitmap.Save(ms, ImageFormat.Png);
                File.WriteAllText("sheets-skinmask.js",
                                  $"data:image/png;base64,{Convert.ToBase64String(ms.ToArray())}");
            }
            skinBitmap.SavePng("skins.png");
            maskBitmap.SavePng("skinsmask.png");
        }