empi 0.21 → 0.25

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