avm-mays_magical_school 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: []