Class: Cursor

Inherits:
Object
  • Object
show all
Defined in:
lib/lib/user_interface/cursor.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x, y, map, infopane) ⇒ Cursor

Returns a new instance of Cursor.



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/lib/user_interface/cursor.rb', line 4

def initialize(x, y, map, infopane)
  dir_path = File.dirname(__FILE__)

  @x = x
  @y = y
  @map = map
  @infopane = infopane

  @image = Gosu::Image.new(dir_path + '/../../media/cursor.png')
  @freeroam = false
  @info_stopped = false

  # Give to Infopane link to yourself (for freeroam marker)
  if !@infopane
    abort("Cursor.initialize(): Infopane is not set")
  end
  @infopane.cursor = self
end

Instance Attribute Details

#freeroamObject

Returns the value of attribute freeroam.



2
3
4
# File 'lib/lib/user_interface/cursor.rb', line 2

def freeroam
  @freeroam
end

#info_stoppedObject

Returns the value of attribute info_stopped.



2
3
4
# File 'lib/lib/user_interface/cursor.rb', line 2

def info_stopped
  @info_stopped
end

Instance Method Details

#check_unitObject

When cursor is in locked mode there needs to be unit it is locked to When cursor is in freeroam mode the locked unit should be kept



216
217
218
219
220
221
# File 'lib/lib/user_interface/cursor.rb', line 216

def check_unit
  if !@freeroam and !@locked_unit
    abort("Cursor.check_unit(): Cursor is in locked mode " \
          "but there is no unit it is locked to (at #{@x}-#{@y})")
  end
end

#cycle_to_other_unit!(search_forward = true) ⇒ Object

Cycle from selected unit to the next/previous local one



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/lib/user_interface/cursor.rb', line 188

def cycle_to_other_unit!(search_forward = true)
  unless @freeroam
    abort("Cursor.cycle_to_other_unit!():" \
          "cycling to #{ search_forward ? 'next' : 'previous'} " \
          "unit works only in freeroam mode, not in locked one")
  end

  unless @selected_unit
    @infopane.text = ''
    puts "no units to cycle through (at #{@x}-#{@y})"
    return
  end

  local_pile = @map.all_units_from_tile(@x, @y)

  # Pick the previous/next local unit, relative to the current one
  # (picking the previous of the first results in index -1 which is the last
  # so there it is fine but taking the next of the last would go out of range)
  current_index = local_pile.index(@selected_unit)
  other_index = search_forward ? current_index + 1 : current_index - 1
  other_index = 0 if other_index >= local_pile.size # == would be enough

  @selected_unit = local_pile[other_index]
  info
end

#drawObject



68
69
70
# File 'lib/lib/user_interface/cursor.rb', line 68

def draw
  @image.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZCURSOR)
end

#infoObject

Find some info about units on the current tile



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/lib/user_interface/cursor.rb', line 237

def info
  check_unit

  if @selected_unit
    @infopane.text = @selected_unit.info
    puts @selected_unit.info

    if @selected_unit.is_transporting?
      @selected_unit.cargo.each { |uu| puts '- cargo: ' + uu.info }
    end
  else
    @infopane.text = ''
    puts "no unit to show info of (at #{@x}-#{@y})"
  end
end

#move!(xx, yy) ⇒ Object

Move by given change of coordinates



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/lib/user_interface/cursor.rb', line 80

def move!(xx, yy)
  if freeroam
    @x += xx
    @y += yy
    @selected_unit = @map.get_unit(@x, @y)
    # TODO show some basic tile info in infopane
  else
    check_unit

    # Move the unit first
    @locked_unit.x += xx
    @locked_unit.y += yy
    @locked_unit.check_movement(@x, @y) # cursor coordinates work like old_x, old_y

    # Is the unit still alive?
    if @locked_unit.armour_left > 0
      warp_to_locked! # whether it moved or not
    else
      # It got destroyed so clear last links then so that (object of)
      # given unit can be truly destroyed
      @selected_unit = nil
      @locked_unit = nil
    end
  end
end

#reset!Object

Reset to locked mode



123
124
125
126
127
128
129
# File 'lib/lib/user_interface/cursor.rb', line 123

def reset!
  @freeroam = true
  switch_freeroam!
  @selected_unit = nil
  @locked_unit = nil
  to_next_unit!
end

#select_other_unit!(search_forward) ⇒ Object

Skip or cycle units, depending on cursor mode



158
159
160
161
162
163
164
# File 'lib/lib/user_interface/cursor.rb', line 158

def select_other_unit!(search_forward)
  unless @freeroam
    skip_to_other_unit!(search_forward)
  else
    cycle_to_other_unit!(search_forward)
  end
end

#set_function_to_unit(func) ⇒ Object

Tries to set function <func> to selected unit



107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/lib/user_interface/cursor.rb', line 107

def set_function_to_unit(func)
  check_unit

  if @selected_unit
    @selected_unit.set_function!(func, @infopane.faction)

    # Update infopane with the new (possibly changed) state
    # (visible only in freeroam mode as in locked one the infopane is
    # overwritten as cursor either jumps away or switches to freeroam mode)
    @infopane.text = @selected_unit.info
  else
    puts "no unit to set that function to (at #{@x}-#{@y})"
  end
