avm-mays_magical_school 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. checksums.yaml +7 -0
  2. data/lib/avm/mays_magical_school/builders/assembly_stages/stage.rb +38 -0
  3. data/lib/avm/mays_magical_school/builders/assembly_stages/terrain.rb +33 -0
  4. data/lib/avm/mays_magical_school/builders/assembly_stages.rb +35 -0
  5. data/lib/avm/mays_magical_school/builders/yaml_stages/stage.rb +54 -0
  6. data/lib/avm/mays_magical_school/builders/yaml_stages.rb +38 -0
  7. data/lib/avm/mays_magical_school/printed_stage/terrain.rb +29 -0
  8. data/lib/avm/mays_magical_school/printed_stage.rb +76 -0
  9. data/lib/avm/mays_magical_school/runner/extract_tiles.rb +73 -0
  10. data/lib/avm/mays_magical_school/runner/tiles_plan.rb +41 -0
  11. data/lib/avm/mays_magical_school/runner/yaml_stages.rb +21 -0
  12. data/lib/avm/mays_magical_school/runner.rb +24 -0
  13. data/lib/avm/mays_magical_school/sources/base/stage_builder.rb +54 -0
  14. data/lib/avm/mays_magical_school/sources/base/stages.rb +29 -0
  15. data/lib/avm/mays_magical_school/sources/base/terrain_types.rb +43 -0
  16. data/lib/avm/mays_magical_school/sources/base.rb +34 -0
  17. data/lib/avm/mays_magical_school/sources/runners/assembly_stages.rb +24 -0
  18. data/lib/avm/mays_magical_school/sources/runners.rb +13 -0
  19. data/lib/avm/mays_magical_school/sources.rb +11 -0
  20. data/lib/avm/mays_magical_school/stage/object.rb +26 -0
  21. data/lib/avm/mays_magical_school/stage/terrain.rb +18 -0
  22. data/lib/avm/mays_magical_school/stage.rb +92 -0
  23. data/lib/avm/mays_magical_school/terrain_type/version.rb +34 -0
  24. data/lib/avm/mays_magical_school/terrain_type.rb +56 -0
  25. data/lib/avm/mays_magical_school/terrain_type_info/terrain_type.rb +23 -0
  26. data/lib/avm/mays_magical_school/terrain_type_info.rb +78 -0
  27. data/lib/avm/mays_magical_school/terrain_type_searcher.rb +28 -0
  28. data/lib/avm/mays_magical_school/version.rb +7 -0
  29. data/lib/avm/mays_magical_school.rb +9 -0
  30. metadata +117 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 13ba31a5611bc7137a52d3ab1b5629942621a8628f65a6e7a806338fa93e708f
