cyberarm_engine 0.25.0 → 0.30.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.
- checksums.yaml +4 -4
- data/.gitignore +9 -8
- data/.rubocop.yml +7 -7
- data/.travis.yml +5 -5
- data/Gemfile +6 -6
- data/Gemfile.lock +37 -25
- data/LICENSE.txt +21 -21
- data/README.md +74 -74
- data/Rakefile +10 -10
- data/assets/shaders/fragment/g_buffer.glsl +30 -30
- data/assets/shaders/fragment/lighting.glsl +115 -115
- data/assets/shaders/include/light_struct.glsl +11 -11
- data/assets/shaders/include/material_struct.glsl +16 -16
- data/assets/shaders/vertex/g_buffer.glsl +28 -28
- data/assets/shaders/vertex/lighting.glsl +24 -24
- data/assets/textures/ui/circle.png +0 -0
- data/assets/textures/ui/circle_small.png +0 -0
- data/assets/textures/ui/rounded.png +0 -0
- data/assets/textures/ui/rounded_bottom.png +0 -0
- data/assets/textures/ui/rounded_left.png +0 -0
- data/assets/textures/ui/rounded_left_bottom.png +0 -0
- data/assets/textures/ui/rounded_left_top.png +0 -0
- data/assets/textures/ui/rounded_right.png +0 -0
- data/assets/textures/ui/rounded_right_bottom.png +0 -0
- data/assets/textures/ui/rounded_right_top.png +0 -0
- data/assets/textures/ui/rounded_small.png +0 -0
- data/assets/textures/ui/rounded_tiny.png +0 -0
- data/assets/textures/ui/rounded_top.png +0 -0
- data/assets/textures/ui/square.png +0 -0
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/cyberarm_engine.gemspec +35 -36
- data/lib/cyberarm_engine/animator.rb +219 -219
- data/lib/cyberarm_engine/background.rb +156 -158
- data/lib/cyberarm_engine/background_image.rb +93 -93
- data/lib/cyberarm_engine/background_nine_slice.rb +182 -142
- data/lib/cyberarm_engine/bounding_box.rb +150 -150
- data/lib/cyberarm_engine/builtin/intro_state.rb +130 -130
- data/lib/cyberarm_engine/cache/download_manager.rb +123 -123
- data/lib/cyberarm_engine/cache.rb +4 -4
- data/lib/cyberarm_engine/common.rb +133 -131
- data/lib/cyberarm_engine/config_file.rb +46 -46
- data/lib/cyberarm_engine/console/command.rb +157 -157
- data/lib/cyberarm_engine/console/commands/help_command.rb +43 -43
- data/lib/cyberarm_engine/console/subcommand.rb +99 -99
- data/lib/cyberarm_engine/console.rb +248 -248
- data/lib/cyberarm_engine/event_bus.rb +39 -0
- data/lib/cyberarm_engine/game_object.rb +244 -244
- data/lib/cyberarm_engine/game_state.rb +134 -124
- data/lib/cyberarm_engine/gosu_ext/draw_arc.rb +111 -111
- data/lib/cyberarm_engine/gosu_ext/draw_circle.rb +30 -30
- data/lib/cyberarm_engine/gosu_ext/draw_path.rb +17 -17
- data/lib/cyberarm_engine/model/material.rb +21 -21
- data/lib/cyberarm_engine/model/mesh.rb +131 -131
- data/lib/cyberarm_engine/model/parser.rb +74 -74
- data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -138
- data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -154
- data/lib/cyberarm_engine/model.rb +216 -216
- data/lib/cyberarm_engine/model_cache.rb +31 -31
- data/lib/cyberarm_engine/notification.rb +82 -82
- data/lib/cyberarm_engine/notification_manager.rb +241 -241
- data/lib/cyberarm_engine/opengl/light.rb +52 -52
- data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -46
- data/lib/cyberarm_engine/opengl/perspective_camera.rb +41 -41
- data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -249
- data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +167 -167
- data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +307 -307
- data/lib/cyberarm_engine/opengl/renderer/renderer.rb +33 -33
- data/lib/cyberarm_engine/opengl/shader.rb +408 -408
- data/lib/cyberarm_engine/opengl/texture.rb +69 -69
- data/lib/cyberarm_engine/opengl.rb +53 -53
- data/lib/cyberarm_engine/pathfinding/graph.rb +64 -0
- data/lib/cyberarm_engine/pathfinding/graph_search.rb +6 -0
- data/lib/cyberarm_engine/pathfinding/graph_searches/astar_search.rb +6 -0
- data/lib/cyberarm_engine/pathfinding/graph_searches/breadth_first_search.rb +27 -0
- data/lib/cyberarm_engine/pathfinding/graph_searches/dijkstra_search.rb +6 -0
- data/lib/cyberarm_engine/pathfinding/graphs/grid.rb +52 -0
- data/lib/cyberarm_engine/ray.rb +56 -56
- data/lib/cyberarm_engine/result.rb +19 -0
- data/lib/cyberarm_engine/stats.rb +200 -200
- data/lib/cyberarm_engine/text.rb +288 -260
- data/lib/cyberarm_engine/timer.rb +27 -23
- data/lib/cyberarm_engine/transform.rb +296 -296
- data/lib/cyberarm_engine/trees/aabb_node.rb +126 -126
- data/lib/cyberarm_engine/trees/aabb_tree.rb +55 -55
- data/lib/cyberarm_engine/trees/aabb_tree_debug.rb +29 -29
- data/lib/cyberarm_engine/ui/border_canvas.rb +102 -102
- data/lib/cyberarm_engine/ui/dialog.rb +24 -0
- data/lib/cyberarm_engine/ui/dsl.rb +170 -142
- data/lib/cyberarm_engine/ui/element.rb +664 -662
- data/lib/cyberarm_engine/ui/elements/button.rb +99 -100
- data/lib/cyberarm_engine/ui/elements/check_box.rb +58 -54
- data/lib/cyberarm_engine/ui/elements/container.rb +413 -407
- data/lib/cyberarm_engine/ui/elements/edit_box.rb +200 -179
- data/lib/cyberarm_engine/ui/elements/edit_line.rb +299 -297
- data/lib/cyberarm_engine/ui/elements/flow.rb +15 -15
- data/lib/cyberarm_engine/ui/elements/image.rb +78 -72
- data/lib/cyberarm_engine/ui/elements/list_box.rb +79 -79
- data/lib/cyberarm_engine/ui/elements/menu.rb +27 -27
- data/lib/cyberarm_engine/ui/elements/menu_item.rb +6 -6
- data/lib/cyberarm_engine/ui/elements/progress.rb +95 -93
- data/lib/cyberarm_engine/ui/elements/radio.rb +6 -6
- data/lib/cyberarm_engine/ui/elements/slider.rb +111 -107
- data/lib/cyberarm_engine/ui/elements/stack.rb +11 -11
- data/lib/cyberarm_engine/ui/elements/text_block.rb +236 -222
- data/lib/cyberarm_engine/ui/elements/toggle_button.rb +71 -67
- data/lib/cyberarm_engine/ui/elements/widget.rb +45 -0
- data/lib/cyberarm_engine/ui/event.rb +54 -54
- data/lib/cyberarm_engine/ui/gui_state.rb +402 -326
- data/lib/cyberarm_engine/ui/page.rb +39 -0
- data/lib/cyberarm_engine/ui/style.rb +94 -61
- data/lib/cyberarm_engine/ui/theme.rb +237 -225
- data/lib/cyberarm_engine/vector.rb +312 -312
- data/lib/cyberarm_engine/version.rb +4 -4
- data/lib/cyberarm_engine/window.rb +234 -195
- data/lib/cyberarm_engine.rb +88 -76
- data/mrbgem.rake +29 -29
- metadata +30 -5
|
@@ -1,131 +1,133 @@
|
|
|
1
|
-
module CyberarmEngine
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Gosu::Color.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
Gosu::Color.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
klass.new(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
end
|
|
1
|
+
module CyberarmEngine
|
|
2
|
+
GUI_DEBUG = false
|
|
3
|
+
|
|
4
|
+
module Common
|
|
5
|
+
ImageBlob = Data.define(:to_blob, :columns, :rows)
|
|
6
|
+
|
|
7
|
+
def push_state(klass, options = {})
|
|
8
|
+
window.push_state(klass, options)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def current_state
|
|
12
|
+
window.current_state
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def previous_state(state = nil)
|
|
16
|
+
raise "Only available for CyberarmEngine::GameState and subclasses" unless is_a?(CyberarmEngine::GameState) || state.is_a?(CyberarmEngine::GameState)
|
|
17
|
+
|
|
18
|
+
i = window.states.index(state || self)
|
|
19
|
+
window.states[i - 1] unless (i - 1).negative?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def pop_state
|
|
23
|
+
window.pop_state
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def shift_state
|
|
27
|
+
window.shift_state
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def show_cursor
|
|
31
|
+
window.show_cursor
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def show_cursor=(boolean)
|
|
35
|
+
window.show_cursor = boolean
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def find_element_by_tag(container, tag, list = [])
|
|
39
|
+
return unless container
|
|
40
|
+
|
|
41
|
+
container.children.each do |child|
|
|
42
|
+
list << child if child.style.tag == tag
|
|
43
|
+
|
|
44
|
+
find_element_by_tag(child, tag, list) if child.is_a?(CyberarmEngine::Element::Container)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
list.first
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def draw_rect(x, y, width, height, color, z = 0, mode = :default)
|
|
51
|
+
Gosu.draw_rect(x, y, width, height, color, z, mode)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def fill(color, z = 0)
|
|
55
|
+
draw_rect(0, 0, window.width, window.height, color, z)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def lighten(color, amount = 25)
|
|
59
|
+
if color.respond_to?(:alpha)
|
|
60
|
+
Gosu::Color.rgba(color.red + amount, color.green + amount, color.blue + amount, color.alpha)
|
|
61
|
+
else
|
|
62
|
+
Gosu::Color.rgb(color.red + amount, color.green + amount, color.blue + amount)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def darken(color, amount = 25)
|
|
67
|
+
if color.respond_to?(:alpha)
|
|
68
|
+
Gosu::Color.rgba(color.red - amount, color.green - amount, color.blue - amount, color.alpha)
|
|
69
|
+
else
|
|
70
|
+
Gosu::Color.rgb(color.red - amount, color.green - amount, color.blue - amount)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def opacity(color, ratio = 1.0)
|
|
75
|
+
alpha = 255 * ratio
|
|
76
|
+
|
|
77
|
+
Gosu::Color.rgba(color.red, color.green, color.blue, alpha)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def get_asset(path, hash, klass, retro = false, tileable = false)
|
|
81
|
+
asset = nil
|
|
82
|
+
hash.detect do |_asset, instance|
|
|
83
|
+
if _asset == path
|
|
84
|
+
asset = instance
|
|
85
|
+
true
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
unless asset
|
|
90
|
+
instance = nil
|
|
91
|
+
instance = if klass == Gosu::Image
|
|
92
|
+
path_or_blob = path.is_a?(String) ? path : ImageBlob.new(path.to_blob, path.width, path.height)
|
|
93
|
+
klass.new(path_or_blob, retro: retro, tileable: tileable)
|
|
94
|
+
else
|
|
95
|
+
klass.new(path)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
hash[path] = instance
|
|
99
|
+
asset = instance
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
asset
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def get_image(path, retro: false, tileable: false)
|
|
106
|
+
get_asset(path, Window::IMAGES, Gosu::Image, retro, tileable)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def get_sample(path)
|
|
110
|
+
get_asset(path, Window::SAMPLES, Gosu::Sample)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def get_song(path)
|
|
114
|
+
get_asset(path, Window::SONGS, Gosu::Song)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def window
|
|
118
|
+
CyberarmEngine::Window.instance
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def control_down?
|
|
122
|
+
Gosu.button_down?(Gosu::KB_LEFT_CONTROL) || Gosu.button_down?(Gosu::KB_RIGHT_CONTROL)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def shift_down?
|
|
126
|
+
Gosu.button_down?(Gosu::KB_LEFT_SHIFT) || Gosu.button_down?(Gosu::KB_RIGHT_SHIFT)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def alt_down?
|
|
130
|
+
Gosu.button_down?(Gosu::KB_LEFT_ALT) || Gosu.button_down?(Gosu::KB_RIGHT_ALT)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
module CyberarmEngine
|
|
2
|
-
class ConfigFile
|
|
3
|
-
def initialize(file:)
|
|
4
|
-
@file = file
|
|
5
|
-
|
|
6
|
-
if File.exist?(@file)
|
|
7
|
-
deserialize
|
|
8
|
-
else
|
|
9
|
-
@data = {}
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def []=(*keys, value)
|
|
14
|
-
last_key = keys.last
|
|
15
|
-
|
|
16
|
-
if keys.size == 1
|
|
17
|
-
hash = @data
|
|
18
|
-
else
|
|
19
|
-
keys.pop
|
|
20
|
-
hash = @data[keys.shift] ||= {}
|
|
21
|
-
|
|
22
|
-
keys.each do |key|
|
|
23
|
-
hash = hash[key] ||= {}
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
hash[last_key] = value
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def get(*keys)
|
|
31
|
-
@data.dig(*keys)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def serialize
|
|
35
|
-
JSON.dump(@data)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def deserialize
|
|
39
|
-
@data = JSON.parse(File.read(@file), symbolize_names: true)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def save!
|
|
43
|
-
File.open(@file, "w") { |f| f.write(serialize) }
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
1
|
+
module CyberarmEngine
|
|
2
|
+
class ConfigFile
|
|
3
|
+
def initialize(file:)
|
|
4
|
+
@file = file
|
|
5
|
+
|
|
6
|
+
if File.exist?(@file)
|
|
7
|
+
deserialize
|
|
8
|
+
else
|
|
9
|
+
@data = {}
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def []=(*keys, value)
|
|
14
|
+
last_key = keys.last
|
|
15
|
+
|
|
16
|
+
if keys.size == 1
|
|
17
|
+
hash = @data
|
|
18
|
+
else
|
|
19
|
+
keys.pop
|
|
20
|
+
hash = @data[keys.shift] ||= {}
|
|
21
|
+
|
|
22
|
+
keys.each do |key|
|
|
23
|
+
hash = hash[key] ||= {}
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
hash[last_key] = value
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def get(*keys)
|
|
31
|
+
@data.dig(*keys)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def serialize
|
|
35
|
+
JSON.dump(@data)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def deserialize
|
|
39
|
+
@data = JSON.parse(File.read(@file), symbolize_names: true)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def save!
|
|
43
|
+
File.open(@file, "w") { |f| f.write(serialize) }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -1,158 +1,158 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module CyberarmEngine
|
|
4
|
-
class Console
|
|
5
|
-
module Style
|
|
6
|
-
def self.error(string)
|
|
7
|
-
"<c=ff5555>#{string}</c>"
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def self.warn(string)
|
|
11
|
-
"<c=ff7700>#{string}</c>"
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def self.notice(string)
|
|
15
|
-
"<c=55ff55>#{string}</c>"
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def self.highlight(string, color = "5555ff")
|
|
19
|
-
"<c=#{color}>#{string}</c>"
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
class Command
|
|
24
|
-
def self.inherited(subclass)
|
|
25
|
-
@list ||= []
|
|
26
|
-
@commands ||= []
|
|
27
|
-
@list << subclass
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def self.setup
|
|
31
|
-
@list ||= []
|
|
32
|
-
@commands = []
|
|
33
|
-
@list.each do |subclass|
|
|
34
|
-
cmd = subclass.new
|
|
35
|
-
if @commands.detect { |c| c.command == cmd.command }
|
|
36
|
-
raise "Command '#{cmd.command}' from '#{cmd.class}' already exists!"
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
@commands << cmd
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def self.use(command, arguments, console)
|
|
44
|
-
found_command = @commands.detect { |cmd| cmd.command == command.to_sym }
|
|
45
|
-
|
|
46
|
-
if found_command
|
|
47
|
-
found_command.handle(arguments, console)
|
|
48
|
-
else
|
|
49
|
-
console.stdin("Command #{Style.error(command)} not found.")
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def self.find(command)
|
|
54
|
-
@commands.detect { |cmd| cmd.command == command.to_sym }
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def self.list_commands
|
|
58
|
-
@commands
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def initialize
|
|
62
|
-
@store = {}
|
|
63
|
-
@subcommands = []
|
|
64
|
-
|
|
65
|
-
setup
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def setup
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def subcommand(command, type)
|
|
72
|
-
if @subcommands.detect { |subcmd| subcmd.command == command.to_sym }
|
|
73
|
-
raise "Subcommand '#{command}' for '#{self.command}' already exists!"
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
@subcommands << SubCommand.new(self, command, type)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def get(key)
|
|
80
|
-
@store[key]
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def set(key, value)
|
|
84
|
-
@store[key] = value
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def group
|
|
88
|
-
raise NotImplementedError
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def command
|
|
92
|
-
raise NotImplementedError
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def handle(arguments, console)
|
|
96
|
-
raise NotImplementedError
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def autocomplete(console)
|
|
100
|
-
split = console.text_input.text.split(" ")
|
|
101
|
-
|
|
102
|
-
if @subcommands.size.positive?
|
|
103
|
-
if !console.text_input.text.end_with?(" ") && split.size == 2
|
|
104
|
-
list = console.abbrev_search(@subcommands.map { |cmd| cmd.command.to_s }, split.last)
|
|
105
|
-
|
|
106
|
-
if list.size == 1
|
|
107
|
-
console.text_input.text = "#{split.first} #{list.first} "
|
|
108
|
-
else
|
|
109
|
-
return unless list.size.positive?
|
|
110
|
-
|
|
111
|
-
console.stdin(list.map { |cmd| Console::Style.highlight(cmd) }.join(", ").to_s)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# List available options on subcommand
|
|
115
|
-
elsif (console.text_input.text.end_with?(" ") && split.size == 2) || !console.text_input.text.end_with?(" ") && split.size == 3
|
|
116
|
-
subcommand = @subcommands.detect { |cmd| cmd.command.to_s == (split[1]) }
|
|
117
|
-
|
|
118
|
-
if subcommand
|
|
119
|
-
if split.size == 2
|
|
120
|
-
console.stdin("Available options: #{subcommand.values.map { |value| Console::Style.highlight(value) }.join(',')}")
|
|
121
|
-
else
|
|
122
|
-
list = console.abbrev_search(subcommand.values, split.last)
|
|
123
|
-
if list.size == 1
|
|
124
|
-
console.text_input.text = "#{split.first} #{split[1]} #{list.first} "
|
|
125
|
-
elsif list.size.positive?
|
|
126
|
-
console.stdin("Available options: #{list.map { |value| Console::Style.highlight(value) }.join(',')}")
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
# List available subcommands if command was entered and has only a space after it
|
|
132
|
-
elsif console.text_input.text.end_with?(" ") && split.size == 1
|
|
133
|
-
console.stdin("Available subcommands: #{@subcommands.map { |cmd| Console::Style.highlight(cmd.command) }.join(', ')}")
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def handle_subcommand(arguments, console)
|
|
139
|
-
if arguments.size.zero?
|
|
140
|
-
console.stdin(usage)
|
|
141
|
-
return
|
|
142
|
-
end
|
|
143
|
-
subcommand = arguments.delete_at(0)
|
|
144
|
-
|
|
145
|
-
found_command = @subcommands.detect { |cmd| cmd.command == subcommand.to_sym }
|
|
146
|
-
if found_command
|
|
147
|
-
found_command.handle(arguments, console)
|
|
148
|
-
else
|
|
149
|
-
console.stdin("Unknown subcommand #{Style.error(subcommand)} for #{Style.highlight(command)}")
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def usage
|
|
154
|
-
raise NotImplementedError
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CyberarmEngine
|
|
4
|
+
class Console
|
|
5
|
+
module Style
|
|
6
|
+
def self.error(string)
|
|
7
|
+
"<c=ff5555>#{string}</c>"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.warn(string)
|
|
11
|
+
"<c=ff7700>#{string}</c>"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.notice(string)
|
|
15
|
+
"<c=55ff55>#{string}</c>"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.highlight(string, color = "5555ff")
|
|
19
|
+
"<c=#{color}>#{string}</c>"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class Command
|
|
24
|
+
def self.inherited(subclass)
|
|
25
|
+
@list ||= []
|
|
26
|
+
@commands ||= []
|
|
27
|
+
@list << subclass
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.setup
|
|
31
|
+
@list ||= []
|
|
32
|
+
@commands = []
|
|
33
|
+
@list.each do |subclass|
|
|
34
|
+
cmd = subclass.new
|
|
35
|
+
if @commands.detect { |c| c.command == cmd.command }
|
|
36
|
+
raise "Command '#{cmd.command}' from '#{cmd.class}' already exists!"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
@commands << cmd
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.use(command, arguments, console)
|
|
44
|
+
found_command = @commands.detect { |cmd| cmd.command == command.to_sym }
|
|
45
|
+
|
|
46
|
+
if found_command
|
|
47
|
+
found_command.handle(arguments, console)
|
|
48
|
+
else
|
|
49
|
+
console.stdin("Command #{Style.error(command)} not found.")
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.find(command)
|
|
54
|
+
@commands.detect { |cmd| cmd.command == command.to_sym }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.list_commands
|
|
58
|
+
@commands
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def initialize
|
|
62
|
+
@store = {}
|
|
63
|
+
@subcommands = []
|
|
64
|
+
|
|
65
|
+
setup
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def setup
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def subcommand(command, type)
|
|
72
|
+
if @subcommands.detect { |subcmd| subcmd.command == command.to_sym }
|
|
73
|
+
raise "Subcommand '#{command}' for '#{self.command}' already exists!"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
@subcommands << SubCommand.new(self, command, type)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def get(key)
|
|
80
|
+
@store[key]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def set(key, value)
|
|
84
|
+
@store[key] = value
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def group
|
|
88
|
+
raise NotImplementedError
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def command
|
|
92
|
+
raise NotImplementedError
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def handle(arguments, console)
|
|
96
|
+
raise NotImplementedError
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def autocomplete(console)
|
|
100
|
+
split = console.text_input.text.split(" ")
|
|
101
|
+
|
|
102
|
+
if @subcommands.size.positive?
|
|
103
|
+
if !console.text_input.text.end_with?(" ") && split.size == 2
|
|
104
|
+
list = console.abbrev_search(@subcommands.map { |cmd| cmd.command.to_s }, split.last)
|
|
105
|
+
|
|
106
|
+
if list.size == 1
|
|
107
|
+
console.text_input.text = "#{split.first} #{list.first} "
|
|
108
|
+
else
|
|
109
|
+
return unless list.size.positive?
|
|
110
|
+
|
|
111
|
+
console.stdin(list.map { |cmd| Console::Style.highlight(cmd) }.join(", ").to_s)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# List available options on subcommand
|
|
115
|
+
elsif (console.text_input.text.end_with?(" ") && split.size == 2) || !console.text_input.text.end_with?(" ") && split.size == 3
|
|
116
|
+
subcommand = @subcommands.detect { |cmd| cmd.command.to_s == (split[1]) }
|
|
117
|
+
|
|
118
|
+
if subcommand
|
|
119
|
+
if split.size == 2
|
|
120
|
+
console.stdin("Available options: #{subcommand.values.map { |value| Console::Style.highlight(value) }.join(',')}")
|
|
121
|
+
else
|
|
122
|
+
list = console.abbrev_search(subcommand.values, split.last)
|
|
123
|
+
if list.size == 1
|
|
124
|
+
console.text_input.text = "#{split.first} #{split[1]} #{list.first} "
|
|
125
|
+
elsif list.size.positive?
|
|
126
|
+
console.stdin("Available options: #{list.map { |value| Console::Style.highlight(value) }.join(',')}")
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# List available subcommands if command was entered and has only a space after it
|
|
132
|
+
elsif console.text_input.text.end_with?(" ") && split.size == 1
|
|
133
|
+
console.stdin("Available subcommands: #{@subcommands.map { |cmd| Console::Style.highlight(cmd.command) }.join(', ')}")
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def handle_subcommand(arguments, console)
|
|
139
|
+
if arguments.size.zero?
|
|
140
|
+
console.stdin(usage)
|
|
141
|
+
return
|
|
142
|
+
end
|
|
143
|
+
subcommand = arguments.delete_at(0)
|
|
144
|
+
|
|
145
|
+
found_command = @subcommands.detect { |cmd| cmd.command == subcommand.to_sym }
|
|
146
|
+
if found_command
|
|
147
|
+
found_command.handle(arguments, console)
|
|
148
|
+
else
|
|
149
|
+
console.stdin("Unknown subcommand #{Style.error(subcommand)} for #{Style.highlight(command)}")
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def usage
|
|
154
|
+
raise NotImplementedError
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
158
|
end
|