end

#skip_to_other_unit!(search_forward = true) ⇒ Object

Skip from selected unit waiting for commands to the next/previous waiting one



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/lib/user_interface/cursor.rb', line 167

def skip_to_other_unit!(search_forward = true)
  if @freeroam
    abort("Cursor.skip_to_other_unit!(): " \
          "skipping to #{ search_forward ? 'next' : 'previous'} " \
          "unit works only in locked mode, not in freeroam one")
  end

  waiting = @map.all_units.select { |uu| uu.is_waiting_for_commands? }

  # Pick the previous/next waiting unit, relative to the current one
  # (picking the previous of the first results in index -1 which is the last
  # so there it is fine but taking the next of the last would go out of range)
  current_index = waiting.index(@selected_unit)
  other_index = search_forward ? current_index + 1 : current_index - 1
  other_index = 0 if other_index >= waiting.size # == would be enough

  @locked_unit = waiting[other_index]
  warp_to_locked! # so that to_next_unit!() doesn't stay at @selected_unit
end

#switch_freeroam!Object

Switch between being attached to unit and being able to freeroam



224
225
226
227
228
229
230
231
232
233
234
# File 'lib/lib/user_interface/cursor.rb', line 224

def switch_freeroam!
  if freeroam
    @infopane.text = 'freeroam disabled'
    puts 'freeroam disabled'
    @freeroam = false
  else
    @infopane.text = 'freeroam enabled'
    puts 'freeroam enabled'
    @freeroam = true
  end
end

#to_next_unit!Object

Find next unit which is still waiting for commands and lock to it (selected -> last locked to -> next waiting) or switch (back) to freeroaming



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/lib/user_interface/cursor.rb', line 133

def to_next_unit!
  if @selected_unit and @selected_unit.is_waiting_for_commands?
    # Lock to such unit (though it may have already been locked)
    @locked_unit = @selected_unit
  else
    unless @locked_unit and @locked_unit.is_waiting_for_commands?
      waiting = @map.all_units.select { |uu| uu.is_waiting_for_commands? }

      # Are there still some units of active faction waiting for commands?
      if waiting.size <= 0 # == would be enough
        puts 'all movable units without functions moved'
        switch_freeroam!
        return
      end

      # Pick the first waiting unit (leftmost of topmosts)
      @locked_unit = waiting[0]
    end
  end

  warp_to_locked! # stay at old or go to new
  info unless @info_stopped # due to switching out of the play game state
end

#update(button) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/lib/user_interface/cursor.rb', line 23

def update(button)
  case button
  # Cardinal directions
  when Gosu::KbLeft, Gosu::KbA, Gosu::KB_NUMPAD_4 then
    move!(-1, 0) unless @x <= 0
  when Gosu::KbRight, Gosu::KbD, Gosu::KB_NUMPAD_6 then
    move!(1, 0) unless @x >= MAPX
  when Gosu::KbUp, Gosu::KbW, Gosu::KB_NUMPAD_8 then
    move!(0, -1) unless @y <= 0
  when Gosu::KbDown, Gosu::KbX, Gosu::KB_NUMPAD_2 then
    move!(0, 1) unless @y >= MAPY

  # Intercardinal directions
  when Gosu::KbQ, Gosu::KB_NUMPAD_7 then
    move!(-1, -1) unless @x <= 0 || @y <= 0
  when Gosu::KbE, Gosu::KB_NUMPAD_9 then
    move!(1, -1) unless @x >= MAPX || @y <= 0
  when Gosu::KbZ, Gosu::KB_NUMPAD_1 then
    move!(-1, 1) unless @x <= 0 || @y >= MAPY
  when Gosu::KbC, Gosu::KB_NUMPAD_3 then
    move!(1, 1) unless @x >= MAPX || @y >= MAPY

  # Functions
  when Gosu::KbS then
    set_function_to_unit(FUNCSENTRY)
  when Gosu::KbB then
    set_function_to_unit(FUNCBUILD)
  when Gosu::KbN then
    set_function_to_unit(FUNCNONE)

  # The rest
  when Gosu::KbJ, Gosu::KB_NUMPAD_0 then
    switch_freeroam!
  when Gosu::KbK, Gosu::KB_NUMPAD_MINUS then
    select_other_unit!(false)
  when Gosu::KbL, Gosu::KB_NUMPAD_PLUS then
    select_other_unit!(true)
  when Gosu::KbReturn, Gosu::KB_NUMPAD_5 then
    info
  end

  # If in locked mode, stay at current/jump to next movable unit
  to_next_unit! unless @freeroam
end

#warp_to_locked!Object

Move to coordinates of map unit the cursor is locked to



73
74
75
76
77
# File 'lib/lib/user_interface/cursor.rb', line 73

def warp_to_locked!()
  @x = @locked_unit.x
  @y = @locked_unit.y
  @selected_unit = @locked_unit
end