cyberarm_engine 0.18.0 → 0.19.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f24458d4ec27a35ff7877afa6e4acdc06d153b8cd161c53063a26282dc14802b
4
- data.tar.gz: baf54b9e08f2f78a75e6db02dfdc6e7ad749f73afb9dfad6260f666f75447fe8
3
+ metadata.gz: c8a871fd51f7fb568600a1668f93f37b2fdc3a077d8e6b7310ff297ff60690df
4
+ data.tar.gz: 80fb6e494d039fb78f03c656159d70f7388dd50673bf6171a27d7b63a973cdef
5
5
  SHA512:
6
- metadata.gz: 6296128b5384912865a96a0e80e176cdc92d853838874507c7eebe5ad86089062ea14fd5a12f0e848fa176047064f4ecf2f68aa1ddddfcc35830e01e688fa164
7
- data.tar.gz: '07386961b8796e2e4d73155c8e44c6c2df6906888609f8424a3cb94f947328356851dc6e72dc2cf26ba3952415c6696cca3c8524963359c6f2b5463c81d5cc18'
6
+ metadata.gz: 9a4f3bddd2d3a146fc6a71496eb0bb8d00c10ce7fddaadd2ab81fa4972471ca47d029b43d141a4c39fca3b2d6c75018b1f97e7925d3a943c88891b0e1e79a30a
7
+ data.tar.gz: 43bc7a87c50e0f56c9cecae84dbb1fc03c45ce3a2e30503b8074c42e0d981cabb1e1eb592a5e4e716d27aeb8ae5952421bd514332699f07a4bb8d894240a6e4b
@@ -43,14 +43,177 @@ module CyberarmEngine
43
43
  Gosu::Color.from_ahsv(alpha, hue, saturation, value)
44
44
  end
45
45
 
46
- # NOTE: Use this for future reference? https://github.com/danro/easing-js/blob/master/easing.js
46
+ # Tween functions based on those provided here: https://github.com/danro/easing-js/blob/master/easing.js
47
+ # Under MIT / BSD
47
48
 
48
49
  def tween_linear(t)
49
50
  t
50
51
  end
51
52
 
52
- def tween_ease_in_out(t)
53
+ def tween_ease_in_quad(t)
54
+ t ** 2
55
+ end
56
+
57
+ def tween_ease_out_quad(t)
58
+ -((t - 1) ** 2) -1
59
+ end
60
+
61
+ def tween_ease_in_out_quad(t)
62
+ return 0.5 * (t ** 2) if (t /= 0.5) < 1
63
+ return -0.5 * ((t -= 2) * t - 2)
64
+ end
65
+
66
+ def tween_ease_in_cubic(t)
67
+ t ** 3
68
+ end
69
+
70
+ def tween_ease_out_cubic(t)
71
+ ((t - 1) ** 3) + 1
72
+ end
73
+
74
+ def tween_ease_in_out_cubic(t)
75
+ return 0.5 * (t ** 3) if ((t /= 0.5) < 1)
76
+ return 0.5 * ((t - 2) ** 3) + 2
77
+ end
78
+
79
+ def tween_ease_in_quart(t)
80
+ t ** 4
81
+ end
82
+
83
+ def tween_ease_out_quart(t)
84
+ -((t - 1) ** 4) - 1
85
+ end
86
+
87
+ def tween_ease_in_out_quart(t)
88
+ return 0.5 * (t ** 4) if ((t /= 0.5) < 1)
89
+ return -0.5 * ((t -= 2) * (t ** 3) - 2)
90
+ end
91
+
92
+ def tween_ease_in_quint(t)
93
+ t ** 5
94
+ end
95
+
96
+ def tween_ease_out_quint(t)
97
+ ((t - 1) ** 5) + 1
98
+ end
99
+
100
+ def tween_ease_in_out_quint(t)
101
+ return 0.5 * (t ** 5) if ((t /= 0.5) < 1)
102
+ return 0.5 * ((t - 2) ** 5) + 2
103
+ end
104
+
105
+ def tween_ease_in(t) # sine
106
+ -Math.cos(t * (Math::PI / 2)) + 1
107
+ end
108
+
109
+ def tween_ease_out(t) # sine
110
+ Math.sin(t * (Math::PI / 2))
111
+ end
112
+
113
+ def tween_ease_in_out(t) # sine
53
114
  (-0.5 * (Math.cos(Math::PI * t) - 1))
