예제 #1
0
        protected override void Export(CookingContext context, ParticleSystemSet input)
        {
            var particleBitmaps = new Dictionary <Bitmap, ParticleSystem>();

            foreach (var item in input.ParticleSystems)
            {
                var tag = (ImageCookingTag)item.Value.Image.Tag;
                particleBitmaps.Add(tag.Bitmap, item.Value);
            }

            using (var bitmapSheet = BitmapSheet.Create(particleBitmaps.Keys,
                                                        BitmapSheetSize.Width, BitmapSheetSize.Height,
                                                        BitmapSheetClusterSize.Width, BitmapSheetClusterSize.Height,
                                                        BitmapSheet.Options.PowerOfTwoSize | BitmapSheet.Options.RotatableMerging))
            {
                ExportImageSet.SaveTextureAssets(context, bitmapSheet, TextureOutput, (source, textureURI, clippingRectangle, appliedTransform) =>
                {
                    ParticleSystem value = null;
                    if (particleBitmaps.TryGetValue(source, out value))
                    {
                        value.Image.TextureURI        = textureURI;
                        value.Image.ClippingRectangle = clippingRectangle;
                        value.Image.AppliedTransform  = appliedTransform;
                    }
                });
            }
        }
예제 #2
0
        public static void SaveTextureAssets(CookingContext context, BitmapSheet bitmapSheet, string textureOutput, Action <Bitmap, string, Rectangle, Image.Transform> f)
        {
            SaveTextureAssets(context, bitmapSheet.Sheets, textureOutput, true);

            foreach (BitmapSheet.Element item in bitmapSheet.Elements)
            {
                string textureURI        = Path.Combine(context.Directory, Path.ChangeExtension((string)item.Sheet.Tag, null));
                var    clippingRectangle = new Rectangle(item.Bounds.X, item.Bounds.Y,
                                                         item.Bounds.Width, item.Bounds.Height);
                var appliedTransform = item.AppliedTransform;

                f(item.Source, textureURI, clippingRectangle, appliedTransform);
            }
        }
예제 #3
0
        protected override void Export(CookingContext context, SpriteSet input)
        {
            var spriteBitmaps = new Dictionary <Bitmap, List <Tuple <Sprite, int> > >();

            foreach (var item in input.Sprites)
            {
                var tag = (SpriteCookingTag)item.Value.Tag;
                for (int i = 0; i < tag.Bitmaps.Count; i++)
                {
                    Bitmap bitmap = tag.Bitmaps[i];
                    List <Tuple <Sprite, int> > values = null;
                    if (spriteBitmaps.TryGetValue(bitmap, out values))
                    {
                        values.Add(Tuple.Create(item.Value, i));
                    }
                    else
                    {
                        values = new List <Tuple <Sprite, int> >();
                        values.Add(Tuple.Create(item.Value, i));
                        spriteBitmaps.Add(bitmap, values);
                    }
                }
            }

            using (var bitmapSheet = BitmapSheet.Create(spriteBitmaps.Keys,
                                                        BitmapSheetSize.Width, BitmapSheetSize.Height,
                                                        BitmapSheetClusterSize.Width, BitmapSheetClusterSize.Height,
                                                        BitmapSheet.Options.PowerOfTwoSize | BitmapSheet.Options.RotatableMerging))
            {
                ExportImageSet.SaveTextureAssets(context, bitmapSheet, TextureOutput, (source, textureURI, clippingRectangle, appliedTransform) =>
                {
                    List <Tuple <Sprite, int> > values = null;
                    if (spriteBitmaps.TryGetValue(source, out values))
                    {
                        foreach (var item in values)
                        {
                            item.Item1.Keyframes[item.Item2].TextureURI        = textureURI;
                            item.Item1.Keyframes[item.Item2].ClippingRectangle = clippingRectangle;
                            item.Item1.Keyframes[item.Item2].AppliedTransform  = appliedTransform;
                        }
                    }
                });
            }
        }
예제 #4
0
        public static void Export(CookingContext context, ImageSet input, Size bitmapSheetSize, Size bitmapSheetClusterSize, string textureOutput)
        {
            var imageBitmaps = new Dictionary <Bitmap, List <Image> >();

            foreach (var item in input.Images)
            {
                var tag = (ImageCookingTag)item.Value.Tag;

                List <Image> values = null;
                if (imageBitmaps.TryGetValue(tag.Bitmap, out values))
                {
                    values.Add(item.Value);
                }
                else
                {
                    values = new List <Image>();
                    values.Add(item.Value);
                    imageBitmaps.Add(tag.Bitmap, values);
                }
            }

            using (var bitmapSheet = BitmapSheet.Create(imageBitmaps.Keys,
                                                        bitmapSheetSize.Width, bitmapSheetSize.Height,
                                                        bitmapSheetClusterSize.Width, bitmapSheetClusterSize.Height,
                                                        BitmapSheet.Options.PowerOfTwoSize | BitmapSheet.Options.RotatableMerging))
            {
                SaveTextureAssets(context, bitmapSheet, textureOutput, (source, textureURI, clippingRectangle, appliedTransform) =>
                {
                    List <Image> values = null;
                    if (imageBitmaps.TryGetValue(source, out values))
                    {
                        foreach (Image image in values)
                        {
                            image.TextureURI        = textureURI;
                            image.ClippingRectangle = clippingRectangle;
                            image.AppliedTransform  = appliedTransform;
                        }
                    }
                });
            }
        }
