Magically import images and more into Gamecraft as blocks
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
3.3KB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Security.Cryptography;
  5. using System.Text;
  6. using Unity.Mathematics;
  7. using UnityEngine;
  8. using GamecraftModdingAPI;
  9. using GamecraftModdingAPI.Blocks;
  10. using GamecraftModdingAPI.Players;
  11. using GamecraftModdingAPI.Utility;
  12. using Pixi.Common;
  13. namespace Pixi.Images
  14. {
  15. public class ImageTextBlockImporter : Importer
  16. {
  17. public int Priority { get; } = 0;
  18. public bool Optimisable { get; } = false;
  19. public string Name { get; } = "ImageText~Spell";
  20. public BlueprintProvider BlueprintProvider { get; } = null;
  21. private Dictionary<string, string[]> textBlockContents = new Dictionary<string, string[]>();
  22. public bool Qualifies(string name)
  23. {
  24. return name.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase)
  25. || name.EndsWith(".jpg", StringComparison.InvariantCultureIgnoreCase);
  26. }
  27. public BlockJsonInfo[] Import(string name)
  28. {
  29. Texture2D img = new Texture2D(64, 64);
  30. // load file into texture
  31. try
  32. {
  33. byte[] imgData = File.ReadAllBytes(name);
  34. img.LoadImage(imgData);
  35. }
  36. catch (Exception e)
  37. {
  38. Logging.CommandLogError($"Failed to load picture data. Reason: {e.Message}");
  39. Logging.MetaLog(e.Message + "\n" + e.StackTrace);
  40. return new BlockJsonInfo[0];
  41. }
  42. string text = PixelUtility.TextureToString(img);
  43. // generate text block name
  44. byte[] textHash;
  45. using (HashAlgorithm hasher = SHA256.Create())
  46. textHash = hasher.ComputeHash(Encoding.UTF8.GetBytes(text));
  47. string textId = "Pixi_";
  48. for (int i = 0; i < 2 && i < textHash.Length; i++)
  49. {
  50. textId += textHash[i].ToString("X2");
  51. }
  52. // save text block info for post-processing
  53. textBlockContents[name] = new string[2] { textId, text};
  54. return new BlockJsonInfo[1]
  55. {
  56. new BlockJsonInfo
  57. {
  58. color = new float[] {0f, 0f, 0f},
  59. name = "TextBlock",
  60. position = new float[] {0f, 0f, 0f},
  61. rotation = new float[] {0f, 0f, 0f},
  62. scale = new float[] {Mathf.Ceil(img.width / 16f), 1f, Mathf.Ceil(img.height / 16f)}
  63. }
  64. };
  65. }
  66. public void PreProcess(string name, ref ProcessedVoxelObjectNotation[] blocks)
  67. {
  68. Player p = new Player(PlayerType.Local);
  69. float3 pos = p.Position;
  70. for (int i = 0; i < blocks.Length; i++)
  71. {
  72. blocks[i].position += pos;
  73. }
  74. }
  75. public void PostProcess(string name, ref Block[] blocks)
  76. {
  77. // populate text block
  78. AsyncUtils.WaitForSubmission(); // just in case
  79. TextBlock tb = blocks[0].Specialise<TextBlock>();
  80. tb.TextBlockId = textBlockContents[name][0];
  81. tb.Text = textBlockContents[name][1];
  82. textBlockContents.Remove(name);
  83. }
  84. }
  85. }