54
115
  end
116
+
117
+ def tween_ease_in_expo(t)
118
+ (t == 0) ? 0 : 2 ** 10 * (t - 1)
119
+ end
120
+
121
+ def tween_ease_out_expo(t)
122
+ (t == 1) ? 1 : -(2 ** -10 * t) + 1
123
+ end
124
+
125
+ def tween_ease_in_out_expo(t)
126
+ return 0 if (t == 0)
127
+ return 1 if (t == 1)
128
+ return 0.5 * (2 ** 10 * (t - 1)) if ((t /= 0.5) < 1)
129
+ return 0.5 * (-(2 ** -10 * (t -= 1)) + 2)
130
+ end
131
+
132
+ def tween_ease_in_circ(t)
133
+ -(Math.sqrt(1 - (t * t)) - 1)
134
+ end
135
+
136
+ def tween_ease_out_circ(t)
137
+ Math.sqrt(1 - ((t - 1) ** 2))
138
+ end
139
+
140
+ def tween_ease_in_out_circ(t)
141
+ return -0.5 * (Math.sqrt(1 - t * t) - 1) if ((t /= 0.5) < 1)
142
+ return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1)
143
+ end
144
+
145
+ def tween_ease_in_back(t)
146
+ s = 1.70158
147
+ t * t * ((s + 1) * t - s)
148
+ end
149
+
150
+ def tween_ease_out_back(t)
151
+ s = 1.70158
152
+ (t = t - 1) * t * ((s + 1) * t + s) + 1
153
+ end
154
+
155
+ def tween_ease_in_out_back(t)
156
+ s = 1.70158
157
+ return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)) if ((t /= 0.5) < 1)
158
+ return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2)
159
+ end
160
+
161
+ def tween_elastic(t)
162
+ -1 * (4 ** (-8 * t)) * Math.sin((t * 6 - 1) * (2 * Math::PI) / 2) + 1
163
+ end
164
+
165
+ def tween_swing_from_to(t)
166
+ s = 1.70158
167
+ return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)) if (t /= 0.5) < 1
168
+ return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2)
169
+ end
170
+
171
+ def tween_swing_from(t)
172
+ s = 1.70158;
173
+ t * t * ((s + 1) * t - s)
174
+ end
175
+
176
+ def tween_swing_to(t)
177
+ s = 1.70158
178
+ (t -= 1) * t * ((s + 1) * t + s) + 1
179
+ end
180
+
181
+ def tween_bounce(t)
182
+ if (t < (1 / 2.75))
183
+ (7.5625 * t * t)
184
+ elsif (t < (2 / 2.75))
185
+ (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75)
186
+ elsif (t < (2.5 / 2.75))
187
+ (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375)
188
+ else
189
+ (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375)
190
+ end
191
+ end
192
+
193
+ def tween_bounce_past(t)
194
+ if (t < (1 / 2.75))
195
+ # missing "2 -"?
196
+ (7.5625 * t * t)
197
+ elsif (t < (2 / 2.75))
198
+ 2 - (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75)
199
+ elsif (t < (2.5 / 2.75))
200
+ 2 - (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375)
201
+ else
202
+ 2 - (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375)
203
+ end
204
+ end
205
+
206
+ def tween_ease_from_to(t)
207
+ return 0.5 * (t ** 4) if ((t /= 0.5) < 1)
208
+ return -0.5 * ((t -= 2) * (t ** 3) - 2)
209
+ end
210
+
211
+ def tween_ease_from(t)
212
+ t ** 4
213
+ end
214
+
215
+ def tween_ease_to(t)
216
+ t ** 0.25
217
+ end
55
218
  end
