empi 0.16.6

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.
data/lib/army.rb ADDED
@@ -0,0 +1,18 @@
1
+ require_relative './unit'
2
+
3
+ class Army < Unit
4
+ def initialize(x, y, faction, map, infopane)
5
+ super
6
+ dir_path = File.dirname(__FILE__)
7
+ @image = Gosu::Image.new(dir_path + '/media/army.png')
8
+
9
+ @name = 'army'
10
+ @value = 5
11
+ @armor_left = @armor_max = 3
12
+ @moves_max = 5
13
+ end
14
+
15
+ def can_ride?
16
+ true
17
+ end
18
+ end
data/lib/cursor.rb ADDED
@@ -0,0 +1,99 @@
1
+ class Cursor
2
+ attr_accessor :x, :y, :freeroam
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(key)
17
+ case key
18
+ # Cardinal directions
19
+ when Gosu::KbLeft, Gosu::KbA then
20
+ @x -= 1 unless @x <= 0
21
+ when Gosu::KbRight, Gosu::KbD then
22
+ @x += 1 unless @x >= MAPX
23
+ when Gosu::KbUp, Gosu::KbW then
24
+ @y -= 1 unless @y <= 0
25
+ when Gosu::KbDown, Gosu::KbX then
26
+ @y += 1 unless @y >= MAPY
27
+
28
+ # Intercardinal directions
29
+ when Gosu::KbQ then
30
+ unless @x <= 0 || @y <= 0
31
+ @x -= 1
32
+ @y -= 1
33
+ end
34
+ when Gosu::KbE then
35
+ unless @x >= MAPX || @y <= 0
36
+ @x += 1
37
+ @y -= 1
38
+ end
39
+ when Gosu::KbZ then
40
+ unless @x <= 0 || @y >= MAPY
41
+ @x -= 1
42
+ @y += 1
43
+ end
44
+ when Gosu::KbC then
45
+ unless @x >= MAPX || @y >= MAPY
46
+ @x += 1
47
+ @y += 1
48
+ end
49
+
50
+ # Functions
51
+ when Gosu::KbS then
52
+ uu = @map.get_unit(@x, @y)
53
+ if uu then uu.set_function(FUNCSENTRY) end
54
+ when Gosu::KbB then
55
+ uu = @map.get_unit(@x, @y)
56
+ if uu then uu.set_function(FUNCBUILD) end
57
+ when Gosu::KbN then
58
+ uu = @map.get_unit(@x, @y)
59
+ if uu then uu.set_function(FUNCNONE) end
60
+
61
+ when Gosu::KbReturn then
62
+ info
63
+ end
64
+ end
65
+
66
+ def draw
67
+ @image.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZCURSOR)
68
+ end
69
+
70
+ # Move to given coordinates
71
+ def warp(x, y)
72
+ @x = x
73
+ @y = y
74
+ end
75
+
76
+ # Switch between being attached to unit and being able to freeroam
77
+ def switch_freeroam
78
+ if freeroam == true
79
+ @infopane.text = 'freeroam disabled'
80
+ puts 'freeroam disabled'
81
+ else
82
+ @infopane.text = 'freeroam enabled'
83
+ puts 'freeroam enabled'
84
+ end
85
+ @freeroam = !@freeroam
86
+ end
87
+
88
+ # Find some info about unit in current tile
89
+ def info
90
+ uu = @map.get_unit(@x, @y)
91
+ if uu
92
+ @infopane.text = uu.info
93
+ puts uu.info
94
+ else
95
+ @infopane.text = ''
96
+ puts 'nothing here'
97
+ end
98
+ end
99
+ end
Binary file
data/lib/docu/info.txt ADDED
@@ -0,0 +1,149 @@
1
+ /-- /// /-/ -/-
2
+ /-- ||| /-/ |
3
+ /-- ||| | -/-
4
+
5
+ Empi: Ruby Edition
6
+ ====================
7
+
8
+
9
+ v16 dev
10
+ =========
11
+ - units on sentry duty say so when functioning
12
+ - neutral units can't have functions
13
+ - links to media and save files use full path
14
+ - towns build armies
15
+ ! hardcoded unit type to be built
16
+ - units can transport other units
17
+ - newly built units are stored in town instead of map
18
+ fixes: new units are saved in map instead of the towns that built them
19
+ ! transported units are not drawn
20
+ ! transported units show info of their transport instead when selected
21
+ ! all units can capture and visit towns
22
+
23
+ file changes
24
+ --------------
25
+ map
26
+ initialize() uses full paths to files
27
+ all_units renamed to all_map_units() - Return only units directly on map
28
+ +all_transported_units() - Return only units transported by other units
29
+ +all_units() - Return both map units and transported units
30
+ draw_units() draws only map units
31
+
32
+ unit
33
+ +@cargo, @cargo_max
34
+ +can_transport?() - Unit is able to both transport other units and currently has some space left
35
+ set_function() checks for @faction == 0
36
+ checking of movement separated from update()
37
+ +check_movement() - Processes move of unit and takes care of its (un)loading or attack
38
+ capture() makes newly captured towns start building
39
+
40
+ town
41
+ initialize() uses full path to file
42
+ +parts_built
43
+ +@cargo_max set to 10
44
+
45
+ army
46
+ initialize() uses full path to file
47
+
48
+ ship
49
+ initialize() uses full path to file
50
+ +@cargo_max set to 3
51
+
52
+ unitFunction
53
+ +FUNCBUILD case in func!()
54
+ FUNCSENTRY case in func!() sets "ret" even when unit keeps sentrying
55
+
56
+
57
+ v15 dev
58
+ =========
59
+ - units referenced only from map
60
+ fixed: no destruction of units
61
+ - loading of units from file
62
+ fixed: no loading
63
+ - checks of loaded terrain tiles and units
64
+ - map stored as [row, column], not [xx, yy]
65
+
66
+ file changes
67
+ --------------
68
+ empi.rb
69
+ -scenario_units() - Return list of units for given scenario
70
+
71
+ map.rb
72
+ load_map() now loads units too
73
+ load_head() now returns number of units to load too
74
+ load_map(), tile(), get_unit(), set_unit() use rr and cc instead of xx and yy
75
+ +load_unit() - Load one unit from given line
76
+ +draw_units() - Draw all units
77
+
78
+ save/m01.esf
79
+ 8 units from old empi.scenario_units()
80
+
81
+ save/m02.esf
82
+ 10 units similar to old empi.scenario_units()
83
+
84
+ save/m03.esf
85
+
86
+
87
+ v14 dev
88
+ =========
89
+ - loading of terrain tiles from file
90
+ fixed: hardcoded starting scenario
91
+ ! hardcoded save file name
92
+ ! hardcoded map size
93
+
94
+ file changes
95
+ --------------
96
+ empi.rb
97
+ TILE constants moved to map.rb
98
+
99
+ map.rb
100
+ -scenario_tiles() - Return map tile for given scenario
101
+ +load_map() - Load map from file (for now only terrain tiles)
102
+ +load_head() - Load head row of file
103
+
104
+ unit.rb
105
+ removed generic unit image
106
+
107
+ save/m01.esf
108
+ save/m02.esf
109
+
110
+
111
+ older versions
112
+ ================
113
+ - towns and armies
114
+ - functions none and sentry
115
+ - armor and movement points
116
+ - movement of units
117
+ - rudimentary terrain checking after move
118
+ - capturing of units
119
+ - turn and score counting
120
+ - commmand line and screen text output
121
+ - next avaiable unit / freeroam cursor
122
+
123
+ current state
124
+ ===============
125
+ old wishlist
126
+ ! no panning of map
127
+ !x no destruction of units
128
+ !x no building of units
129
+ ! no victory conditions
130
+ ! attacker always wins
131
+ ! player playing both factions at once
132
+ !x hardcoded starting scenario
133
+ ! no fog of war
134
+ ! no saving
135
+ !x no loading
136
+ ! no title screen
137
+ ! no highscore screen
138
+ ! no settings
139
+ ! no sound, no music
140
+
141
+ new problems
142
+ ! hardcoded save file name
143
+ ! hardcoded map size
144
+ ! hardcoded unit type to be built
145
+ ! transported units are not drawn
146
+ ! transported units show info of their transport instead when selected
147
+ ! all units can capture and visit towns
148
+
149
+ (! thing to fix, !x fixed thing)
data/lib/empi.rb ADDED
@@ -0,0 +1,143 @@
1
+ require 'rubygems'
2
+ require 'gosu'
3
+
4
+ require_relative './army'
5
+ require_relative './cursor'
6
+ require_relative './infopane'
7
+ require_relative './map'
8
+ require_relative './ship'
9
+ require_relative './town'
10
+
11
+ TILESIZE = 50
12
+ MAPX = 10
13
+ MAPY = 10
14
+
15
+ XTEXT = 5
16
+ YTEXT = 5
17
+
18
+ ZTILE = 0
19
+ ZUNIT = 1
20
+ ZTEXT = 2
21
+ ZCURSOR = 3
22
+
23
+ FACTIONS = 2
24
+ COLOUR = [0xff_ffffff, 0xff_ff3300, 0xff_ffcc00]
25
+
26
+ FUNCNONE = 'none'
27
+ FUNCSENTRY = 'sentry'
28
+ FUNCBUILD = 'build'
29
+
30
+ # Main class
31
+ class GameWindow < Gosu::Window
32
+ def initialize(width = (MAPX + 1) * TILESIZE, \
33
+ height = (MAPY + 2) * TILESIZE, \
34
+ fullscreen = false)
35
+ super
36
+ self.caption = 'Empi: Ruby Edition 0.16 dev'
37
+
38
+ @infopane = Infopane.new
39
+ @map = Map.new(@infopane)
40
+ @cursor = Cursor.new(5, 5, @map, @infopane)
41
+
42
+ new_turn
43
+ end
44
+
45
+ def button_up(key)
46
+ @button = key
47
+
48
+ case(key)
49
+ when Gosu::KbEscape then
50
+ close
51
+ when Gosu::KbPeriod then
52
+ new_turn
53
+ when Gosu::KbH then
54
+ help
55
+ when Gosu::KbJ then
56
+ unit_to_move = 0
57
+ @cursor.switch_freeroam
58
+ end
59
+ end
60
+
61
+ # Process given button to cursor
62
+ def update
63
+ if @button == -1 then return end
64
+
65
+ movable_units = @map.all_units.select { |uu| uu.can_move && uu.function == FUNCNONE}
66
+ # If there are any movable units without functions select one of them with the cursor
67
+ if @cursor.freeroam == false && movable_units.size > 0
68
+ unit_to_move = movable_units[0]
69
+ unit_to_move.update(@button)
70
+
71
+ # Can it still move?
72
+ if unit_to_move.can_move && unit_to_move.function == FUNCNONE
73
+ # Move the cursor to it unless it is already there
74
+ if (@cursor.x != unit_to_move.x \
75
+ || @cursor.y != unit_to_move.y)
76
+ @cursor.warp(unit_to_move.x, unit_to_move.y)
77
+ @cursor.info
78
+ end
79
+ else
80
+ # Was that the last currently avaiable non-function move?
81
+ movable_units = @map.all_units.select { |uu| uu.can_move && uu.function == FUNCNONE}
82
+ if movable_units.size == 0
83
+ puts 'all movable units without functions moved'
84
+ @cursor.switch_freeroam
85
+ else
86
+ # Move cursor to next avaiable unit
87
+ unit_to_move = movable_units[0]
88
+ @cursor.warp(unit_to_move.x, unit_to_move.y)
89
+ @cursor.info
90
+ end
91
+ end
92
+
93
+ else
94
+ # Cursor in freeroam mode
95
+ @cursor.update(@button)
96
+ end
97
+ end
98
+
99
+ # Draw only after some button was released and in the start
100
+ def needs_redraw?
101
+ @button != -1
102
+ end
103
+
104
+ def draw
105
+ @button = -1 # use each button just once
106
+
107
+ # Draw map tiles and units
108
+ @map.draw_tiles
109
+ @map.draw_units
110
+ # DEBUG @map.all_units.each { |uu| puts uu.info}
111
+
112
+ @cursor.draw
113
+ @infopane.draw
114
+
115
+ # @message = Gosu::Image.from_text(
116
+ # self, "Empire", Gosu.default_font_name, 20)
117
+ # @message.draw(10, 10, 2)
118
+ end
119
+
120
+ # End current turn and start next one
121
+ def new_turn
122
+ @cursor.freeroam = true
123
+ @cursor.switch_freeroam # so freeroam = false, with messages
124
+
125
+ functionable_units = @map.all_units.select { |uu| uu.function != FUNCNONE}
126
+ functionable_units.each { |uu| uu.function! }
127
+
128
+ @map.all_units.each { |uu| uu.reset_moves}
129
+ @infopane.next_turn
130
+ end
131
+
132
+ def help
133
+ puts "----------\n" \
134
+ "QWEADZXC movement, h help, Enter info, j switch freeroam\n" \
135
+ "functions: s sentry, n none\n" \
136
+ "----------\n"
137
+ end
138
+ end
139
+
140
+ # ---------------------------------------------------------------
141
+
142
+ window = GameWindow.new
143
+ window.show
data/lib/infopane.rb ADDED
@@ -0,0 +1,36 @@
1
+ # Score, turn and event texts
2
+ class Infopane
3
+ attr_writer :text, :act_fact
4
+
5
+ def initialize
6
+ @score = [0, 0]
7
+ @turn = 0
8
+ @act_fact = 0 # active faction
9
+ @text = 'ready'
10
+ end
11
+
12
+ def update
13
+ end
14
+
15
+ def draw
16
+ turnscore = Gosu::Image.from_text(
17
+ self, "Turn: #{@turn}, Score: #{@score[0]} - #{@score[1]}", Gosu.default_font_name, 20)
18
+ turnscore.draw(XTEXT, YTEXT, ZTEXT)
19
+
20
+ text = Gosu::Image.from_text(self, "#{@text}", Gosu.default_font_name, 20)
21
+ text.draw(XTEXT, (TILESIZE / 2) + YTEXT, ZTEXT)
22
+ end
23
+
24
+ def next_faction
25
+
26
+ end
27
+
28
+ def next_turn
29
+ @turn += 1
30
+ puts "Turn: #{@turn}, Score: #{@score[0]} - #{@score[1]}"
31
+ end
32
+
33
+ def add_score(to_whom, how_much)
34
+ @score[to_whom] += how_much
35
+ end
36
+ end
data/lib/map.rb ADDED
@@ -0,0 +1,172 @@
1
+ TILE_SEA = 0
2
+ TILE_GROUND = 1
3
+
4
+ SYMBOL_SEA = '.'
5
+ SYMBOL_GROUND = '#'
6
+ SYMBOL_TOWN = 'T'
7
+ SYMBOL_ARMY = 'A'
8
+ SYMBOL_SHIP = 'S'
9
+
10
+ class Map
11
+ attr_accessor :name, :mapx, :mapy, :infopane
12
+
13
+ # Fill tile map and prepare
14
+ def initialize(infopane)
15
+ dir_path = File.dirname(__FILE__)
16
+
17
+ @infopane = infopane
18
+ @sea_image = Gosu::Image.new(dir_path + '/media/sea.png')
19
+ @ground_image = Gosu::Image.new(dir_path + '/media/ground.png')
20
+ load_map(dir_path + '/save/m03.esf')
21
+ end
22
+
23
+ # Load map from file
24
+ def load_map(filename)
25
+ input = File.open(filename, 'r')
26
+ unit_count = load_head(input.gets)
27
+
28
+ # Load tiles
29
+ @tiles = []
30
+ @units = []
31
+ 0.upto(@mapy - 1) { |rr|
32
+ @tiles[rr] = []
33
+ @units[rr] = []
34
+ map_row = input.gets
35
+ 0.upto(@mapx - 1) { |cc|
36
+ case(map_row[cc])
37
+ when SYMBOL_SEA then
38
+ @tiles[rr][cc] = TILE_SEA
39
+ when SYMBOL_GROUND then
40
+ @tiles[rr][cc] = TILE_GROUND
41
+ else
42
+ abort("map.load_map(): Unknown terrain symbol (#{map_row[cc]})")
43
+ end
44
+ }
45
+ }
46
+
47
+ # Load units
48
+ unit_count.times { load_unit(input.gets) }
49
+
50
+ puts("Save loaded: #{@name} with #{unit_count} units")
51
+ input.close
52
+ end
53
+
54
+ # Load core info from given head row of file
55
+ # Return number of units to be loaded
56
+ def load_head(row)
57
+ head = []
58
+ size = []
59
+
60
+ head = row.split(' ')
61
+ size = head[1].split('x')
62
+
63
+ @name = head[0]
64
+ @mapx = size[0].to_i
65
+ @mapy = size[1].to_i
66
+
67
+ head[2].to_i # unit_count
68
+ end
69
+
70
+ # Load one unit from given line
71
+ def load_unit(row)
72
+ unit = []
73
+ coords = []
74
+
75
+ unit = row.split(' ')
76
+ coords = unit[2].split('-')
77
+
78
+ # Check faction
79
+ fac = unit[1].to_i
80
+ if(fac < 0 || fac > FACTIONS)
81
+ abort("map.load_unit(): Bad faction id (#{fac})")
82
+ end
83
+
84
+ # Check coordinates
85
+ coords_x = coords[0].to_i
86
+ coords_y = coords[1].to_i
87
+ if (coords_x < 0 || coords_x >= @mapx ||
88
+ coords_y < 0 || coords_y >= @mapy)
89
+ abort("map.load_unit(): Unit out of map borders (#{coords_x}-#{coords_y})")
90
+ end
91
+
92
+ # Create unit
93
+ case(unit[0])
94
+ when SYMBOL_TOWN then
95
+ Town.new(coords_x, coords_y, fac, self, @infopane)
96
+ when SYMBOL_ARMY then
97
+ Army.new(coords_x, coords_y, fac, self, @infopane)
98
+ when SYMBOL_SHIP then
99
+ Ship.new(coords_x, coords_y, fac, self, @infopane)
100
+ else
101
+ abort("map.load_unit(): Unknown unit type symbol (#{unit[0]})")
102
+ end
103
+ end
104
+
105
+ # Draw all tiles
106
+ def draw_tiles
107
+ # TODO combine with draw_units()
108
+
109
+ 0.upto(MAPX) { |rr|
110
+ 0.upto(MAPX) { |cc|
111
+ if @tiles[rr][cc] == TILE_SEA
112
+ # TODO tiles (z1) and units (z2) together
113
+ im = @sea_image
114
+ else
115
+ im = @ground_image
116
+ end
117
+ im.draw(cc * TILESIZE, (rr + 1) * TILESIZE, ZTILE)
118
+ }
119
+ }
120
+ end
121
+
122
+ # Draw all map units
123
+ def draw_units
124
+ all_map_units.each { |uu| uu.draw} # TODO do not draw transported units? only draw them on selection (with their tile)?
125
+ end
126
+
127
+ # Getter for tile type in given coordinates
128
+ def tile(cc, rr)
129
+ @tiles[rr][cc]
130
+ end
131
+
132
+ # Getter for unit in given coordinates
133
+ def get_unit(cc, rr)
134
+ @units[rr][cc]
135
+ end
136
+
137
+ # Setter for tile type in given coordinates
138
+ def set_unit(cc, rr, uu)
139
+ @units[rr][cc] = uu
140
+ end
141
+
142
+ # Return both map units and transported units
143
+ def all_units
144
+ all_map_units + all_transported_units
145
+ end
146
+
147
+ # Return only units directly on map
148
+ def all_map_units
149
+ ret = []
150
+ ii = 0
151
+ 0.upto(MAPX) { |rr|
152
+ 0.upto(MAPX) { |cc|
153
+ if @units[rr][cc]
154
+ ret[ii] = @units[rr][cc]
155
+ ii += 1
156
+ end
157
+ }
158
+ }
159
+ ret
160
+ end
161
+
162
+ # Return only units transported by other units
163
+ def all_transported_units
164
+ ret = []
165
+ all_map_units.each { |uu|
166
+ if uu.is_transporting?
167
+ ret += uu.cargo
168
+ end
169
+ }
170
+ ret
171
+ end
172
+ end
Binary file
Binary file
Binary file
data/lib/media/sea.png ADDED
Binary file
Binary file
Binary file
data/lib/save/m01.esf ADDED
@@ -0,0 +1,20 @@
1
+ mission01 11x11 8
2
+ #####..####
3
+ ####....###
4
+ ###......##
5
+ ##........#
6
+ #...###...#
7
+ ....##....#
8
+ ....#....##
9
+ #.......###
10
+ ##.....####
11
+ ###...#####
12
+ ###########
13
+ T 0 1-3
14
+ T 0 3-1
15
+ T 0 6-9
16
+ T 0 9-6
17
+ T 1 8-1
18
+ A 1 9-1
19
+ T 2 1-8
20
+ A 2 1-9
data/lib/save/m02.esf ADDED
@@ -0,0 +1,22 @@
1
+ mission02 11x11 10
2
+ ###########
3
+ #..###..###
4
+ #....#...##
5
+ ##...#....#
6
+ ##....#...#
7
+ ####...####
8
+ #...#....##
9
+ #....#....#
10
+ ##...#....#
11
+ ###..##..##
12
+ ###########
13
+ T 0 1-3
14
+ T 0 3-1
15
+ T 0 6-9
16
+ T 0 9-6
17
+ T 1 8-1
18
+ T 1 9-2
19
+ A 1 10-0
20
+ T 2 1-8
21
+ T 2 2-9
22
+ A 2 0-10
data/lib/save/m03.esf ADDED
@@ -0,0 +1,24 @@
1
+ mission03 11x11 11
2
+ .....###...
3
+ ..#######..
4
+ .#.##.##.#.
5
+ #.#....#.##
6
+ ##...##.###
7
+ #..#####..#
8
+ ###.##...##
9
+ ##.#....#.#
10
+ .#.##.##.#.
11
+ ..#######..
12
+ ...###.....
13
+ T 0 3-8
14
+ T 0 10-4
15
+ T 0 5-1
16
+ T 0 5-5
17
+ T 0 5-9
18
+ T 0 7-2
19
+ T 0 0-6
20
+ T 1 2-3
21
+ A 1 1-2
22
+ T 2 8-7
23
+ A 2 9-8
24
+
data/lib/ship.rb ADDED
@@ -0,0 +1,19 @@
1
+ require_relative './unit'
2
+
3
+ class Ship < Unit
4
+ def initialize(x, y, faction, map, infopane)
5
+ super
6
+ dir_path = File.dirname(__FILE__)
7
+ @image = Gosu::Image.new(dir_path + '/media/ship.png')
8
+
9
+ @name = 'ship'
10
+ @value = 10
11
+ @armor_left = @armor_max = 1
12
+ @moves_max = 2
13
+ @cargo_max = 3
14
+ end
15
+
16
+ def can_sail?
17
+ true
18
+ end
19
+ end
data/lib/town.rb ADDED
@@ -0,0 +1,24 @@
1
+ require_relative './unit'
2
+
3
+ class Town < Unit
4
+ attr_accessor :parts_built
5
+
6
+ def initialize(x, y, faction, map, infopane)
7
+ super
8
+ dir_path = File.dirname(__FILE__)
9
+ @image = Gosu::Image.new(dir_path + '/media/town.png')
10
+
11
+ @name = 'town'
12
+ @value = 20
13
+ @armor_left = @armor_max = 1
14
+ @moves_max = 0
15
+
16
+ @parts_built = 0
17
+ @cargo_max = 10
18
+ set_function(FUNCBUILD)
19
+ end
20
+
21
+ def can_build?
22
+ true
23
+ end
24
+ end
data/lib/unit.rb ADDED
@@ -0,0 +1,244 @@
1
+ require_relative './unitFunction'
2
+
3
+ # All capturable game pieces
4
+ class Unit
5
+ attr_accessor :x, :y, :faction, :function, :cargo
6
+
7
+
8
+ def initialize(x, y, faction, map, infopane)
9
+ @x = x
10
+ @y = y
11
+ @faction = faction
12
+ @map = map
13
+ @infopane = infopane
14
+
15
+ @name = 'unit'
16
+ @value = 1
17
+ @armor_max = 1
18
+ @armor_left = @armor_max
19
+ @moves_max = 1
20
+ @moves_left = @moves_max
21
+ @cargo = [] # transported units
22
+ @cargo_max = 0
23
+ @function = UnitFunction.new(FUNCNONE)
24
+
25
+
26
+
27
+ # Store yourself
28
+ coords_unit = @map.get_unit(@x, @y)
29
+ if !coords_unit
30
+ @map.set_unit(@x, @y, self)
31
+ else # some town has just built you
32
+ coords_unit.cargo.insert(-1, self) # -1 = to the end
33
+ end
34
+ end
35
+
36
+ # Add <value> to the other faction
37
+ def destroy
38
+ @infopane.add_score(3 - @faction - 1, @value) # TODO more factions?
39
+ # TODO is this deleted enough?
40
+ @map.set_unit(@x, @y, nil)
41
+ end
42
+
43
+ def capture(by_whom)
44
+ # add <value> to the capturing faction
45
+ @infopane.add_score(by_whom - 1, @value)
46
+ @faction = by_whom
47
+
48
+ # if you are a town, start building units
49
+ if can_build?
50
+ set_function(FUNCBUILD)
51
+ end
52
+ end
53
+
54
+ def update(key)
55
+ old_x = @x
56
+ old_y = @y
57
+
58
+ case key
59
+ # Cardinal directions
60
+ when Gosu::KbLeft, Gosu::KbA then
61
+ @x -= 1 unless @x <= 0
62
+ when Gosu::KbRight, Gosu::KbD then
63
+ @x += 1 unless @x >= MAPX
64
+ when Gosu::KbUp, Gosu::KbW then
65
+ @y -= 1 unless @y <= 0
66
+ when Gosu::KbDown, Gosu::KbX then
67
+ @y += 1 unless @y >= MAPY
68
+
69
+ # Intercardinal directions
70
+ when Gosu::KbQ then
71
+ unless @x <= 0 || @y <= 0
72
+ @x -= 1
73
+ @y -= 1
74
+ end
75
+ when Gosu::KbE then
76
+ unless @x >= MAPX || @y <= 0
77
+ @x += 1
78
+ @y -= 1
79
+ end
80
+ when Gosu::KbZ then
81
+ unless @x <= 0 || @y >= MAPY
82
+ @x -= 1
83
+ @y += 1
84
+ end
85
+ when Gosu::KbC then
86
+ unless @x >= MAPX || @y >= MAPY
87
+ @x += 1
88
+ @y += 1
89
+ end
90
+
91
+ # Functions
92
+ when Gosu::KbS then
93
+ set_function(FUNCSENTRY)
94
+ when Gosu::KbB then
95
+ set_function(FUNCBUILD)
96
+ end
97
+
98
+ check_movement(old_x, old_y)
99
+ end
100
+
101
+
102
+ # Processes move of unit and takes care of its (un)loading or attack
103
+ def check_movement(old_x, old_y)
104
+ if @x != old_x || @y != old_y
105
+ oldcoords_unit = @map.get_unit(old_x, old_y)
106
+ newcoords_unit = @map.get_unit(@x, @y)
107
+
108
+ # If there is nobody or is there friendly unit with some cargo space
109
+ if !newcoords_unit || \
110
+ (newcoords_unit.faction == @faction && newcoords_unit.can_transport?)
111
+
112
+ # Leave old coordinates
113
+ if oldcoords_unit == self
114
+ @map.set_unit(old_x, old_y, nil)
115
+ else # if you have been transported
116
+ puts "oldcoords_unit.cargo = \"#{oldcoords_unit.cargo}\""
117
+ oldcoords_unit.cargo.delete(self)
118
+ puts "oldcoords_unit.cargo = \"#{oldcoords_unit.cargo}\""
119
+ end
120
+
121
+ # Get to new coordinates
122
+ if newcoords_unit == nil
123
+ @map.set_unit(@x, @y, self)
124
+ else # if you are going to be transported
125
+ newcoords_unit.cargo.insert(-1, self) # -1 = to the end
126
+ end
127
+
128
+ else # if there already is somebody
129
+ # Stay on your original tile
130
+ @x = old_x
131
+ @y = old_y
132
+
133
+ # Don't capture allies
134
+ if newcoords_unit.faction != @faction
135
+ puts to_s + ' is capturing ' + newcoords_unit.to_s # TODO capture only towns, do combat otherwise
136
+ newcoords_unit.capture(@faction)
137
+ end
138
+ end
139
+ @moves_left -= 1
140
+
141
+ # Check if unit is on invalid type of tile
142
+ if tile_check == false
143
+ puts to_s + " found itself in a bad place"
144
+ destroy
145
+ end
146
+ end
147
+ end
148
+
149
+
150
+ def draw
151
+ @image.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZUNIT,
152
+ scale_x = 1, scale_y = 1, color = COLOUR[@faction])
153
+ end
154
+
155
+ def can_move
156
+ (can_fly? || can_sail? || can_ride?) && @moves_left > 0
157
+ end
158
+
159
+ def can_fly?
160
+ false
161
+ end
162
+
163
+ def can_sail?
164
+ false
165
+ end
166
+
167
+ def can_ride?
168
+ false
169
+ end
170
+
171
+ def can_build?
172
+ false
173
+ end
174
+
175
+ # Unit is able to both transport other units and currently has some space left
176
+ def can_transport?
177
+ @cargo_max > 0 && @cargo.size < @cargo_max
178
+ end
179
+
180
+ def is_transporting?
181
+ @cargo.size > 0
182
+ end
183
+
184
+ def tile_check
185
+ case @map.tile(@x, @y)
186
+ when TILE_SEA
187
+ return can_fly? || can_sail?
188
+ when TILE_GROUND
189
+ return can_fly? || can_ride?
190
+ end
191
+ true
192
+ end
193
+
194
+ def function
195
+ @function.func
196
+ end
197
+
198
+ def set_function(func)
199
+ unless @faction == 0 # neutral faction doesn't need functions
200
+ if (func == FUNCBUILD && !can_build?)
201
+ puts to_s + ": this unit can't build other units"
202
+ end
203
+
204
+ if @function == func
205
+ puts to_s + ": function already set to #{@function.func}"
206
+ else
207
+ @function.func = func
208
+ puts to_s + ": function set to #{@function.func}"
209
+ end
210
+ end
211
+ end
212
+
213
+
214
+ def function!
215
+ ret = @function.func!(@x, @y, @map, @infopane)
216
+ puts to_s + ret
217
+ end
218
+
219
+ # Set short info string: type, faction, coordinates
220
+ def to_s
221
+ "#{@name} (FAC#{@faction} #{@x}-#{@y})"
222
+ end
223
+
224
+ # Set long info string: short info string, armor, moves, function, cargo
225
+ def info
226
+ ret = to_s + ": armor #{@armor_left}/#{@armor_max}"
227
+
228
+ if can_move
229
+ ret = ret + ", moves #{@moves_left}/#{@moves_max}"
230
+ end
231
+
232
+ ret = ret + ", func #{@function.func}"
233
+
234
+ if @cargo.size > 0
235
+ ret = ret + ", transports #{@cargo.size} units"
236
+ end
237
+
238
+ ret
239
+ end
240
+
241
+ def reset_moves
242
+ @moves_left = @moves_max
243
+ end
244
+ end
@@ -0,0 +1,47 @@
1
+ PARTS = 3
2
+
3
+ class UnitFunction
4
+ attr_accessor :func
5
+
6
+ def initialize(function = FUNCNONE)
7
+ @func = function
8
+ end
9
+
10
+ def func!(xx, yy, map, infopane)
11
+ ret = " didn't actually do anything (ERROR)"
12
+
13
+ unit = map.get_unit(xx, yy)
14
+ if unit == nil
15
+ abort("unitFunction.func!(): Functioning unit not found at given coordinates (#{xx}-#{yy})")
16
+ end
17
+
18
+ case @func
19
+ # Build given unit
20
+ when FUNCBUILD
21
+ if(unit.parts_built >= PARTS) # just == should be enough
22
+ ret = " completed building of army"
23
+ unit.parts_built = 0
24
+ Army.new(unit.x, unit.y, unit.faction, map, infopane) # TODO allow setting what to build
25
+ else
26
+ ret = " built next part of army"
27
+ unit.parts_built = unit.parts_built + 1
28
+ end
29
+
30
+ # Wake up when enemies are nearby
31
+ when FUNCSENTRY
32
+ units_around = map.all_units.select { |uu|
33
+ (uu.x - xx).abs <= 1 &&
34
+ (uu.y - yy).abs <= 1 &&
35
+ uu.faction != unit.faction
36
+ }
37
+ if units_around.size > 0
38
+ ret = " woke up"
39
+ @func = FUNCNONE
40
+ else
41
+ ret = " was on sentry duty"
42
+ end
43
+ end
44
+
45
+ ret
46
+ end
47
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: empi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.16.6
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Detros
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-04-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: gosu
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '10.0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '10.0'
46
+ description: ! 'Empi: Ruby Edition is a turn based wargame, currently deep in development.
47
+ While learning Ruby I have found there are hardly any strategic games avaiable.
48
+ So this should be Ruby version of Classic Empire, wargame from old times.'
49
+ email: rasunadon@seznam.cz
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - lib/docu/Empi v14.png
55
+ - lib/docu/info.txt
56
+ - lib/media/town.png
57
+ - lib/media/ship.png
58
+ - lib/media/army.png
59
+ - lib/media/cursor.png
60
+ - lib/media/sea.png
61
+ - lib/media/ground.png
62
+ - lib/save/m02.esf
63
+ - lib/save/m01.esf
64
+ - lib/save/m03.esf
65
+ - lib/ship.rb
66
+ - lib/unit.rb
67
+ - lib/unitFunction.rb
68
+ - lib/town.rb
69
+ - lib/map.rb
70
+ - lib/army.rb
71
+ - lib/cursor.rb
72
+ - lib/infopane.rb
73
+ - lib/empi.rb
74
+ homepage: http://www.bay12forums.com/smf/index.php?topic=157538.0
75
+ licenses:
76
+ - CC-BY-SA 3.0
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 1.8.23
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Turn-based wargame
99
+ test_files: []