empi 0.21 → 0.25

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.
@@ -0,0 +1,56 @@
1
+ require_relative './../game_states/set_state'
2
+
3
+ TILE_SEA = 0
4
+ TILE_GROUND = 1
5
+
6
+ SYMBOL_SEA = '.'
7
+ SYMBOL_GROUND = '#'
8
+
9
+ class Tile
10
+ attr_accessor :terrain, :infopane, :unit
11
+
12
+ def initialize(x, y, loaded_symbol, infopane)
13
+ dir_path = File.dirname(__FILE__)
14
+
15
+ @x = x
16
+ @y = y
17
+ @infopane = infopane
18
+
19
+ case(loaded_symbol)
20
+ when SYMBOL_SEA then
21
+ @terrain = TILE_SEA
22
+ @image = Gosu::Image.new(dir_path + '/../../media/sea.png')
23
+ when SYMBOL_GROUND then
24
+ @terrain = TILE_GROUND
25
+ @image = Gosu::Image.new(dir_path + '/../../media/ground.png')
26
+ else
27
+ abort("Tile.initialize(): Unknown terrain symbol (#{loaded_symbol})")
28
+ end
29
+ end
30
+
31
+ def draw
32
+ # 1) terrain
33
+ @image.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZTILE)
34
+
35
+ # 2) unit
36
+ if @unit
37
+ @unit.draw
38
+ end
39
+
40
+ # 3) axes
41
+ draw_axis_tick(@x, @y, 0) if SetState.instance.settings['axis_top'] # TODO 0 -> viewport.y
42
+ draw_axis_tick(@x, @y, MAPY) if SetState.instance.settings['axis_bottom']
43
+ draw_axis_tick(@y, @x, 0) if SetState.instance.settings['axis_left'] # TODO 0 -> viewport.x
44
+ draw_axis_tick(@y, @x, MAPX) if SetState.instance.settings['axis_right']
45
+ end
46
+
47
+ # Draw one tick of axis for appropriate tiles
48
+ def draw_axis_tick(draw_coord, test_coord, test_against)
49
+ # TODO appropriatness can be changed (show axes: no/top/left/bottom/right)
50
+ if test_coord == test_against
51
+ tick = Gosu::Image.from_text(draw_coord, 20)
52
+ tick.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZTEXT)
53
+ # ^^ TODO substract test_against of viewport from @x and @y here?
54
+ end
55
+ end
56
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: empi
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.21'
4
+ version: '0.25'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Detros
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-13 00:00:00.000000000 Z
11
+ date: 2021-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gosu
@@ -38,22 +38,32 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
- description: 'Empi: Ruby Edition is a turn based wargame, currently deep in development.
42
- While learning Ruby I have found there are hardly any strategic games avaiable.
43
- So this should be Ruby version of Classic Empire, wargame from old times.'
41
+ description: |-
42
+ Empi: Ruby Edition is a turn-based wargame with hotseat
43
+ multiplayer, currently in alpha development state. The game is inspired by
44
+ Classic Empire, originally from 1977.
44
45
  email: rasunadon@seznam.cz
45
46
  executables: []
46
47
  extensions: []
47
48
  extra_rdoc_files: []
48
49
  files:
49
- - lib/army.rb
50
- - lib/build_state.rb
51
- - lib/cursor.rb
52
50
  - lib/empi.rb
53
- - lib/escape_state.rb
54
- - lib/game_state.rb
55
- - lib/infopane.rb
56
- - lib/map.rb
51
+ - lib/lib/game_states/build_state.rb
52
+ - lib/lib/game_states/game_state.rb
53
+ - lib/lib/game_states/play_state.rb
54
+ - lib/lib/game_states/quit_state.rb
55
+ - lib/lib/game_states/set_state.rb
56
+ - lib/lib/game_states/welcome_state.rb
57
+ - lib/lib/game_states/win_state.rb
58
+ - lib/lib/units/army.rb
59
+ - lib/lib/units/ship.rb
60
+ - lib/lib/units/town.rb
61
+ - lib/lib/units/unit.rb
62
+ - lib/lib/units/unit_function.rb
63
+ - lib/lib/user_interface/cursor.rb
64
+ - lib/lib/user_interface/infopane.rb
65
+ - lib/lib/user_interface/map.rb
66
+ - lib/lib/user_interface/tile.rb
57
67
  - lib/media/Empi v18.png
58
68
  - lib/media/army.png
59
69
  - lib/media/cursor.png
@@ -61,16 +71,10 @@ files:
61
71
  - lib/media/sea.png
62
72
  - lib/media/ship.png
63
73
  - lib/media/town.png
64
- - lib/play_state.rb
65
74
  - lib/save/m01.esf
66
75
  - lib/save/m02-err.esf
67
76
  - lib/save/m02.esf