56
219
  end
@@ -1,10 +1,11 @@
1
1
  module CyberarmEngine
2
2
  class BackgroundNineSlice
3
3
  include CyberarmEngine::Common
4
- attr_accessor :x, :y, :z, :width, :height
4
+ attr_accessor :x, :y, :z, :width, :height, :left, :top, :right, :bottom, :mode, :color
5
+ attr_reader :image
5
6
 
6
- def initialize(image_path:, x: 0, y: 0, z: 0, width: 64, height: 64, mode: :tiled, left: 4, top: 4, right: 56, bottom: 56)
7
- @image = get_image(image_path)
7
+ def initialize(image_path: nil, x: 0, y: 0, z: 0, width: 0, height: 0, mode: :tiled, left: 1, top: 1, right: 1, bottom: 1, color: Gosu::Color::WHITE)
8
+ @image = get_image(image_path) if image_path
8
9
 
9
10
  @x = x
10
11
  @y = y
@@ -20,23 +21,33 @@ module CyberarmEngine
20
21
  @right = right
21
22
  @bottom = bottom
22
23
 
23
- nine_slice
24
+ @color = color
25
+
26
+ nine_slice if @image
27
+ end
28
+
29
+ def image=(image_path)
30
+ old_image = @image
31
+ @image = image_path ? get_image(image_path) : image_path
32
+ nine_slice if @image && old_image != @image
24
33
  end
25
34
 
26
35
  def nine_slice
27
- @segment_top_left = Gosu.render(@left, @top) { @image.draw(0, 0, 0) }
28
- @segment_top_right = Gosu.render(@image.width - @right, @top) { @image.draw(-@right, 0, 0) }
36
+ # pp [@left, @top, @right, @bottom, @image.width]
29
37
 
30
- @segment_left = Gosu.render(@left, @bottom - @top) { @image.draw(0, -@top, 0) }
31
- @segment_right = Gosu.render(@image.width - @right, @bottom - @top) { @image.draw(-@right, -@top, 0) }
38
+ @segment_top_left = @image.subimage(0, 0, @left, @top)
39
+ @segment_top_right = @image.subimage(@image.width - @right, 0, @right, @top)
32
40
 
33
- @segment_bottom_left = Gosu.render(@left, @image.height - @bottom) { @image.draw(0, -@bottom, 0) }
34
- @segment_bottom_right = Gosu.render(@image.width - @right, @image.height - @bottom) { @image.draw(-@right, -@bottom, 0) }
41
+ @segment_left = @image.subimage(0, @top, @left, @image.height - (@top + @bottom))
42
+ @segment_right = @image.subimage(@image.width - @right, @top, @left, @image.height - (@top + @bottom))
35
43
 
36
- @segment_top = Gosu.render(@right - @left, @top) { @image.draw(-@left, 0, 0) }
37
- @segment_bottom = Gosu.render(@right - @left, @image.height - @bottom) { @image.draw(-@left, -@bottom, 0) }
44
+ @segment_bottom_left = @image.subimage(0, @image.height - @bottom, @left, @bottom)
45
+ @segment_bottom_right = @image.subimage(@image.width - @right, @image.height - @bottom, @right, @bottom)
38
46
 
39
- @segment_middle = Gosu.render(@right - @left, @bottom - @top) { @image.draw(-@left, -@top, 0) }
47
+ @segment_top = @image.subimage(@left, 0, @image.width - (@left + @right), @top)
48
+ @segment_bottom = @image.subimage(@left, @image.height - @bottom, @image.width - (@left + @right), @bottom)
49
+
50
+ @segment_middle = @image.subimage(@left, @top, @image.width - (@left + @right), @image.height - (@top + @bottom))
40
51
  end
41
52
 
42
53
  def cx