예제 #5
0
        private void MergeAllImages(CookingContext context, ICollection <UIImage> images)
        {
            var imageBitmaps = new Dictionary <Bitmap, List <UIImage> >(images.Count);

            foreach (var item in images)
            {
                var tag = item.Source.Tag as ImageCookingTag;
                if (tag != null && tag.Bitmap != null)
                {
                    List <UIImage> values = null;
                    if (imageBitmaps.TryGetValue(tag.Bitmap, out values))
                    {
                        values.Add(item);
                    }
                    else
                    {
                        values = new List <UIImage>()
                        {
                            item
                        };
                        imageBitmaps.Add(tag.Bitmap, values);
                    }
                }
            }

            using (var bitmapSheet = BitmapSheet.Create(imageBitmaps.Keys,
                                                        BitmapSheetSize.Width, BitmapSheetSize.Height,
                                                        BitmapSheetClusterSize.Width, BitmapSheetClusterSize.Height,
                                                        BitmapSheet.Options.PowerOfTwoSize /* | BitmapSheet.Options.RotatableMerging*/))
            {
                #region Texture File과 Asset을 저장합니다.
                string absoluteDirectory = Path.Combine(context.BaseDirectory, context.Directory);
                if (Directory.Exists(absoluteDirectory) == false)
                {
                    Directory.CreateDirectory(absoluteDirectory);
                }

                int    textureNumber       = 0;
                string textureOutputFormat = context.ExpandVariables(TextureOutput);
                foreach (Bitmap item in bitmapSheet.Sheets)
                {
                    Trace.Assert(item.Tag == null); // 밑에서 Tag를 직접 사용할 것이기 때문에 확인합니다.

                    string path = string.Format(textureOutputFormat, textureNumber++);

                    string textureFilePath   = Path.ChangeExtension(path, "png");
                    string fullPath          = Path.Combine(absoluteDirectory, textureFilePath);
                    string fullPathDirectory = Path.GetDirectoryName(fullPath);
                    if (Directory.Exists(fullPathDirectory) == false)
                    {
                        Directory.CreateDirectory(fullPathDirectory);
                    }

                    item.Save(fullPath, ImageFormat.Png);
                    item.Tag = textureFilePath;

                    using (var fs = new FileStream(Path.ChangeExtension(fullPath, "asset"), FileMode.Create, FileAccess.Write))
                    {
                        // png 파일은 자동 추론 되기 때문에 그냥 빈 파일만 생성합니다.
                    }
                }
                #endregion

                #region Image Asset을 저장합니다
                // EMBEDDED UIIMAGE

                /*
                 * var readImage = new ReadGameAsset();
                 * var imageRecipe = new GameAssetRecipe()
                 * {
                 *  Cook = readImage,
                 *  Author = GetType().FullName,
                 *  Comment = "Automatically generated.",
                 * };
                 *
                 * int imageNumber = 0;
                 * string imageOutputFormat = context.ExpandVariables(ImageOutput);
                 */

                foreach (BitmapSheet.Element item in bitmapSheet.Elements)
                {
                    string textureURI = Path.Combine(context.Directory, Path.ChangeExtension((string)item.Sheet.Tag, null));

                    /*
                     * string path = string.Format(imageOutputFormat, imageNumber++);
                     *
                     * readImage.Input = new Image()
                     * {
                     *  TextureURI = Path.Combine(context.Directory, Path.ChangeExtension((string)item.Sheet.Tag, null)),
                     *  ClippingRectangle = new Rectangle(item.Bounds.X, item.Bounds.Y,
                     *                                    item.Bounds.Width, item.Bounds.Height),
                     *  AppliedTransform = item.AppliedTransform,
                     * };
                     *
                     * JsonSerializer.Instance.Serialize(Path.Combine(context.BaseDirectory, context.Directory, Path.ChangeExtension(path, "asset")), imageRecipe);
                     */

                    List <UIImage> values = null;
                    if (imageBitmaps.TryGetValue(item.Source, out values))
                    {
                        foreach (var image in values)
                        {
                            image.Source.TextureURI        = textureURI;
                            image.Source.ClippingRectangle = new Rectangle(item.Bounds.X, item.Bounds.Y,
                                                                           item.Bounds.Width, item.Bounds.Height);
                            image.Source.AppliedTransform = item.AppliedTransform;
                        }

                        /*
                         * context.Store(Path.Combine(context.Directory, Path.ChangeExtension(path, null)), values[0].Source);
                         *
                         * for (int i = 1; i < values.Count; i++)
                         *  values[i] = values[0];
                         */
                    }
                }
                #endregion
            }
        }
예제 #6
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");
        }