Class: Unit

Inherits:
Object
  • Object
show all
Defined in:
lib/lib/units/unit.rb

Overview

Both capturable and movable game pieces

Direct Known Subclasses

Army, Ship, Town

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x, y, faction, map, infopane) ⇒ Unit

Returns a new instance of Unit.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/lib/units/unit.rb', line 11

def initialize(x, y, faction, map, infopane)
  @x = x
  @y = y
  @faction = faction
  @map = map
  @infopane = infopane

  @armor_max = 1
  @armor_left = @armor_max
  @moves_max = 1
  @moves_left = @moves_max
  @cargo = [] # transported units
  @cargo_max = 0
  @function = UnitFunction.new(FUNCNONE, self)

  # Store yourself
  coords_unit = @map.get_unit(@x, @y)
  if !coords_unit
    @map.set_unit(@x, @y, self)
  else # some town has just built you
    coords_unit.cargo.insert(-1, self) # -1 = to the end
  end
end

Class Attribute Details

.map_symbolObject (readonly)

Returns the value of attribute map_symbol.



6
7
8
# File 'lib/lib/units/unit.rb', line 6

def map_symbol
  @map_symbol
end

.nameObject (readonly)

Returns the value of attribute name.



6
7
8
# File 'lib/lib/units/unit.rb', line 6

def name
  @name
end

.priceObject (readonly)

Returns the value of attribute price.



6
7
8
# File 'lib/lib/units/unit.rb', line 6

def price
  @price
end

.valueObject (readonly)

Returns the value of attribute value.



6
7
8
# File 'lib/lib/units/unit.rb', line 6

def value
  @value
end

Instance Attribute Details

#cargoObject

Returns the value of attribute cargo.



9
10
11
# File 'lib/lib/units/unit.rb', line 9

def cargo
  @cargo
end

#cargo_maxObject

Returns the value of attribute cargo_max.



9
10
11
# File 'lib/lib/units/unit.rb', line 9

def cargo_max
  @cargo_max
end

#factionObject

Returns the value of attribute faction.



9
10
11
# File 'lib/lib/units/unit.rb', line 9

def faction
  @faction
end

#functionObject

Returns the value of attribute function.



9
10
11
# File 'lib/lib/units/unit.rb', line 9

def function
  @function
end

#xObject

Returns the value of attribute x.



9
10
11
# File 'lib/lib/units/unit.rb', line 9

def x
  @x
end

#yObject

Returns the value of attribute y.



9
10
11
# File 'lib/lib/units/unit.rb', line 9

def y
  @y
end

Instance Method Details

#attack!(by_whom) ⇒ Object

Process attack targeted at this unit



59
60
61
62
# File 'lib/lib/units/unit.rb', line 59

def attack!(by_whom)
  puts PROMPT + by_whom.to_s + ' is attacking ' + to_s
  destroy! # TODO proper combat
end

#can_be_built?Boolean

Returns:

  • (Boolean)


189
190
191
# File 'lib/lib/units/unit.rb', line 189

def can_be_built?
  self.class.price > 0
end

#can_be_captured?Boolean

Returns:

  • (Boolean)


213
214
215
# File 'lib/lib/units/unit.rb', line 213

def can_be_captured?
  false
end

#can_build?Boolean

Returns:

  • (Boolean)


185
186
187
# File 'lib/lib/units/unit.rb', line 185

def can_build?
  false
end

#can_capture?Boolean

Returns:

  • (Boolean)


209
210
211
# File 'lib/lib/units/unit.rb', line 209

def can_capture?
  false
end

#can_fly?Boolean

Returns:

  • (Boolean)


173
174
175
# File 'lib/lib/units/unit.rb', line 173

def can_fly?
  false
end

#can_move?Boolean

Returns:

  • (Boolean)


169
170
171
# File 'lib/lib/units/unit.rb', line 169

def can_move?
  (can_fly? || can_sail? || can_ride?) && @moves_left > 0
end

#can_ride?Boolean

Returns:

  • (Boolean)


181
182
183
# File 'lib/lib/units/unit.rb', line 181

def can_ride?
  false
end

#can_sail?Boolean

Returns:

  • (Boolean)


177
178
179
# File 'lib/lib/units/unit.rb', line 177

def can_sail?
  false
end

#can_transport?Boolean

Returns:

  • (Boolean)


193
194
195
# File 'lib/lib/units/unit.rb', line 193

def can_transport?
  @cargo_max > 0
end

#capture!(by_whom) ⇒ Object

Process capture targeted at this unit



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/lib/units/unit.rb', line 65

def capture!(by_whom)
  unless can_be_captured?
    abort("unit.capture!(): This unit can\'t be captured")
  end

  if by_whom == @faction
    abort("unit.capture!(): This unit already belongs to faction #{@faction}")
  end

  # Add <value> to the capturing faction
  @infopane.add_score(by_whom - 1, self.class.value)
  @faction = by_whom
end

#check_movement(old_x, old_y) ⇒ Object

Process move of unit and take care of its (un)loading or start of engagement



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/lib/units/unit.rb', line 95