@@ -56,67 +67,73 @@ module CyberarmEngine
56
67
  end
57
68
 
58
69
  def width_scale
59
- width_scale = (@width - (@left + (@image.width - @right))).to_f / (@right - @left)
70
+ scale = (@width.to_f - (@left + @right)) / (@image.width - (@left + @right))
71
+ scale.abs
60
72
  end
61
73
 
62
74
  def height_scale
63
- height_scale = (@height - (@top + (@image.height - @bottom))).to_f / (@bottom - @top)
75
+ scale = (@height - (@top + @bottom)).to_f / (@image.height - (@top + @bottom))
76
+ scale.abs
64
77
  end
65
78
 
66
79
  def draw
80
+ return unless @image && @segment_top_left
81
+
67
82
  @mode == :tiled ? draw_tiled : draw_stretched
68
83
  end
69
84
 
70
85
  def draw_stretched
71
- @segment_top_left.draw(@x, @y, @z)
72
- @segment_top.draw(@x + @segment_top_left.width, @y, @z, width_scale) # SCALE X
73
- @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z)
74
-
75
- @segment_right.draw((@x + @width) - @segment_right.width, @y + @top, @z, 1, height_scale) # SCALE Y
76
- @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z)
77
- @segment_bottom.draw(@x + @segment_bottom_left.width, (@y + @height) - @segment_bottom.height, @z, width_scale) # SCALE X
78
- @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z)
79
- @segment_left.draw(@x, @y + @top, @z, 1, height_scale) # SCALE Y
80
- @segment_middle.draw(@x + @segment_top_left.width, @y + @segment_top.height, @z, width_scale, height_scale) # SCALE X and SCALE Y
86
+ @segment_top_left.draw(@x, @y, @z, 1, 1, @color)
87
+ @segment_top.draw(@x + @segment_top_left.width, @y, @z, width_scale, 1, @color) # SCALE X
88
+ @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color)
89
+
90
+ @segment_right.draw((@x + @width) - @segment_right.width, @y + @top, @z, 1, height_scale, @color) # SCALE Y
91
+ @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color)
92
+ @segment_bottom.draw(@x + @segment_bottom_left.width, (@y + @height) - @segment_bottom.height, @z, width_scale, 1, @color) # SCALE X
93
+ @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color)
94
+ @segment_left.draw(@x, @y + @top, @z, 1, height_scale, @color) # SCALE Y
95
+ @segment_middle.draw(@x + @segment_top_left.width, @y + @segment_top.height, @z, width_scale, height_scale, @color) # SCALE X and SCALE Y
81
96
  end
82
97
 
83
98
  def draw_tiled
84
- @segment_top_left.draw(@x, @y, @z)
99
+ @segment_top_left.draw(@x, @y, @z, 1, 1, @color)
100
+
101
+ # p [width_scale, height_scale]
85
102
 
86
103
  Gosu.clip_to(@x + @segment_top_left.width, @y, @segment_top.width * width_scale, @segment_top.height) do
87
104
  width_scale.ceil.times do |i|
88
- @segment_top.draw(@x + @segment_top_left.width + (@segment_top.width * i), @y, @z) # SCALE X
105
+ @segment_top.draw(@x + @segment_top_left.width + (@segment_top.width * i), @y, @z, 1, 1, @color) # SCALE X
89
106
  end
90
107
  end
91
108
 
92
- @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z)
109
+ @segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color)
93
110
 
94
111
  Gosu.clip_to(@x + @width - @segment_top_right.width, @y + @top, @segment_right.width, @segment_right.height * height_scale) do
95
112
  height_scale.ceil.times do |i|
96
- @segment_right.draw((@x + @width) - @segment_right.width, @y + @top + (@segment_right.height * i), @z) # SCALE Y
113
+ @segment_right.draw((@x + @width) - @segment_right.width, @y + @top + (@segment_right.height * i), @z, 1, 1, @color) # SCALE Y
97
114
  end