68
77
  - lib/save/m03.esf
69
- - lib/ship.rb
70
- - lib/tile.rb
71
- - lib/town.rb
72
- - lib/unit.rb
73
- - lib/unitFunction.rb
74
78
  homepage: http://www.bay12forums.com/smf/index.php?topic=157538
75
79
  licenses:
76
80
  - CC-BY-SA-3.0
@@ -99,5 +103,5 @@ rubyforge_project:
99
103
  rubygems_version: 2.7.6
100
104
  signing_key:
101
105
  specification_version: 4
102
- summary: Turn-based wargame
106
+ summary: A turn-based wargame
103
107
  test_files: []
data/lib/build_state.rb DELETED
@@ -1,54 +0,0 @@
1
- require 'singleton'
2
-
3
- require_relative './game_state'
4
- require_relative './play_state'
5
-
6
- require_relative './army'
7
- require_relative './ship'
8
-
9
- # Game state of closing the game window
10
- class BuildState < GameState
11
- include Singleton
12
-
13
- attr_accessor :unit
14
-
15
- # What to do just after state gets activated
16
- #def after_start
17
- #end
18
-
19
- # What to do just before state gets deactivated
20
- #def before_end
21
- # TODO hide question?
22
- #end
23
-
24
- # Process given button to cursor
25
- def update(button)
26
- project = nil
27
-
28
- case(button)
29
- when Gosu::KbN, Gosu::KbEscape then
30
- puts PROMPT + @unit.to_s + ": no project selected, resetting function"
31
- @unit.set_function!(FUNCNONE)
32
- GameState.switch!(PlayState.instance)
33
- when Gosu::Kb1, Gosu::KbA then
34
- project = Army
35
- when Gosu::Kb2, Gosu::KbS then
36
- project = Ship
37
- end
38
-
39
- # Did we get any proper answer?
40
- if project
41
- @unit.set_project!(project)
42
- GameState.switch!(PlayState.instance)
43
- end
44
- end
45
-
46
- def draw
47
- build_project = Gosu::Image.from_text(
48
- "Select the project for " + @unit.to_s + ":\n
49
- 1, A – Army (3 turns)\n
50
- 2, S – Ship (5 turns)\n\n
51
- N, Esc – none\n", 20)
52
- build_project.draw((2*TILESIZE) + XTEXT, (3*TILESIZE) + YTEXT, ZTEXT)
53
- end
54
- end
data/lib/cursor.rb DELETED
@@ -1,167 +0,0 @@
1
- class Cursor
2
- attr_accessor :x, :y, :freeroam, :unit
3
-
4
- def initialize(x, y, map, infopane)
5
- dir_path = File.dirname(__FILE__)
6
-
7
- @x = x
8
- @y = y
9
- @map = map
10
- @infopane = infopane
11
-
12
- @image = Gosu::Image.new(dir_path + '/media/cursor.png')
13
- @freeroam = false
14
- end
15
-
16
- def update(button)
17
- case button
18
- # Cardinal directions
19
- when Gosu::KbLeft, Gosu::KbA, Gosu::KB_NUMPAD_4 then
20
- move!(-1, 0) unless @x <= 0
21
- when Gosu::KbRight, Gosu::KbD, Gosu::KB_NUMPAD_6 then
22
- move!(1, 0) unless @x >= MAPX
23
- when Gosu::KbUp, Gosu::KbW, Gosu::KB_NUMPAD_8 then
24
- move!(0, -1) unless @y <= 0
25
- when Gosu::KbDown, Gosu::KbX, Gosu::KB_NUMPAD_2 then
26
- move!(0, 1) unless @y >= MAPY
27
-
28
- # Intercardinal directions
29
- when Gosu::KbQ, Gosu::KB_NUMPAD_7 then
30
- move!(-1, -1) unless @x <= 0 || @y <= 0
31
- when Gosu::KbE, Gosu::KB_NUMPAD_9 then
32
- move!(1, -1) unless @x >= MAPX || @y <= 0
33
- when Gosu::KbZ, Gosu::KB_NUMPAD_1 then
34
- move!(-1, 1) unless @x <= 0 || @y >= MAPY
35
- when Gosu::KbC, Gosu::KB_NUMPAD_3 then
36
- move!(1, 1) unless @x >= MAPX || @y >= MAPY
37
-
38
- # Functions
39
- when Gosu::KbS then
40
- set_function_to_unit(FUNCSENTRY)
41
- when Gosu::KbB then
42
- set_function_to_unit(FUNCBUILD)
43
- when Gosu::KbN then
44
- set_function_to_unit(FUNCNONE)
45
-
46
- # The rest
47
- when Gosu::KbJ, Gosu::KB_NUMPAD_0 then
48
- switch_freeroam!
49
- when Gosu::KbReturn, Gosu::KB_NUMPAD_5 then
50
- info
51
- end
52
-
53
- # If in locked mode, stay at current/jump to next movable unit
54
- to_next_unit! unless freeroam
55
- end
56
-
57
- def draw
58
- @image.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZCURSOR)
59
- end
60
-
61
- # Move to coordinates of given unit
62
- def warp_to!(uu)
63
- @x = uu.x
64
- @y = uu.y
65
- @unit = uu
66
- end
67
-
68
- # Move by given change of coordinates
69
- def move!(xx, yy)
70
- if freeroam
71
- @x += xx
72
- @y += yy
73
- @unit = @map.get_unit(@x, @y)
74
- return
75
- end
76
-
77
- # If in locked mode
78
- if !@unit
79
- abort("cursor.move!(): Cursor is in locked mode but there is no unit it is locked to (at #{@x} - #{@y})")
80
- end
81
-
82
- @unit.x += xx
83
- @unit.y += yy
84
- @unit.check_movement(@x, @y) # cursor coordinates work like old_x, old_y
85
-
86
- uu = @map.get_unit(@unit.x, @unit.y)
87
- if !uu # it got destroyed
88
- @unit = nil # clear the last links so that (object of) given unit can be truly destroyed
89
- return
90
- end
91
-
92
- warp_to!(@unit) # whether it moved or not, unless it got destroyed
93
- end
94
-
95
- # Tries to set function <func> to currently selected unit
96
- def set_function_to_unit(func)
97
- if freeroam
98
- uu = @map.get_unit(@x, @y)
99
- else # in locked mode
100
- if !@unit
101
- abort("cursor.set_function_to_unit(): Cursor is in locked mode but there is no unit it is locked to (at #{@x} - #{@y})")
102
- end
103
- uu = @unit
104
- end
105
-
106
- uu.set_function!(func) unless !uu
107
- end
108
-
109
- # Find next unit to target with cursor
110
- def to_next_unit!
111
- unless @unit && @unit.can_move? && @unit.function == FUNCNONE # unless the current one is still movable
112
- movable_units = @map.all_units.select { |uu| uu.can_move? && uu.function == FUNCNONE}
113
-
114
- # If there are no more movable units without function, switch to freeroam mode
115
- if movable_units.size <= 0 # == would be enough
116
- puts 'all movable units without functions moved'
117
-
118
- switch_freeroam!
119
- return
120
- end
121
-
122
- @unit = movable_units[0] # newly selected one
123
- end
124
-
125
- warp_to!(@unit) # stay at old or go to new
126
- info
127
- end
128
-
129
- # Switch between being attached to unit and being able to freeroam
130
- def switch_freeroam!
131
- if freeroam
132
- @infopane.text = 'freeroam disabled'
133
- puts 'freeroam disabled'
134
- @freeroam = false
135
- to_next_unit!
136
- else
137
- @infopane.text = 'freeroam enabled'
138
- puts 'freeroam enabled'
139
- @freeroam = true
140
- @unit = nil
141
- end
142
- end
143
-
144
- # Find some info about units on the current tile
145
- def info
146
- if freeroam
147
- uu = @map.get_unit(@x, @y)
148
- else
149
- if !@unit
150
- abort("cursor.info(): Cursor is in locked mode but there is no unit it is locked to (at #{@x} - #{@y})")
151
- end
152
- uu = @unit
153
- end
154
-
155
- if uu
156
- @infopane.text = uu.info
157
- puts uu.info
158
-
159
- if uu.is_transporting?
160
- uu.cargo.each { |uu| puts '- cargo: ' + uu.info }
161
- end
162
- else
163
- @infopane.text = ''
164
- puts 'nothing here'
165
- end
166
- end
167
- end
data/lib/infopane.rb DELETED
@@ -1,38 +0,0 @@
1
- LINE_HEIGHT = 20
2
-
3
- # Score, turn and event texts
4
- class Infopane
5
- attr_writer :text, :act_fact
6
-
7
- def initialize
8
- @score = [0, 0]
9
- @turn = 0
10
- @act_fact = 0 # active faction
11
- @text = 'ready'
12
- end
13
-
14
- def update
15
- end
16
-
17
- def draw
18
- turnscore = Gosu::Image.from_text(
19
- "Turn: #{@turn}, Score: #{@score[0]} - #{@score[1]}", LINE_HEIGHT)
20
- turnscore.draw(XTEXT, YTEXT, ZTEXT)
21
-
22
- text = Gosu::Image.from_text("#{@text}", LINE_HEIGHT)
23
- text.draw(XTEXT, (TILESIZE / 2) + YTEXT, ZTEXT)
24
- end
25
-
26
- def next_faction
27
- # TODO active faction switching
28
- end
29
-
30
- def next_turn
31
- @turn += 1
32
- puts "Turn: #{@turn}, Score: #{@score[0]} - #{@score[1]}"
33
- end
34
-
35
- def add_score(to_whom, how_much)
36
- @score[to_whom] += how_much
37
- end
38
- end
data/lib/map.rb DELETED
@@ -1,153 +0,0 @@
1
- require_relative './army'
2
- require_relative './ship'
3
- require_relative './tile'
4
- require_relative './town'
5
-
6
- class Map
7
- attr_accessor :name, :mapx, :mapy, :infopane
8
-
9
- def initialize(infopane)
10
- dir_path = File.dirname(__FILE__)
11
-
12
- @infopane = infopane
13
- @known_unit_types = Hash[
14
- [Army, Ship, Town].collect { |ii| [ii.map_symbol, ii] }
15
- ]
16
-
17
- # TODO selectable starting scenario
18
- load_map(dir_path + '/save/m02.esf')
19
- end
20
-
21
- # Load map from file
22
- def load_map(filename)
23
- input = File.open(filename, 'r')
24
- unit_count = load_head(input.gets)
25
-
26
- # Load tiles
27
- @tiles = []
28
- 0.upto(@mapy - 1) { |rr|
29
- @tiles[rr] = []
30
- map_row = input.gets
31
- 0.upto(@mapx - 1) { |cc|
32
- @tiles[rr][cc] = Tile.new(cc, rr, map_row[cc], @infopane)
33
- }
34
- }
35
-
36
- # Load units
37
- unit_count.times { load_unit(input.gets) }
38
-
39
- puts("Save loaded: #{@name} with #{unit_count} units")
40
- input.close
41
- end
42
-
43
- # Load core info from given head row of file
44
- # Return number of units to be loaded
45
- def load_head(row)
46
- head = []
47
- size = []
48
-
49
- head = row.split(' ')
50
- size = head[1].split('x')
51
-
52
- @name = head[0]
53
- @mapx = size[0].to_i
54
- @mapy = size[1].to_i
55
-
56
- head[2].to_i # unit_count
57
- end
58
-
59
- # Load one unit from given row
60
- def load_unit(row)
61
- unit = []
62
- coords = []
63
-
64
- unit = row.split(' ')
65
-
66
- # Check coordinates
67
- coords = unit[2].split('-')
68
- coords_x = coords[0].to_i
69
- coords_y = coords[1].to_i
70
- if (coords_x < 0 || coords_x >= @mapx ||
71
- coords_y < 0 || coords_y >= @mapy)
72
- abort("map.load_unit(): Unit out of map borders (#{coords_x}-#{coords_y})")
73
- end
74
-
75
- # Check faction
76
- fac = unit[1].to_i
77
- if(fac < 0 || fac > FACTIONS)
78
- abort("map.load_unit(): Bad faction id (#{fac})")
79
- end
80
-
81
- # Create unit
82
- unit_type = unit[0]
83
- if @known_unit_types.include?(unit_type)
84
- @known_unit_types[unit_type].new(coords_x, coords_y, fac, self, @infopane)
85
- else
86
- abort("map.load_unit(): Unknown unit type symbol (#{unit_type})")
87
- end
88
- end
89
-
90
- # Draw all tiles
91
- def draw_tiles
92
- all_tiles.each { |tt| tt.draw}
93
- end
94
-
95
- # Getter for tile at given coordinates
96
- def tile(cc, rr)
97
- @tiles[rr][cc]
98
- end
99
-
100
- # Return all tiles
101
- def all_tiles
102
- ret = []
103
- ii = 0
104
- 0.upto(MAPX) { |rr|
105
- 0.upto(MAPX) { |cc|
106
- ret[ii] = @tiles[rr][cc]
107
- ii += 1
108
- }
109
- }
110
- ret
111
- end
112
-
113
- # Getter for unit at given coordinates
114
- def get_unit(cc, rr)
115
- @tiles[rr][cc].unit
116
- end
117
-
118
- # Setter for unit at given coordinates
119
- def set_unit(cc, rr, uu)
120
- @tiles[rr][cc].unit = uu
121
- end
122
-
123
- # Return both map units and transported units
124
- def all_units
125
- all_map_units + all_transported_units
126
- end
127
-
128
- # Return only units directly on map
129
- def all_map_units
130
- ret = []
131
- ii = 0
132
- 0.upto(MAPX) { |rr|
133
- 0.upto(MAPX) { |cc|
134
- if get_unit(cc, rr)
135
- ret[ii] = get_unit(cc, rr)
136
- ii += 1
137
- end
138
- }
139
- }
140
- ret
141
- end
142
-
143
- # Return only units transported by other units
144
- def all_transported_units
145
- ret = []
146
- all_map_units.each { |uu|
147
- if uu.is_transporting?
148
- ret += uu.cargo
149
- end
150
- }
151
- ret
152
- end
153
- end