def check_movement(old_x, old_y)
  if @x != old_x || @y != old_y # only if it moved
    if @moves_left <= 0
      abort("unit.check_movement(): Moving unit does not have enough move points (#{@moves_left} moves)")
    end

    oldcoords_unit = @map.get_unit(old_x, old_y)
    newcoords_unit = @map.get_unit(@x, @y)

    # If there is nobody or is there friendly unit with some cargo space (and bigger cargo space)
    if !newcoords_unit || \
      (newcoords_unit.faction == @faction && \
       newcoords_unit.can_transport? && \
       @cargo_max < newcoords_unit.cargo_max && \
       !newcoords_unit.is_full?)

      # Leave old coordinates
      if oldcoords_unit == self
        @map.set_unit(old_x, old_y, nil)
      else # if you have been transported
        oldcoords_unit.cargo.delete(self)
      end

      # Get to new coordinates
      if !newcoords_unit
        @map.set_unit(@x, @y, self)
        @cargo.each { |uu|
          uu.x = @x
          uu.y = @y
        }

      else # if you are going to be transported
        newcoords_unit.cargo.insert(-1, self) # -1 = to the end
        puts PROMPT + to_s + ' got loaded into '+ newcoords_unit.to_s
        @moves_left = 1 unless newcoords_unit.can_build? # use all your left moves unless you are getting loaded into a town
      end

    else # if there already is somebody that can't transport you (enemy or full friend)
      # Stay on your original tile
      @x = old_x
      @y = old_y

      # If it was a friend unit
      if newcoords_unit.faction == @faction
        if !newcoords_unit.can_transport?
          puts PROMPT + newcoords_unit.to_s + ' can\'t transport other units'
        else
          if @cargo_max >= newcoords_unit.cargo_max
            puts PROMPT + "#{self.class.name} can\'t fit in #{newcoords_unit.class.name}"
          else # thus newcoords_unit.is_full? is true
            puts PROMPT + newcoords_unit.to_s + ' is already full'
          end
        end
      else
        # Enemy!
        newcoords_unit.engage!(self)
      end
    end
    @moves_left -= 1

    # Check if you are on an invalid type of terrain (unless transported)
    unless is_terrain_suitable?
      puts PROMPT + to_s + " found itself in a bad place"
      destroy!
    end
  end
end

#destroy!Object

Add <value> to the other faction and remove links to given unit



80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/lib/units/unit.rb', line 80

def destroy!
  # If you are transporting somebody, destroy them first
  @cargo.each { |uu| uu.destroy! }

  @infopane.add_score(3 - @faction - 1, self.class.value) # TODO more factions?

  if is_transported?
    coords_unit = @map.get_unit(@x, @y)
    coords_unit.cargo -= [self]
  else
    @map.set_unit(@x, @y, nil)
  end
end

#drawObject



164
165
166
167
# File 'lib/lib/units/unit.rb', line 164

def draw
  @image.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZUNIT,
              scale_x = 1, scale_y = 1, color = COLOUR[@faction])
end

#engage!(by_whom) ⇒ Object

Process engagement targeted at this unit



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/lib/units/unit.rb', line 36

def engage!(by_whom)
  if by_whom == @faction
    abort("unit.engage!(): Engaging unit is of the same faction as this one (#{@faction})")
  end

  # Can it be captured and is it without defenders?
  if can_be_captured?
    if is_transporting?
      cargo[0].attack!(by_whom)
    else # then capture it if you can
      if by_whom.can_capture?
        puts PROMPT + by_whom.to_s + ' is capturing ' + to_s
        capture!(by_whom.faction)
      else
        puts PROMPT + by_whom.to_s + ' can\'t capture other units'
      end
    end
  else
    attack!(by_whom) # uncapturable transporters can't get help from their cargo
  end
end

#function!Object



254
255
256
257
# File 'lib/lib/units/unit.rb', line 254

def function!
  ret = @function.func!(@map, @infopane)
  puts to_s + ret
end

#infoObject

Set long info string: short info string, armor, moves, function, cargo



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/lib/units/unit.rb', line 265

def info
  ret = to_s + ": armor #{@armor_left}/#{@armor_max}"

  if @moves_max > 0
    ret = ret + ", moves #{@moves_left}/#{@moves_max}"
  end

  ret = ret + ", #{@function.info}"

  if @cargo_max > 0
    ret = ret + ", cargo #{@cargo.size}/#{@cargo_max}"
  end

  ret
end

#is_full?Boolean

Returns:

  • (Boolean)


197
198
199
# File 'lib/lib/units/unit.rb', line 197

def is_full?
   @cargo.size >= @cargo_max # just == should be enough
end

#is_terrain_suitable?Boolean

Checks if unit is on the right type of terrain (not for transported units)

Returns:

  • (Boolean)


218
219
220
221
222
223
224
225
226
227
228
# File 'lib/lib/units/unit.rb', line 218

def is_terrain_suitable?
  unless is_transported?
    case @map.tile(@x, @y).terrain
    when TILE_SEA
      return can_fly? || can_sail?
    when TILE_GROUND
      return can_fly? || can_ride?
    end
  end
  true
end

#is_transported?Boolean

Returns:

  • (Boolean)


205
206
207
# File 'lib/lib/units/unit.rb', line 205

def is_transported?
  @map.get_unit(@x, @y) != self
end

#is_transporting?Boolean

Returns:

  • (Boolean)


201
202
203
# File 'lib/lib/units/unit.rb', line 201

def is_transporting?
  @cargo.size > 0
end

#reset_moves!Object



281
282
283
# File 'lib/lib/units/unit.rb', line 281

def reset_moves!
  @moves_left = @moves_max
end

#set_function!(func) ⇒ Object

Set desired function



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/lib/units/unit.rb', line 235

def set_function!(func)
  if @faction == 0
    puts PROMPT + to_s + ": neutral towns can't have functions set"
  else
    if func == FUNCBUILD and !can_build?
      puts PROMPT + to_s + ": this unit can't build other units"
      return
    end

    # Check current function and set the new one
    if @function.func == func
      puts PROMPT + to_s + ": function is already set to #{@function.func}"
    else
      @function.func = func
      puts PROMPT + to_s + ": function set to #{@function.func}"
    end
  end
end

#to_sObject

Set short info string: type, faction, coordinates



260
261
262
# File 'lib/lib/units/unit.rb', line 260

def to_s
  "#{self.class.name} (FAC#{@faction} #{@x}-#{@y})"
end