98
115
  end
99
116
 
100
- @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z)
117
+ @segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color)
101
118
 
102
119
  Gosu.clip_to(@x + @segment_top_left.width, @y + @height - @segment_bottom.height, @segment_top.width * width_scale, @segment_bottom.height) do
103
120
  width_scale.ceil.times do |i|
104
- @segment_bottom.draw(@x + @segment_bottom_left.width + (@segment_bottom.width * i), (@y + @height) - @segment_bottom.height, @z) # SCALE X
121
+ @segment_bottom.draw(@x + @segment_bottom_left.width + (@segment_bottom.width * i), (@y + @height) - @segment_bottom.height, @z, 1, 1, @color) # SCALE X
105
122
  end
106
123
  end
107
124
 
108
- @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z)
125
+ @segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color)
109
126
 
110
127
  Gosu.clip_to(@x, @y + @top, @segment_left.width, @segment_left.height * height_scale) do
111
128
  height_scale.ceil.times do |i|
112
- @segment_left.draw(@x, @y + @top + (@segment_left.height * i), @z) # SCALE Y
129
+ @segment_left.draw(@x, @y + @top + (@segment_left.height * i), @z, 1, 1, @color) # SCALE Y
113
130
  end
114
131
  end
115
132
 
116
133
  Gosu.clip_to(@x + @segment_top_left.width, @y + @segment_top.height, @width - (@segment_left.width + @segment_right.width), @height - (@segment_top.height + @segment_bottom.height)) do
117
134
  height_scale.ceil.times do |y|
118
135
  width_scale.ceil.times do |x|
119
- @segment_middle.draw(@x + @segment_top_left.width + (@segment_middle.width * x), @y + @segment_top.height + (@segment_middle.height * y), @z) # SCALE X and SCALE Y
136
+ @segment_middle.draw(@x + @segment_top_left.width + (@segment_middle.width * x), @y + @segment_top.height + (@segment_middle.height * y), @z, 1, 1, @color) # SCALE X and SCALE Y
120
137
  end
121
138
  end
122
139
  end
@@ -22,18 +22,19 @@ module CyberarmEngine
22
22
 
23
23
  base_time = Gosu.milliseconds
24
24
 