4
+ data.tar.gz: '08c0a2bc2210b3ce10f1d74b0f42bacf55f38fd50ca356c4383212fbe6b64d13'
5
+ SHA512:
6
+ metadata.gz: 8181c642214da510d093d65e2a27f48e1731d58e69ad93a11cc81eaf97b0da85b96e7c78821e84b400e49da81a7384f5f85030a40dc90b801976e9e6b10af10d
7
+ data.tar.gz: e9f23d6f1a42a6d50fb29080c0e8ac1996ed3812af4b7f01105511ed15479d35c8c32c150840985acb815a31a4804dd4e9aa156961d40b1310d6ed4fe16f9c7e
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/mays_magical_school/builders/assembly_stages/terrain'
4
+ require 'eac_ruby_utils/core_ext'
5
+ require 'eac_ruby_utils/bit_array'
6
+
7
+ module Avm
8
+ module MaysMagicalSchool
9
+ module Builders
10
+ class AssemblyStages
11
+ class Stage
12
+ common_constructor :stages_data, :stage
13
+
14
+ def target_content
15
+ "stage_#{stage.number}:\n" \
16
+ '.byte ' + to_bit_array.to_byte_array.map(&:to_asm_hex).join(', ') + "\n"
17
+ end
18
+
19
+ def to_bit_array
20
+ r = ::EacRubyUtils::BitArray.new
21
+ terrains.each do |tile|
22
+ r.push_array(tile.to_bit_array)
23
+ end
24
+ r
25
+ end
26
+
27
+ private
28
+
29
+ def terrains
30
+ stage.terrains.map do |terrain|
31
+ ::Avm::MaysMagicalSchool::Builders::AssemblyStages::Terrain.new(self, terrain)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cliutils/images/base'
4
+ require 'cliutils/v2'
5
+ require 'eac_ruby_utils/core_ext'
6
+ require 'eac_ruby_utils/bit_array'
7
+
8
+ module Avm
9
+ module MaysMagicalSchool
10
+ module Builders
11
+ class AssemblyStages
12
+ class Terrain
13
+ BITS_PER_CODE = 6
14
+ BIT_RANGE = (0..BITS_PER_CODE - 1).freeze
15
+ CODE_RANGE = (0..(2**BITS_PER_CODE - 1)).freeze
16
+
17
+ common_constructor :stage, :terrain
18
+
19
+ def to_bit_array
20
+ ::EacRubyUtils::Byte.new(code).to_bit_array(BIT_RANGE)
21
+ end
22
+
23
+ def code
24
+ r = terrain.asm_code
25
+ return r if CODE_RANGE.include?(r)
26
+
27
+ raise ::RangeError, "Element: #{r}, Range: #{CODE_RANGE}"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module Avm
6
+ module MaysMagicalSchool
7
+ module Builders
8
+ class AssemblyStages
9
+ require_sub __FILE__
10
+ enable_speaker
11
+ enable_simple_cache
12
+ common_constructor :source
13
+
14
+ def perform
15
+ infov 'Target file', target_file
16
+ target_file.write(target_content)
17
+ end
18
+
19
+ def target_file
20
+ source.path.join('res', 'stages.s')
21
+ end
22
+
23
+ def target_content
24
+ stages.map(&:target_content).join("\n")
25
+ end
26
+
27
+ def stages
28
+ source.stages.map do |stage|
29
+ ::Avm::MaysMagicalSchool::Builders::AssemblyStages::Stage.new(self, stage)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_ruby_utils/yaml'
5
+
6
+ module Avm
7
+ module MaysMagicalSchool
8
+ module Builders
9
+ class YamlStages
10
+ class Stage
11
+ common_constructor :builder, :stage
12
+ delegate :source, :number, to: :stage
13
+
14
+ def perform
15
+ target_path.parent.mkpath
16
+ ::EacRubyUtils::Yaml.dump_file(target_path, target_data)
17
+ end
18
+
19
+ def target_data
20
+ {
21
+ objects: objects,
22
+ terrain: terrains_to_s
23
+ }
24
+ end
25
+
26
+ def target_path
27
+ builder.yaml_stages_dir.join("#{number}.yaml")
28
+ end
29
+
30
+ def terrains_to_s
31
+ stage.size.y.times.map { |y| terrains_row_to_s(y) + "\n" }.join
32
+ end
33
+
34
+ def objects
35
+ stage.objects.map do |obj|
36
+ { type: obj.type, x: obj.coord.x, y: obj.coord.y }
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def terrains_row_to_s(terrains_y)
43
+ stage.size.x.times
44
+ .map { |x| terrain_letter(stage.terrain(x, terrains_y)) }.join
45
+ end
46
+
47
+ def terrain_letter(terrain)
48
+ source.terrain_type_info.fetch_letter(terrain.type)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/eac_generic_base0/sources/base'
4
+ require 'avm/mays_magical_school/printed_stage'
5
+ require 'avm/mays_magical_school/terrain_type'
6
+ require 'eac_ruby_utils/core_ext'
7
+ require 'eac_ruby_utils/fs/clearable_directory'
8
+
9
+ module Avm
10
+ module MaysMagicalSchool
11
+ module Builders
12
+ class YamlStages
13
+ require_sub __FILE__
14
+ enable_simple_cache
15
+ enable_speaker
16
+ common_constructor :source
17
+
18
+ def perform
19
+ start_banner
20
+ source.stages.each do |stage|
21
+ ::Avm::MaysMagicalSchool::Builders::YamlStages::Stage.new(self, stage).perform
22
+ end
23
+ end
24
+
25
+ def start_banner
26
+ infov 'Source printscreens dir.', source.printed_stages_dir
27
+ infov 'Target YAML dir.', yaml_stages_dir
28
+ infov 'Terrain types', source.terrain_types.count
29
+ infov 'Stages', source.stages.count
30
+ end
31
+
32
+ def yaml_stages_dir
33
+ source.external_resources_dir.join('build', 'stages_yaml')
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cliutils/v2'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module Avm
7
+ module MaysMagicalSchool
8
+ class PrintedStage
9
+ class Terrain
10
+ SIZE = ::Cliutils.v2.new(16, 16)
11
+
12
+ enable_simple_cache
13
+ common_constructor :printed_stage, :coord
14
+ delegate :source, to: :printed_stage
15
+ delegate :object_type, :letter, :type, to: :terrain_type_version
16
+
17
+ private
18
+
19
+ def terrain_type_version_uncached
20
+ source.terrain_type_version(image)
21
+ end
22
+
23
+ def image
24
+ printed_stage.terrains_image.crop(coord * SIZE, SIZE)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/mays_magical_school/stage'
4
+ require 'cliutils/images/base'
5
+ require 'cliutils/v2'
6
+ require 'eac_ruby_utils/core_ext'
7
+
8
+ module Avm
9
+ module MaysMagicalSchool
10
+ class PrintedStage
11
+ require_sub __FILE__
12
+ enable_speaker
13
+ enable_simple_cache
14
+ common_constructor :source, :file
15
+
16
+ TERRAINS_OFFSET = ::Cliutils.v2.new(32, 23)
17
+ TERRAINS_COUNT = ::Cliutils.v2.new(11, 12)
18
+
19
+ # @return [Avm::MaysMagicalSchool::Stage]
20
+ def build_stage
21
+ ::Avm::MaysMagicalSchool::Stage.new(source, number, build_stage_terrain_types,
22
+ build_stage_objects)
23
+ end
24
+
25
+ def number
26
+ file.basename_noext.to_path.to_i
27
+ end
28
+
29
+ def terrains_flat
30
+ terrains.flat_map(&:itself)
31
+ end
32
+
33
+ def terrains_count
34
+ TERRAINS_COUNT
35
+ end
36
+
37
+ def terrain(*v2_args)
38
+ coord = ::Cliutils.v2.parse_args(*v2_args).first
39
+ terrains[coord.x][coord.y] || raise(::ArgumentError, "Index out of bounds: #{coord}")
40
+ end
41
+
42
+ private
43
+
44
+ def build_stage_objects
45
+ terrains_flat
46
+ .select { |t| t.object_type.present? }
47
+ .map { |t| ::Avm::MaysMagicalSchool::Stage::Object.new(t.object_type, t.coord) }
48
+ end
49
+
50
+ def build_stage_terrain_types
51
+ terrains_flat.map { |t| t.type.name.to_sym }
52
+ end
53
+
54
+ def image_uncached
55
+ ::Cliutils::Images::Base.from_file(file)
56
+ end
57
+
58
+ def terrains_image_uncached
59
+ image.crop(
60
+ TERRAINS_OFFSET,
61
+ TERRAINS_COUNT * ::Avm::MaysMagicalSchool::PrintedStage::Terrain::SIZE
62
+ )
63
+ end
64
+
65
+ # @return [Array<Array<Avm::MaysMagicalSchool::StagesBuilder::Terrain>>]
66
+ def terrains_uncached
67
+ TERRAINS_COUNT.x.times.map do |x|
68
+ TERRAINS_COUNT.y.times.map do |y|
69
+ ::Avm::MaysMagicalSchool::PrintedStage::Terrain
70
+ .new(self, ::Cliutils.v2.new(x, y))
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require File.expand_path('ruby/init', ENV['MYSELF_LIB'])
5
+ require 'cliutils/core_ext'
6
+ require 'cliutils/core/command'
7
+ require 'avm/mays_magical_school/sources/base'
8
+
9
+ module Avm
10
+ module MaysMagicalSchool
11
+ class Runner
12
+ class ExtractTiles
13
+ runner_with :help do
14
+ desc 'Extrai tiles.'
15
+ bool_opt '-p', '--perform', 'Executa a extração de fato.'
16
+ end
17
+
18
+ def run
19
+ start_banner
20
+ original_tiles_sources.each(&:perform) if parsed.perform?
21
+ end
22
+
23
+ # @return [Pathname]
24
+ def original_tiles_root
25
+ source.external_resources_dir.join('src', 'snes_tiles')
26
+ end
27
+
28
+ # @return [Pathname]
29
+ def output_directory
30
+ source.external_resources_dir.join('build', 'snes_extracted_tiles')
31
+ end
32
+
33
+ private
34
+
35
+ def start_banner
36
+ infov 'Source', source
37
+ infov 'Original tiles root', original_tiles_root
38
+ infov 'Original tiles source', original_tiles_sources.count
39
+ infov 'Output directory', output_directory
40
+ end
41
+
42
+ def source_uncached
43
+ ::Avm::MaysMagicalSchool::Sources::Base.default
44
+ end
45
+
46
+ def original_tiles_sources_uncached
47
+ original_tiles_root.glob('*.png').map do |file|
48
+ OriginalTilesSource.new(self, file)
49
+ end
50
+ end
51
+
52
+ class OriginalTilesSource
53
+ common_constructor :runner, :source_file
54
+ delegate :source, to: :runner
55
+
56
+ def perform
57
+ extract_tiles_command.system!
58
+ end
59
+
60
+ def extract_tiles_command
61
+ ::Cliutils::Core.command('i/extract_tiles', '--width=16', '--height=16', '--output-dir',
62
+ output_dir,
63
+ source_file)
64
+ end
65
+
66
+ def output_dir
67
+ runner.output_directory.join(source_file.basename_noext)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cliutils/core_ext'
4
+ require 'avm/mays_magical_school/sources/base'
5
+ require 'cliutils/nes/tiles_plan'
6
+
7
+ module Avm
8
+ module MaysMagicalSchool
9
+ class Runner
10
+ class TilesPlan
11
+ runner_with :help do
12
+ desc 'Constrói os tiles para NES.'
13
+ end
14
+
15
+ def run
16
+ start_banner
17
+ tiles_plan.perform
18
+ end
19
+
20
+ private
21
+
22
+ def start_banner
23
+ infov 'App. instance', tiles_plan.app_instance
24
+ infov 'Source dir.', tiles_plan.source_dir
25
+ infov 'Target dir.', tiles_plan.target_dir
26
+ end
27
+
28
+ def app_instance
29
+ source
30
+ end
31
+
32
+ def tiles_plan_uncached
33
+ ::Cliutils::Nes::TilesPlan.new(
34
+ ::Cliutils::Paths.resource('eac/mays-magic-school_dev/tiles_plan.yaml'),
35
+ app_instance
36
+ )
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cliutils/core_ext'
4
+ require 'avm/mays_magical_school/builders/yaml_stages'
5
+
6
+ module Avm
7
+ module MaysMagicalSchool
8
+ class Runner
9
+ class YamlStages
10
+ runner_with :help do
11
+ desc 'Constrói os arquivo de estágios em YAML.'
12
+ end
13
+
14
+ def run
15
+ source_banner
16
+ ::Avm::MaysMagicalSchool::Builders::YamlStages.new(source).perform
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cliutils/core_ext'
4
+ require 'avm/mays_magical_school/sources/base'
5
+
6
+ module Avm
7
+ module MaysMagicalSchool
8
+ class Runner
9
+ require_sub __FILE__
10
+ runner_with :help, :subcommands do
11
+ pos_arg :source_path
12
+ subcommands
13
+ end
14
+
15
+ def source_banner
16
+ infov 'AppSrc', source
17
+ end
18
+
19
+ def source_uncached
20
+ ::Avm::MaysMagicalSchool::Sources::Base.new(parsed.source_path)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'avm/mays_magical_school/printed_stage'
5
+ require 'avm/mays_magical_school/stage'
6
+
7
+ module Avm
8
+ module MaysMagicalSchool
9
+ module Sources
10
+ class Base < ::Avm::EacGenericBase0::Sources::Base
11
+ class StageBuilder
12
+ common_constructor :source, :number
13
+
14
+ # @return [Avm::MaysMagicalSchool::Stage, nil]
15
+ def build
16
+ build_from_cache || build_from_printed
17
+ end
18
+
19
+ private
20
+
21
+ # @return [Avm::MaysMagicalSchool::Stage, nil]
22
+ def build_from_cache
23
+ return nil unless fs_cache.stored?
24
+
25
+ ::Avm::MaysMagicalSchool::Stage.from_serialized_file(source, fs_cache.content_path)
26
+ end
27
+
28
+ def build_from_printed
29
+ printed_stage.if_present do |_v|
30
+ r = printed_stage.build_stage
31
+ r.serialize_file(fs_cache.content_path)
32
+ r
33
+ end
34
+ end
35
+
36
+ def fs_cache_parent
37
+ source.fs_cache.child('stages')
38
+ end
39
+
40
+ def fs_object_id
41
+ number.to_s
42
+ end
43
+
44
+ # @return [Avm::MaysMagicalSchool::Stage]
45
+ def printed_stage
46
+ source.printed_stages_dir.join("#{number}.png").if_exist do |v|
47
+ ::Avm::MaysMagicalSchool::PrintedStage.new(source, v)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avm
4
+ module MaysMagicalSchool
5
+ module Sources
6
+ class Base < ::Avm::EacGenericBase0::Sources::Base
7
+ module Stages
8
+ STAGES_COUNT = 100
9
+
10
+ # @return [Pathname]
11
+ def printed_stages_dir
12
+ external_resources_dir.join('src', 'printed_stages')
13
+ end
14
+
15
+ private
16
+
17
+ # @return [Array<Avm::MaysMagicalSchool::Stage>]
18
+ def stages_uncached
19
+ STAGES_COUNT.times.map { |count| build_stage(count + 1) }.reject(&:blank?)
20
+ end
21
+
22
+ def build_stage(number)
23
+ ::Avm::MaysMagicalSchool::Sources::Base::StageBuilder.new(self, number).build
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/eac_generic_base0/sources/base'
4
+ require 'eac_ruby_utils/core_ext'
5
+ require 'avm/mays_magical_school/terrain_type_searcher'
6
+ require 'avm/mays_magical_school/terrain_type_info'
7
+
8
+ module Avm
9
+ module MaysMagicalSchool
10
+ module Sources
11
+ class Base < ::Avm::EacGenericBase0::Sources::Base
12
+ module TerrainTypes
13
+ UNKNOWN_TYPE_TERRAIN_NAME = 'unknown'
14
+
15
+ def terrain_types_dir
16
+ external_resources_dir.join('src', 'stages_terrain_types')
17
+ end
18
+
19
+ def terrain_type_version(image)
20
+ ::Avm::MaysMagicalSchool::TerrainTypeSearcher.new(self, image).find
21
+ end
22
+
23
+ private
24
+
25
+ def terrain_types_uncached
26
+ terrain_types_dir.glob('*/').map do |dir|
27
+ ::Avm::MaysMagicalSchool::TerrainType.new(self, dir)
28
+ end
29
+ end
30
+
31
+ def terrain_type_info_uncached
32
+ ::Avm::MaysMagicalSchool::TerrainTypeInfo.new(self)
33
+ end
34
+
35
+ def unknown_terrain_type_uncached
36
+ terrain_types.find { |tt| tt.name == UNKNOWN_TYPE_TERRAIN_NAME } ||
37
+ raise("Terrain type not found with name \"#{UNKNOWN_TYPE_TERRAIN_NAME}\"")
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/eac_generic_base0/sources/base'
4
+ require 'avm/mays_magical_school/sources/runners'
5
+ require 'eac_ruby_utils/core_ext'
6
+
7
+ module Avm
8
+ module MaysMagicalSchool
9
+ module Sources
10
+ class Base < ::Avm::EacGenericBase0::Sources::Base
11
+ require_sub __FILE__, include_modules: true
12
+ enable_simple_cache
13
+
14
+ DEFAULT_PATH_ENVVAR_KEY = 'MAYSMAGICSCHOOL_DEV_INSTALL_PATH'
15
+
16
+ class << self
17
+ def default
18
+ @default ||= new(ENV.fetch(DEFAULT_PATH_ENVVAR_KEY))
19
+ end
20
+ end
21
+
22
+ # @return [Pathname]
23
+ def external_resources_dir
24
+ instance.entry('resources_path').value.to_pathname
25
+ end
26
+
27
+ # @return [String]
28
+ def fs_object_id
29
+ path.to_path.variableize
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cliutils/core_ext'
4
+ require 'avm/mays_magical_school/builders/assembly_stages'
5
+
6
+ module Avm
7
+ module MaysMagicalSchool
8
+ module Sources
9
+ module Runners
10
+ class AssemblyStages
11
+ runner_with :help do
12
+ desc 'Constrói o arquivo de estágios em Assembly.'
13
+ end
14
+
15
+ def run
16
+ source_banner
17
+ ::Avm::MaysMagicalSchool::Builders::AssemblyStages.new(runner_context.call(:source))
18
+ .perform
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module Avm
6
+ module MaysMagicalSchool
7
+ module Sources
8
+ module Runners
9
+ require_sub __FILE__
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module Avm
6
+ module MaysMagicalSchool
7
+ module Sources
8
+ require_sub __FILE__
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/eac_generic_base0/sources/base'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module Avm
7
+ module MaysMagicalSchool
8
+ class Stage
9
+ class Object
10
+ class << self
11
+ def from_serialized_data(data)
12
+ new(data.fetch(:type), ::Cliutils.v2.new(*data.fetch(:coord)))
13
+ end
14
+ end
15
+
16
+ common_constructor :type, :coord
17
+
18
+ def to_serialized_data
19
+ {
20
+ type: type, coord: coord.values
21
+ }
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/eac_generic_base0/sources/base'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module Avm
7
+ module MaysMagicalSchool
8
+ class Stage
9
+ class Terrain
10
+ common_constructor :stage, :type, :coord
11
+
12
+ def asm_code
13
+ stage.source.terrain_type_info.fetch_code(type)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'avm/eac_generic_base0/sources/base'
4
+ require 'avm/mays_magical_school/builders/yaml_stages/stage'
5
+ require 'cliutils/v2'
6
+ require 'eac_ruby_utils/core_ext'
7
+
8
+ module Avm
9
+ module MaysMagicalSchool
10
+ class Stage
11
+ require_sub __FILE__
12
+
13
+ SIZE = ::Cliutils.v2.new(11, 12)
14
+
15
+ class << self
16
+ def from_serialized_file(source, file)
17
+ from_serialized_data(source, ::EacRubyUtils::Yaml.load_file(file))
18
+ end
19
+
20
+ def from_serialized_data(source, data)
21
+ new(
22
+ source,
23
+ data.fetch(:number),
24
+ terrains_types_from_data(data.fetch(:terrains)),
25
+ objects_from_data(data.fetch(:objects))
26
+ )
27
+ end
28
+
29
+ private
30
+
31
+ def objects_from_data(data)
32
+ data.map.each do |item_data|
33
+ ::Avm::MaysMagicalSchool::Stage::Object.from_serialized_data(item_data)
34
+ end
35
+ end
36
+
37
+ def terrains_types_from_data(data)
38
+ data
39
+ end
40
+ end
41
+
42
+ attr_reader :source, :number, :terrains, :objects
43
+
44
+ def initialize(source, number, terrains_types, objects)
45
+ self.source = source
46
+ self.number = number
47
+ self.terrains = terrains_types.assert_count(SIZE.product, 'terrains_types')
48
+ .each_with_index.map do |tt, i|
49
+ ::Avm::MaysMagicalSchool::Stage::Terrain.new(self, tt, ::Cliutils.v2.new(
50
+ i % size.x,
51
+ i.div(size.y)
52
+ ))
53
+ end
54
+ self.objects = objects
55
+ end
56
+
57
+ def serialize_file(file)
58
+ file.to_pathname.parent.mkpath
59
+ ::EacRubyUtils::Yaml.dump_file(file, to_serialized_data)
60
+ end
61
+
62
+ def size
63
+ SIZE
64
+ end
65
+
66
+ def terrain(*coord_args)
67
+ coord = ::Cliutils.v2.new(*coord_args)
68
+ terrains.fetch(coord.x + coord.y * size.x)
69
+ end
70
+
71
+ def to_serialized_data
72
+ {
73
+ number: number,
74
+ terrains: terrains_to_serialized_data,
75
+ objects: objects_to_serialized_data
76
+ }
77
+ end
78
+
79
+ private
80
+
81
+ attr_writer :source, :number, :terrains, :objects
82
+
83
+ def objects_to_serialized_data
84
+ objects.map(&:to_serialized_data)
85
+ end
86
+
87
+ def terrains_to_serialized_data
88
+ terrains.map(&:type)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cliutils/v2'
4
+ require 'cliutils/images/base'
5
+ require 'eac_ruby_utils/core_ext'
6
+
7
+ module Avm
8
+ module MaysMagicalSchool
9
+ class TerrainType
10
+ class Version
11
+ enable_simple_cache
12
+ common_constructor :type, :file
13
+ delegate :letter, to: :type
14
+
15
+ MAY_BASENAME = 'may'
16
+ FLAME_BASENAME = 'flame'
17
+
18
+ def match_image?(image)
19
+ self.image == image
20
+ end
21
+
22
+ private
23
+
24
+ def image_uncached
25
+ ::Cliutils::Images::Base.from_file(file)
26
+ end
27
+
28
+ def object_type_uncached
29
+ file.basename_noext.to_path.split('_').find { |s| !/\A\d+\z/.match?(s) }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cliutils/v2'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module Avm
7
+ module MaysMagicalSchool
8
+ class TerrainType
9
+ require_sub __FILE__
10
+ enable_simple_cache
11
+ attr_reader :versions
12
+ common_constructor :source, :dir do
13
+ self.versions = dir.glob('*.png').map do |file|
14
+ ::Avm::MaysMagicalSchool::TerrainType::Version.new(self, file)
15
+ end
16
+ end
17
+
18
+ LETTER_FILE_BASENAME = 'letter'
19
+
20
+ def add(image)
21
+ path = new_image_file
22
+ path.parent.mkpath
23
+ image.write(path)
24
+ version = ::Avm::MaysMagicalSchool::TerrainType::Version.new(self, path)
25
+ versions << version
26
+ version
27
+ end
28
+
29
+ def new_image_file
30
+ i = 1
31
+ loop do
32
+ file = dir.join("#{i}.png")
33
+ return file unless file.exist?
34
+
35
+ i += 1
36
+ end
37
+ end
38
+
39
+ def letter
40
+ source.terrain_type_info.fetch_letter(name)
41
+ end
42
+
43
+ def match_image_version(image)
44
+ versions.find { |v| v.match_image?(image) }
45
+ end
46
+
47
+ def name
48
+ dir.basename.to_path
49
+ end
50
+
51
+ private
52
+
53
+ attr_writer :versions
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module Avm
6
+ module MaysMagicalSchool
7
+ class TerrainTypeInfo
8
+ class TerrainType
9
+ class << self
10
+ def from_data(info, data)
11
+ new(info, data.fetch(:name), data.fetch(:letter), data.fetch(:code))
12
+ end
13
+ end
14
+
15
+ common_constructor :info, :name, :letter, :code
16
+
17
+ def to_data
18
+ { name: name, letter: letter, code: code }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module Avm
6
+ module MaysMagicalSchool
7
+ class TerrainTypeInfo
8
+ require_sub __FILE__
9
+ attr_reader :terrain_types
10
+ common_constructor :source do
11
+ self.terrain_types = read_data_file.with_indifferent_access
12
+ end
13
+
14
+ NEW_LETTERS = [*'A'..'Z', *'a'..'z', *'0'..'9'].freeze
15
+
16
+ def fetch_code(terrain_type_name)
17
+ fetch_terrain(terrain_type_name).code
18
+ end
19
+
20
+ def fetch_letter(terrain_type_name)
21
+ fetch_terrain(terrain_type_name).letter
22
+ end
23
+
24
+ def fetch_terrain(terrain_type_name)
25
+ terrain_types[terrain_type_name] || new_terrain_type(terrain_type_name)
26
+ end
27
+
28
+ def file
29
+ source.terrain_types_dir.join('info.yaml')
30
+ end
31
+
32
+ private
33
+
34
+ attr_writer :terrain_types
35
+
36
+ def new_terrain_type(terrain_type_name)
37
+ terrain_types[terrain_type_name] = ::Avm::MaysMagicalSchool::TerrainTypeInfo::TerrainType
38
+ .new(self, terrain_type_name, new_terrain_type_letter,
39
+ new_terray_type_code)
40
+ write_data_file
41
+ terrain_types[terrain_type_name]
42
+ end
43
+
44
+ def new_terray_type_code
45
+ codes = terrain_types.values.map(&:code)
46
+ r = 0
47
+ r += 1 while codes.include?(r)
48
+ r
49
+ end
50
+
51
+ def new_terrain_type_letter
52
+ letters = terrain_types.values.map(&:letter)
53
+ NEW_LETTERS.each do |letter|
54
+ return letter unless letters.include?(letter)
55
+ end
56
+
57
+ raise 'No available letter'
58
+ end
59
+
60
+ def data_to_dump
61
+ terrain_types.values.map { |t| [t.name, t.to_data] }.sort_by { |v| [v.first] }
62
+ .to_h.stringify_keys
63
+ end
64
+
65
+ def read_data_file
66
+ return {} unless file.exist?
67
+
68
+ ::EacRubyUtils::Yaml.load_file(file).map do |name, data|
69
+ [name, ::Avm::MaysMagicalSchool::TerrainTypeInfo::TerrainType.from_data(self, data)]
70
+ end.to_h
71
+ end
72
+
73
+ def write_data_file
74
+ ::EacRubyUtils::Yaml.dump_file(file, data_to_dump)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cliutils/v2'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module Avm
7
+ module MaysMagicalSchool
8
+ class TerrainTypeSearcher
9
+ require_sub __FILE__
10
+
11
+ common_constructor :source, :image
12
+
13
+ def find
14
+ find_by_known || find_by_unknown
15
+ end
16
+
17
+ private
18
+
19
+ def find_by_known
20
+ source.terrain_types.lazy.map { |tt| tt.match_image_version(image) }.find(&:present?)
21
+ end
22
+
23
+ def find_by_unknown
24
+ source.unknown_terrain_type.add(image)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Avm
4
+ module MaysMagicalSchool
5
+ VERSION = '0.2.0'
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module Avm
6
+ module MaysMagicalSchool
7
+ require_sub __FILE__
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: avm-mays_magical_school
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Put here the authors
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-03-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: avm-eac_generic_base0
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: eac_ruby_utils
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.112'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.112'
41
+ - !ruby/object:Gem::Dependency
42
+ name: eac_ruby_gem_support
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.5'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 0.5.1
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '0.5'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 0.5.1
61
+ description:
62
+ email:
63
+ executables: []
64
+ extensions: []
65
+ extra_rdoc_files: []
66
+ files:
67
+ - lib/avm/mays_magical_school.rb
68
+ - lib/avm/mays_magical_school/builders/assembly_stages.rb
69
+ - lib/avm/mays_magical_school/builders/assembly_stages/stage.rb
70
+ - lib/avm/mays_magical_school/builders/assembly_stages/terrain.rb
71
+ - lib/avm/mays_magical_school/builders/yaml_stages.rb
72
+ - lib/avm/mays_magical_school/builders/yaml_stages/stage.rb
73
+ - lib/avm/mays_magical_school/printed_stage.rb
74
+ - lib/avm/mays_magical_school/printed_stage/terrain.rb
75
+ - lib/avm/mays_magical_school/runner.rb
76
+ - lib/avm/mays_magical_school/runner/extract_tiles.rb
77
+ - lib/avm/mays_magical_school/runner/tiles_plan.rb
78
+ - lib/avm/mays_magical_school/runner/yaml_stages.rb
79
+ - lib/avm/mays_magical_school/sources.rb
80
+ - lib/avm/mays_magical_school/sources/base.rb
81
+ - lib/avm/mays_magical_school/sources/base/stage_builder.rb
82
+ - lib/avm/mays_magical_school/sources/base/stages.rb
83
+ - lib/avm/mays_magical_school/sources/base/terrain_types.rb
84
+ - lib/avm/mays_magical_school/sources/runners.rb
85
+ - lib/avm/mays_magical_school/sources/runners/assembly_stages.rb
86
+ - lib/avm/mays_magical_school/stage.rb
87
+ - lib/avm/mays_magical_school/stage/object.rb
88
+ - lib/avm/mays_magical_school/stage/terrain.rb
89
+ - lib/avm/mays_magical_school/terrain_type.rb
90
+ - lib/avm/mays_magical_school/terrain_type/version.rb
91
+ - lib/avm/mays_magical_school/terrain_type_info.rb
92
+ - lib/avm/mays_magical_school/terrain_type_info/terrain_type.rb
93
+ - lib/avm/mays_magical_school/terrain_type_searcher.rb
94
+ - lib/avm/mays_magical_school/version.rb
95
+ homepage:
96
+ licenses: []
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubygems_version: 3.1.6
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Put here de description.
117
+ test_files: []