class Unit

Both capturable and movable game pieces

Attributes

map_symbol[R]
name[R]
price[R]
value[R]
armour_left[R]
cargo[RW]
cargo_max[RW]
faction[RW]
function[RW]
x[RW]
y[RW]

Public Class Methods

new(x, y, faction, map, infopane) click to toggle source
# File lib/lib/units/unit.rb, line 12
def initialize(x, y, faction, map, infopane)
  @x = x
  @y = y
  @faction = faction
  @map = map
  @infopane = infopane

  @armour_max = 1
  @armour_left = @armour_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

Public Instance Methods

attack!(by_whom) click to toggle source

Process attack targeted at this unit

# File lib/lib/units/unit.rb, line 60
def attack!(by_whom)
  puts PROMPT + by_whom.to_s + ' is attacking ' + to_s
  destroy! # TODO proper combat
end
can_be_built?() click to toggle source
# File lib/lib/units/unit.rb, line 198
def can_be_built?
  self.class.price > 0
end
can_be_captured?() click to toggle source
# File lib/lib/units/unit.rb, line 222
def can_be_captured?
  false
end
can_build?() click to toggle source
# File lib/lib/units/unit.rb, line 194
def can_build?
  false
end
can_capture?() click to toggle source
# File lib/lib/units/unit.rb, line 218
def can_capture?
  false
end
can_fly?() click to toggle source
# File lib/lib/units/unit.rb, line 182
def can_fly?
  false
end
can_move?() click to toggle source
# File lib/lib/units/unit.rb, line 178
def can_move?
  (can_fly? || can_sail? || can_ride?) && @moves_left > 0
end
can_ride?() click to toggle source
# File lib/lib/units/unit.rb, line 190
def can_ride?
  false
end
can_sail?() click to toggle source
# File lib/lib/units/unit.rb, line 186
def can_sail?
  false
end
can_transport?() click to toggle source
# File lib/lib/units/unit.rb, line 202
def can_transport?
  @cargo_max > 0
end
capture!(by_whom) click to toggle source

Process capture targeted at this unit

# File lib/lib/units/unit.rb, line 66
def capture!(by_whom)
  unless can_be_captured?
    abort("Unit.capture!(): This unit can\'t be captured")
  end

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

  # Add <value> to the capturing faction
  @infopane.add_score(by_whom.faction - 1, self.class.value)
  @faction = by_whom.faction
end
check_movement(old_x, old_y) click to toggle source

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

# File lib/lib/units/unit.rb, line 98
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)
      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

      # Update position of your cargo
      @cargo.each { |uu|
        uu.x = @x
        uu.y = @y
      }

    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!() click to toggle source

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

# File lib/lib/units/unit.rb, line 81
def destroy!
  @armour_left = 0 # for non-attack damage

  # 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
draw() click to toggle source
# File lib/lib/units/unit.rb, line 167
def draw
  @image.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZUNIT,
              scale_x = 1, scale_y = 1, color = COLOUR[@faction])
end
engage!(by_whom) click to toggle source

Process engagement targeted at this unit

# File lib/lib/units/unit.rb, line 37
def engage!(by_whom)
  if by_whom.faction == @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)
      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!() click to toggle source
# File lib/lib/units/unit.rb, line 272
def function!
  ret = @function.func!(@map, @infopane)
  puts to_s + ret
end
info() click to toggle source

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

# File lib/lib/units/unit.rb, line 283
def info
  ret = to_s + ": armour #{@armour_left}/#{@armour_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?() click to toggle source
# File lib/lib/units/unit.rb, line 206
def is_full?
   @cargo.size >= @cargo_max # just == should be enough
end
is_terrain_suitable?() click to toggle source

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

# File lib/lib/units/unit.rb, line 227
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?() click to toggle source
# File lib/lib/units/unit.rb, line 214
def is_transported?
  @map.get_unit(@x, @y) != self
end
is_transporting?() click to toggle source
# File lib/lib/units/unit.rb, line 210
def is_transporting?
  @cargo.size > 0
end
is_waiting_for_commands?() click to toggle source
# File lib/lib/units/unit.rb, line 172
def is_waiting_for_commands?
  @faction == @infopane.faction and
  function == FUNCNONE and
  can_move?
end
reset_moves!() click to toggle source
# File lib/lib/units/unit.rb, line 299
def reset_moves!
  @moves_left = @moves_max
end
set_function!(func, commanding_faction) click to toggle source

Set desired function

# File lib/lib/units/unit.rb, line 244
def set_function!(func, commanding_faction)
  # Check your neutrality
  if @faction == 0
    puts PROMPT + to_s + ": neutral units can't have functions set"
    return
  end

  # Check origin of command
  if commanding_faction != @faction
    puts PROMPT + to_s + ": this unit does not take commands from other factions"
    return
  end

  # Check your abilities
  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
to_s() click to toggle source

Set short info string: type, faction, coordinates

# File lib/lib/units/unit.rb, line 278
def to_s
  "#{self.class.name} (FAC#{@faction} #{@x}-#{@y})"
end