25
+ @born_time = Gosu.milliseconds
26
+ @continue_after = 5_000
27
+
25
28
  @animators = [
26
29
  Animator.new(start_time: base_time += 1000, duration: 100, from: 0.0, to: 1.0, tween: :ease_in_out),
27
30
  Animator.new(start_time: base_time += -500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
28
31
  Animator.new(start_time: base_time += 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
29
32
  Animator.new(start_time: base_time += 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
30
33
  Animator.new(start_time: base_time + 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
34
+ Animator.new(start_time: Gosu.milliseconds + @continue_after - 1_000, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out),
31
35
 
32
- Animator.new(start_time: Gosu.milliseconds + 250, duration: 500, from: 0.0, to: 1.0, tween: :ease_in_out) # CyberarmEngine LOGO
36
+ Animator.new(start_time: Gosu.milliseconds + 250, duration: 500, from: 0.0, to: 1.0, tween: :swing_to) # CyberarmEngine LOGO
33
37
  ]
34
-
35
- @born_time = Gosu.milliseconds
36
- @continue_after = 5_000
37
38
  end
38
39
 
39
40
  def draw
@@ -60,7 +61,7 @@ module CyberarmEngine
60
61
  Gosu::Color::WHITE
61
62
  )
62
63
 
63
- @title.x = window.width / 2 - @title.width / 2
64
+ @title.x = window.width / 2 - @title.text_width / 2
64
65
  @title.y = (window.height / 2 + (@spacer_height / 2) + @padding) * @animators[1].transition
65
66
  @title.text = "Powered By"
66
67
 
@@ -89,6 +90,8 @@ module CyberarmEngine
89
90
  )
90
91
  end
91
92
  end
93
+
94
+ Gosu.draw_rect(0, 0, window.width, window.height, Gosu::Color.rgba(0, 0, 0, 255 * @animators[5].transition), 10_000)
92
95
  end
93
96
 
94
97
  def update
@@ -112,14 +115,14 @@ module CyberarmEngine
112
115
  height = @title_size + @caption_size + @spacer_height + 2 * @padding + @spacer_height
113
116
 
114
117
  Gosu.record(width.ceil, height.ceil) do
115
- @title.x = (width - @padding * 2) / 2 - @title.width / 2
118
+ @title.x = (width - @padding * 2) / 2 - @title.text_width / 2
116
119
  @title.y = @padding
117
120
  @title.draw
118
121
 
119
122
  Gosu.draw_rect(0, @padding + @title_size + @padding, @spacer_width, @spacer_height, Gosu::Color::WHITE)
120
123
  Gosu.draw_rect(1, @padding + @title_size + @padding + 1, @spacer_width - 2, @spacer_height - 2, color_hint)
121
124
 
122
- @caption.x = (width - @padding * 2) / 2 - @caption.width / 2
125
+ @caption.x = (width - @padding * 2) / 2 - @caption.text_width / 2
123
126
  @caption.y = @padding + @title_size + @padding + @spacer_height + @padding
124
127
  @caption.draw
125
128
  end
@@ -28,8 +28,8 @@ module CyberarmEngine
28
28
  window.show_cursor = boolean
29
29
  end
30
30
 
31
- def draw_rect(x, y, width, height, color, z = 0)
32
- Gosu.draw_rect(x, y, width, height, color, z)
31
+ def draw_rect(x, y, width, height, color, z = 0, mode = :default)
32
+ Gosu.draw_rect(x, y, width, height, color, z, mode)
33
33
  end
34
34
 
35
35
  def fill(color, z = 0)
@@ -97,5 +97,17 @@ module CyberarmEngine
97
97
  def window
98
98
  $window
99
99
  end
100
+
101
+ def control_down?
102
+ Gosu.button_down?(Gosu::KB_LEFT_CONTROL) || Gosu.button_down?(Gosu::KB_RIGHT_CONTROL)
103
+ end
104
+
105
+ def shift_down?
106
+ Gosu.button_down?(Gosu::KB_LEFT_SHIFT) || Gosu.button_down?(Gosu::KB_RIGHT_SHIFT)
107
+ end
108
+
109
+ def alt_down?
110
+ Gosu.button_down?(Gosu::KB_LEFT_ALT) || Gosu.button_down?(Gosu::KB_RIGHT_ALT)
111
+ end
100
112
  end
101
113
  end
@@ -0,0 +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
158
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CyberarmEngine
4
+ class Console
5
+ class HelpCommand < CyberarmEngine::Console::Command
6
+ def group
7
+ :global
8
+ end
9
+
10
+ def command
11
+ :help
12
+ end
13
+
14
+ def handle(arguments, console)
15
+ console.stdin(usage(arguments.first))
16
+ end
17
+
18
+ def autocomplete(console)
19
+ split = console.text_input.text.split(" ")
20
+ if !console.text_input.text.start_with?(" ") && split.size == 2
21
+ list = console.abbrev_search(Command.list_commands.map { |cmd| cmd.command.to_s }, split.last)
22
+ if list.size == 1
23
+ console.text_input.text = "#{split.first} #{list.first} "
24
+ elsif list.size > 1
25
+ console.stdin(list.map { |cmd| Style.highlight(cmd) }.join(", "))
26
+ end
27
+ end
28
+ end
29
+
30
+ def usage(command = nil)
31
+ if command
32
+ if cmd = Command.find(command)
33
+ cmd.usage
34
+ else
35
+ "#{Style.error(command)} is not a command"
36
+ end
37
+ else
38
+ "Available commands:\n#{Command.list_commands.map { |cmd| Style.highlight(cmd.command).to_s }.join(', ')}"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end