empi 0.19 → 0.24
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/lib/empi.rb +22 -75
- data/lib/lib/game_states/build_state.rb +68 -0
- data/lib/lib/game_states/game_state.rb +27 -0
- data/lib/lib/game_states/play_state.rb +135 -0
- data/lib/lib/game_states/quit_state.rb +33 -0
- data/lib/lib/game_states/welcome_state.rb +64 -0
- data/lib/{army.rb → lib/units/army.rb} +7 -4
- data/lib/{ship.rb → lib/units/ship.rb} +7 -4
- data/lib/lib/units/town.rb +108 -0
- data/lib/{unit.rb → lib/units/unit.rb} +66 -41
- data/lib/{unitFunction.rb → lib/units/unitFunction.rb} +15 -6
- data/lib/lib/user_interface/cursor.rb +190 -0
- data/lib/lib/user_interface/infopane.rb +49 -0
- data/lib/{map.rb → lib/user_interface/map.rb} +31 -25
- data/lib/lib/user_interface/tile.rb +52 -0
- data/lib/docu/Empi v18.png b/data/lib/media/Empi → v18.png +0 -0
- metadata +30 -20
- data/lib/cursor.rb +0 -166
- data/lib/docu/info.txt +0 -372
- data/lib/infopane.rb +0 -36
- data/lib/tile.rb +0 -36
- data/lib/town.rb +0 -77
@@ -0,0 +1,49 @@
|
|
1
|
+
LINE_HEIGHT = 20
|
2
|
+
|
3
|
+
# Score, turn and event texts
|
4
|
+
class Infopane
|
5
|
+
attr_reader :faction
|
6
|
+
attr_writer :cursor, :text
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@turn = 0
|
10
|
+
@faction = FACTIONS # so that FAC1 will be then the first active faction
|
11
|
+
@score = [0, 0]
|
12
|
+
@text = 'ready'
|
13
|
+
end
|
14
|
+
|
15
|
+
def update
|
16
|
+
end
|
17
|
+
|
18
|
+
def draw
|
19
|
+
freeroam_text = ""
|
20
|
+
freeroam_text = " (freeroam)" if (@cursor and @cursor.freeroam)
|
21
|
+
|
22
|
+
state = Gosu::Image.from_text(turnscore + freeroam_text, LINE_HEIGHT)
|
23
|
+
state.draw(XTEXT, YTEXT, ZTEXT)
|
24
|
+
|
25
|
+
text = Gosu::Image.from_text("#{@text}", LINE_HEIGHT)
|
26
|
+
text.draw(XTEXT, (TILESIZE / 2) + YTEXT, ZTEXT)
|
27
|
+
end
|
28
|
+
|
29
|
+
def turnscore
|
30
|
+
"Turn: #{@turn}, " \
|
31
|
+
"Faction: FAC#{@faction}, " \
|
32
|
+
"Score: #{@score[0]} - #{@score[1]}"
|
33
|
+
end
|
34
|
+
|
35
|
+
# Increment faction counter (modulo count of factions)
|
36
|
+
def next_faction!
|
37
|
+
@faction += 1
|
38
|
+
@faction = 1 if @faction > FACTIONS # marks the end of turn
|
39
|
+
end
|
40
|
+
|
41
|
+
# Increment turn counter
|
42
|
+
def next_turn!
|
43
|
+
@turn += 1
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_score(to_whom, how_much)
|
47
|
+
@score[to_whom] += how_much
|
48
|
+
end
|
49
|
+
end
|
@@ -1,21 +1,31 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative './tile'
|
2
|
+
|
3
|
+
require_relative './../units/army'
|
4
|
+
require_relative './../units/ship'
|
5
|
+
require_relative './../units/town'
|
4
6
|
|
5
7
|
class Map
|
6
8
|
attr_accessor :name, :mapx, :mapy, :infopane
|
7
9
|
|
8
|
-
def initialize(infopane)
|
10
|
+
def initialize(file, infopane)
|
9
11
|
dir_path = File.dirname(__FILE__)
|
10
12
|
|
11
13
|
@infopane = infopane
|
12
|
-
|
14
|
+
@known_unit_types = Hash[
|
15
|
+
[Army, Ship, Town].collect { |ii| [ii.map_symbol, ii] }
|
16
|
+
]
|
17
|
+
|
18
|
+
load_map!(dir_path + "/../../save/#{file}.esf")
|
13
19
|
end
|
14
20
|
|
15
21
|
# Load map from file
|
16
|
-
def load_map(
|
17
|
-
|
18
|
-
|
22
|
+
def load_map!(file_path)
|
23
|
+
unless File.file?(file_path)
|
24
|
+
abort("Map.load_map!(): File not found (#{file_path})")
|
25
|
+
end
|
26
|
+
|
27
|
+
input = File.open(file_path, 'r')
|
28
|
+
unit_count = load_head!(input.gets)
|
19
29
|
|
20
30
|
# Load tiles
|
21
31
|
@tiles = []
|
@@ -28,7 +38,7 @@ class Map
|
|
28
38
|
}
|
29
39
|
|
30
40
|
# Load units
|
31
|
-
unit_count.times { load_unit(input.gets) }
|
41
|
+
unit_count.times { load_unit!(input.gets) }
|
32
42
|
|
33
43
|
puts("Save loaded: #{@name} with #{unit_count} units")
|
34
44
|
input.close
|
@@ -36,7 +46,7 @@ class Map
|
|
36
46
|
|
37
47
|
# Load core info from given head row of file
|
38
48
|
# Return number of units to be loaded
|
39
|
-
def load_head(row)
|
49
|
+
def load_head!(row)
|
40
50
|
head = []
|
41
51
|
size = []
|
42
52
|
|
@@ -51,7 +61,7 @@ class Map
|
|
51
61
|
end
|
52
62
|
|
53
63
|
# Load one unit from given row
|
54
|
-
def load_unit(row)
|
64
|
+
def load_unit!(row)
|
55
65
|
unit = []
|
56
66
|
coords = []
|
57
67
|
|
@@ -63,34 +73,30 @@ class Map
|
|
63
73
|
coords_y = coords[1].to_i
|
64
74
|
if (coords_x < 0 || coords_x >= @mapx ||
|
65
75
|
coords_y < 0 || coords_y >= @mapy)
|
66
|
-
abort("map.load_unit(): Unit out of map borders (#{coords_x}-#{coords_y})")
|
76
|
+
abort("map.load_unit!(): Unit out of map borders (#{coords_x}-#{coords_y})")
|
67
77
|
end
|
68
78
|
|
69
79
|
# Check faction
|
70
80
|
fac = unit[1].to_i
|
71
81
|
if(fac < 0 || fac > FACTIONS)
|
72
|
-
abort("map.load_unit(): Bad faction id (#{fac})")
|
82
|
+
abort("map.load_unit!(): Bad faction id (#{fac})")
|
73
83
|
end
|
74
84
|
|
75
85
|
# Create unit
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
when SYMBOL_ARMY then
|
80
|
-
Army.new(coords_x, coords_y, fac, self, @infopane)
|
81
|
-
when SYMBOL_SHIP then
|
82
|
-
Ship.new(coords_x, coords_y, fac, self, @infopane)
|
86
|
+
unit_type = unit[0]
|
87
|
+
if @known_unit_types.include?(unit_type)
|
88
|
+
@known_unit_types[unit_type].new(coords_x, coords_y, fac, self, @infopane)
|
83
89
|
else
|
84
|
-
abort("map.load_unit(): Unknown unit type symbol (#{
|
90
|
+
abort("map.load_unit!(): Unknown unit type symbol (#{unit_type})")
|
85
91
|
end
|
86
92
|
end
|
87
93
|
|
88
94
|
# Draw all tiles
|
89
95
|
def draw_tiles
|
90
|
-
all_tiles.each { |tt| tt.draw}
|
96
|
+
all_tiles.each { |tt| tt.draw}
|
91
97
|
end
|
92
98
|
|
93
|
-
# Getter for tile
|
99
|
+
# Getter for tile at given coordinates
|
94
100
|
def tile(cc, rr)
|
95
101
|
@tiles[rr][cc]
|
96
102
|
end
|
@@ -108,12 +114,12 @@ class Map
|
|
108
114
|
ret
|
109
115
|
end
|
110
116
|
|
111
|
-
# Getter for unit
|
117
|
+
# Getter for unit at given coordinates
|
112
118
|
def get_unit(cc, rr)
|
113
119
|
@tiles[rr][cc].unit
|
114
120
|
end
|
115
121
|
|
116
|
-
# Setter for unit
|
122
|
+
# Setter for unit at given coordinates
|
117
123
|
def set_unit(cc, rr, uu)
|
118
124
|
@tiles[rr][cc].unit = uu
|
119
125
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
TILE_SEA = 0
|
2
|
+
TILE_GROUND = 1
|
3
|
+
|
4
|
+
SYMBOL_SEA = '.'
|
5
|
+
SYMBOL_GROUND = '#'
|
6
|
+
|
7
|
+
class Tile
|
8
|
+
attr_accessor :terrain, :infopane, :unit
|
9
|
+
|
10
|
+
def initialize(x, y, loaded_symbol, infopane)
|
11
|
+
dir_path = File.dirname(__FILE__)
|
12
|
+
|
13
|
+
@x = x
|
14
|
+
@y = y
|
15
|
+
@infopane = infopane
|
16
|
+
|
17
|
+
case(loaded_symbol)
|
18
|
+
when SYMBOL_SEA then
|
19
|
+
@terrain = TILE_SEA
|
20
|
+
@image = Gosu::Image.new(dir_path + '/../../media/sea.png')
|
21
|
+
when SYMBOL_GROUND then
|
22
|
+
@terrain = TILE_GROUND
|
23
|
+
@image = Gosu::Image.new(dir_path + '/../../media/ground.png')
|
24
|
+
else
|
25
|
+
abort("tile.initialize(): Unknown terrain symbol (#{loaded_symbol})")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def draw
|
30
|
+
# 1) terrain
|
31
|
+
@image.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZTILE)
|
32
|
+
|
33
|
+
# 2) unit
|
34
|
+
if @unit
|
35
|
+
@unit.draw
|
36
|
+
end
|
37
|
+
|
38
|
+
# 3) axes
|
39
|
+
draw_axis_tick(@x, @y, 0) # TODO 0 -> viewport.y
|
40
|
+
draw_axis_tick(@y, @x, 0) # TODO 0 -> viewport.x
|
41
|
+
end
|
42
|
+
|
43
|
+
# Draw one tick of axis for appropriate tiles
|
44
|
+
def draw_axis_tick(draw_coord, test_coord, test_against)
|
45
|
+
# TODO appropriatness can be changed (show axes: no/top/left/bottom/right)
|
46
|
+
if test_coord == test_against
|
47
|
+
tick = Gosu::Image.from_text(draw_coord, 20)
|
48
|
+
tick.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZTEXT)
|
49
|
+
# ^^ TODO substract test_against of viewport from @x and @y here?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
File without changes
|
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.
|
4
|
+
version: '0.24'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Detros
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gosu
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
19
|
+
version: '0.9'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
26
|
+
version: '0.9'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,21 +38,31 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
-
description:
|
42
|
-
|
43
|
-
|
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/cursor.rb
|
51
|
-
- lib/docu/Empi v18.png
|
52
|
-
- lib/docu/info.txt
|
53
50
|
- lib/empi.rb
|
54
|
-
- lib/
|
55
|
-
- lib/
|
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/welcome_state.rb
|
56
|
+
- lib/lib/units/army.rb
|
57
|
+
- lib/lib/units/ship.rb
|
58
|
+
- lib/lib/units/town.rb
|
59
|
+
- lib/lib/units/unit.rb
|
60
|
+
- lib/lib/units/unitFunction.rb
|
61
|
+
- lib/lib/user_interface/cursor.rb
|
62
|
+
- lib/lib/user_interface/infopane.rb
|
63
|
+
- lib/lib/user_interface/map.rb
|
64
|
+
- lib/lib/user_interface/tile.rb
|
65
|
+
- lib/media/Empi v18.png
|
56
66
|
- lib/media/army.png
|
57
67
|
- lib/media/cursor.png
|
58
68
|
- lib/media/ground.png
|
@@ -63,15 +73,15 @@ files:
|
|
63
73
|
- lib/save/m02-err.esf
|
64
74
|
- lib/save/m02.esf
|
65
75
|
- lib/save/m03.esf
|
66
|
-
- lib/ship.rb
|
67
|
-
- lib/tile.rb
|
68
|
-
- lib/town.rb
|
69
|
-
- lib/unit.rb
|
70
|
-
- lib/unitFunction.rb
|
71
76
|
homepage: http://www.bay12forums.com/smf/index.php?topic=157538
|
72
77
|
licenses:
|
73
78
|
- CC-BY-SA-3.0
|
74
|
-
metadata:
|
79
|
+
metadata:
|
80
|
+
source_code_uri: https://gitlab.com/rasunadon/empi
|
81
|
+
bug_tracker_uri: https://gitlab.com/rasunadon/empi/issues
|
82
|
+
documentation_uri: https://gitlab.com/rasunadon/empi/blob/master/README.md
|
83
|
+
changelog_uri: https://gitlab.com/rasunadon/empi/blob/master/CHANGELOG.md
|
84
|
+
homepage_uri: http://www.bay12forums.com/smf/index.php?topic=157538
|
75
85
|
post_install_message:
|
76
86
|
rdoc_options: []
|
77
87
|
require_paths:
|
@@ -91,5 +101,5 @@ rubyforge_project:
|
|
91
101
|
rubygems_version: 2.7.6
|
92
102
|
signing_key:
|
93
103
|
specification_version: 4
|
94
|
-
summary:
|
104
|
+
summary: A turn-based wargame
|
95
105
|
test_files: []
|
data/lib/cursor.rb
DELETED
@@ -1,166 +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
|
-
|
15
|
-
# to_next_unit! # get to the first one
|
16
|
-
end
|
17
|
-
|
18
|
-
def update(key)
|
19
|
-
case key
|
20
|
-
# Cardinal directions
|
21
|
-
when Gosu::KbLeft, Gosu::KbA then
|
22
|
-
move!(-1, 0) unless @x <= 0
|
23
|
-
when Gosu::KbRight, Gosu::KbD then
|
24
|
-
move!(1, 0) unless @x >= MAPX
|
25
|
-
when Gosu::KbUp, Gosu::KbW then
|
26
|
-
move!(0, -1) unless @y <= 0
|
27
|
-
when Gosu::KbDown, Gosu::KbX then
|
28
|
-
move!(0, 1) unless @y >= MAPY
|
29
|
-
|
30
|
-
# Intercardinal directions
|
31
|
-
when Gosu::KbQ then
|
32
|
-
move!(-1, -1) unless @x <= 0 || @y <= 0
|
33
|
-
when Gosu::KbE then
|
34
|
-
move!(1, -1) unless @x >= MAPX || @y <= 0
|
35
|
-
when Gosu::KbZ then
|
36
|
-
move!(-1, 1) unless @x <= 0 || @y >= MAPY
|
37
|
-
when Gosu::KbC then
|
38
|
-
move!(1, 1) unless @x >= MAPX || @y >= MAPY
|
39
|
-
|
40
|
-
# Functions
|
41
|
-
when Gosu::KbS then
|
42
|
-
set_function_to_unit(FUNCSENTRY)
|
43
|
-
when Gosu::KbB then
|
44
|
-
set_function_to_unit(FUNCBUILD)
|
45
|
-
when Gosu::KbN then
|
46
|
-
set_function_to_unit(FUNCNONE)
|
47
|
-
|
48
|
-
when Gosu::KbReturn then
|
49
|
-
info
|
50
|
-
end
|
51
|
-
|
52
|
-
# If in locked mode, stay at current/jump to next movable unit
|
53
|
-
to_next_unit! unless freeroam
|
54
|
-
end
|
55
|
-
|
56
|
-
def draw
|
57
|
-
@image.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZCURSOR)
|
58
|
-
end
|
59
|
-
|
60
|
-
# Move to coordinates of given unit
|
61
|
-
def warp_to!(uu)
|
62
|
-
@x = uu.x
|
63
|
-
@y = uu.y
|
64
|
-
@unit = uu
|
65
|
-
end
|
66
|
-
|
67
|
-
# Move by given change of coordinates
|
68
|
-
def move!(xx, yy)
|
69
|
-
if freeroam
|
70
|
-
@x += xx
|
71
|
-
@y += yy
|
72
|
-
@unit = @map.get_unit(@x, @y)
|
73
|
-
return
|
74
|
-
end
|
75
|
-
|
76
|
-
# If in locked mode
|
77
|
-
if !@unit
|
78
|
-
abort("cursor.move!(): Cursor is in locked mode but there is no unit it is locked to (at #{@x} - #{@y})")
|
79
|
-
end
|
80
|
-
|
81
|
-
@unit.x += xx
|
82
|
-
@unit.y += yy
|
83
|
-
@unit.check_movement(@x, @y) # cursor coordinates work like old_x, old_y
|
84
|
-
|
85
|
-
uu = @map.get_unit(@unit.x, @unit.y)
|
86
|
-
if !uu # it got destroyed
|
87
|
-
@unit = nil # clear the last links so that (object of) given unit can be truly destroyed
|
88
|
-
return
|
89
|
-
end
|
90
|
-
|
91
|
-
warp_to!(@unit) # whether it moved or not, unless it got destroyed
|
92
|
-
end
|
93
|
-
|
94
|
-
# Tries to set function <func> to currently selected unit
|
95
|
-
def set_function_to_unit(func)
|
96
|
-
if freeroam
|
97
|
-
uu = @map.get_unit(@x, @y)
|
98
|
-
else # in locked mode
|
99
|
-
if !@unit
|
100
|
-
abort("cursor.set_function_to_unit(): Cursor is in locked mode but there is no unit it is locked to (at #{@x} - #{@y})")
|
101
|
-
end
|
102
|
-
uu = @unit
|
103
|
-
end
|
104
|
-
|
105
|
-
uu.set_function!(func) unless !uu
|
106
|
-
end
|
107
|
-
|
108
|
-
# Find next unit to target with cursor
|
109
|
-
def to_next_unit!
|
110
|
-
unless @unit && @unit.can_move? && @unit.function == FUNCNONE # unless the current one is still movable
|
111
|
-
movable_units = @map.all_units.select { |uu| uu.can_move? && uu.function == FUNCNONE}
|
112
|
-
|
113
|
-
# If there are no more movable units without function, switch to freeroam mode
|
114
|
-
if movable_units.size <= 0 # == would be enough
|
115
|
-
puts 'all movable units without functions moved'
|
116
|
-
|
117
|
-
switch_freeroam!
|
118
|
-
return
|
119
|
-
end
|
120
|
-
|
121
|
-
@unit = movable_units[0] # newly selected one
|
122
|
-
end
|
123
|
-
|
124
|
-
warp_to!(@unit) # stay at old or go to new
|
125
|
-
info
|
126
|
-
end
|
127
|
-
|
128
|
-
# Switch between being attached to unit and being able to freeroam
|
129
|
-
def switch_freeroam!
|
130
|
-
if freeroam
|
131
|
-
@infopane.text = 'freeroam disabled'
|
132
|
-
puts 'freeroam disabled'
|
133
|
-
@freeroam = false
|
134
|
-
to_next_unit!
|
135
|
-
else
|
136
|
-
@infopane.text = 'freeroam enabled'
|
137
|
-
puts 'freeroam enabled'
|
138
|
-
@freeroam = true
|
139
|
-
@unit = nil
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
# Find some info about units on the current tile
|
144
|
-
def info
|
145
|
-
if freeroam
|
146
|
-
uu = @map.get_unit(@x, @y)
|
147
|
-
else
|
148
|
-
if !@unit
|
149
|
-
abort("cursor.info(): Cursor is in locked mode but there is no unit it is locked to (at #{@x} - #{@y})")
|
150
|
-
end
|
151
|
-
uu = @unit
|
152
|
-
end
|
153
|
-
|
154
|
-
if uu
|
155
|
-
@infopane.text = uu.info
|
156
|
-
puts uu.info
|
157
|
-
|
158
|
-
if uu.is_transporting?
|
159
|
-
uu.cargo.each { |uu| puts '- cargo: ' + uu.info }
|
160
|
-
end
|
161
|
-
else
|
162
|
-
@infopane.text = ''
|
163
|
-
puts 'nothing here'
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|