Module: Api::UnitExtension

Defined in:
lib/sc2ai/protocol/extensions/unit.rb

Overview

Adds additional functionality to message object Api::Unit Mostly adds convenience methods by adding direct access to the Sc2::Bot data and api

Virtual properties collapse

Instance Attribute Summary collapse

Actions collapse

Instance Method Summary collapse

Instance Attribute Details

#botSc2::Player

Every unit gets access back to the bot to allow api access. For your own units, this allows API access.

Returns:



31
32
33
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 31

def bot
  @bot
end

#is_active?Boolean (readonly)

Returns:

  • (Boolean)


191
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 191

def is_active? = is_active

#is_blip?Boolean (readonly)

Returns:

  • (Boolean)


183
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 183

def is_blip? = is_blip

#is_burrowed?Boolean (readonly)

Returns:

  • (Boolean)


167
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 167

def is_burrowed? = is_burrowed

#is_flying?Boolean (readonly)

Returns:

  • (Boolean)


163
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 163

def is_flying? = is_flying

#is_ground?Boolean (readonly)

Returns whether the unit is grounded (not flying).

Returns:

  • (Boolean)


196
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 196

def is_ground? = !is_flying?

#is_hallucination?Boolean (readonly)

Returns:

  • (Boolean)


171
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 171

def is_hallucination? = is_hallucination

#is_on_screen?Boolean (readonly)

Returns:

  • (Boolean)


179
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 179

def is_on_screen? = is_on_screen

#is_powered?Boolean (readonly)

Returns:

  • (Boolean)


187
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 187

def is_powered? = is_powered

#is_selected?Boolean (readonly)

Returns:

  • (Boolean)


175
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 175

def is_selected? = is_selected

#widthFloat

width = radius * 2

Returns:

  • (Float)


152
153
154
155
156
157
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 152

def width = radius * 2
# @!parse
#   # @!attribute width
#   # width = radius * 2
#   # @return [Float]
#   attr_reader :width

Instance Method Details

#ability_available?(ability_id) ⇒ Boolean

Returns whether this unit has an ability available Queries API if necessary

Parameters:

  • ability_id (Integer)

Returns:

  • (Boolean)


455
456
457
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 455

def ability_available?(ability_id)
  @bot.unit_ability_available?(unit_tag: tag, ability_id:)
end

#action(ability_id:, target: nil, queue_command: false) ⇒ Object

Performs action on this unit

Parameters:

  • ability_id (Integer)
  • target (Api::Unit, Integer, Api::Point2D) (defaults to: nil)

    is a unit, unit tag or a Api::Point2D

  • queue_command (Boolean) (defaults to: false)

    shift+command



215
216
217
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 215

def action(ability_id:, target: nil, queue_command: false)
  @bot.action(units: self, ability_id:, target:, queue_command:)
end

#add_onApi::Unit?

Returns the Api::Unit add-on (Reactor/Tech Lab), if present for this structure

Returns:

  • (Api::Unit, nil)

    the unit if an addon is present or nil if not present



535
536
537
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 535

def add_on
  @add_on ||= @bot.structures[add_on_tag]
end

#attack(target:, queue_command: false) ⇒ Object

Shorthand for performing action ATTACK

Parameters:

  • target (Api::Unit, Integer, Api::Point2D)

    is a unit, unit tag or a Api::Point2D

  • queue_command (Boolean) (defaults to: false)

    shift+command



249
250
251
252
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 249

def attack(target:, queue_command: false)
  return false if target.nil?
  action(ability_id: Api::AbilityId::ATTACK, target:, queue_command:)
end

#attack_with(units:, queue_command: false) ⇒ void

This method returns an undefined value.

Inverse of #attack, where you target self using another unit (source_unit)

Parameters:

  • units (Api::Unit, Sc2::UnitGroup)

    a unit or unit group

  • queue_command (Boolean) (defaults to: false)

    shift+command



258
259
260
261
262
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 258

def attack_with(units:, queue_command: false)
  return unless units.is_a?(Api::Unit) || units.is_a?(Sc2::UnitGroup)

  units.attack(target: self, queue_command:)
end

#attributesArray<Api::Attribute>

Returns static [Api::UnitTypeData] for a unit

Returns:



69
70
71
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 69

def attributes
  unit_data.attributes
end

#build(unit_type_id:, target: nil, queue_command: false) ⇒ Object Also known as: train

Builds target unit type, i.e. issuing a build command to worker.build(…Api::UnitTypeId::BARRACKS)

Parameters:

  • unit_type_id (Integer)

    Api::UnitTypeId the unit type you wish to build

  • target (Api::Point2D, Api::Unit, Integer, nil) (defaults to: nil)

    is a unit tag or a Api::Point2D. Nil for addons/orbital

  • queue_command (Boolean) (defaults to: false)

    shift+command



268
269
270
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 268

def build(unit_type_id:, target: nil, queue_command: false)
  @bot.build(units: self, unit_type_id:, target:, queue_command:)
end

#build_reactor(queue_command: false) ⇒ void

This method returns an undefined value.

For Terran builds a tech lab add-on on the current structure



558
559
560
561
562
563
564
565
566
567
568
569
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 558

def build_reactor(queue_command: false)
  unit_type_id = case unit_type
  when Api::UnitTypeId::BARRACKS, Api::UnitTypeId::BARRACKSFLYING
    Api::UnitTypeId::BARRACKSREACTOR
  when Api::UnitTypeId::FACTORY, Api::UnitTypeId::FACTORYFLYING
    Api::UnitTypeId::FACTORYREACTOR
  when Api::UnitTypeId::STARPORT, Api::UnitTypeId::STARPORTFLYING
    Api::UnitTypeId::STARPORTREACTOR
  end

  build(unit_type_id: unit_type_id, target: target_for_addon_placement, queue_command:)
end

#build_tech_lab(queue_command: false) ⇒ void

This method returns an undefined value.

For Terran builds a tech lab add-on on the current structure



573
574
575
576
577
578
579
580
581
582
583
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 573

def build_tech_lab(queue_command: false)
  unit_type_id = case unit_type
  when Api::UnitTypeId::BARRACKS, Api::UnitTypeId::BARRACKSFLYING
    Api::UnitTypeId::BARRACKSTECHLAB
  when Api::UnitTypeId::FACTORY, Api::UnitTypeId::FACTORYFLYING
    Api::UnitTypeId::FACTORYTECHLAB
  when Api::UnitTypeId::STARPORT, Api::UnitTypeId::STARPORTFLYING
    Api::UnitTypeId::STARPORTTECHLAB
  end
  build(unit_type_id: unit_type_id, target: target_for_addon_placement, queue_command:)
end

#can_ability_target_unit?(unit:, ability:) ⇒ Boolean

Returns:

  • (Boolean)


474
475
476
477
478
479
480
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 474

def can_ability_target_unit?(unit:, ability:)
  # false if enemy is air and we can only shoot ground
  return false if ability.target == Api::AbilityData::Target::None

  # Check if weapon and unit models are in range
  in_attack_range?(unit:, range: ability.cast_range)
end

#can_attack?(unit:, weapon_index: 0, ability_id: nil) ⇒ Boolean

Checks whether enemy is within range of weapon or ability and can target ground/air. Defaults to basic weapon. Pass in ability to override

Examples:

ghost.can_attack?(enemy, weapon_index: 0, ability_id: Api::AbilityId::SNIPE)

Parameters:

  • unit (Api::Unit)

    enemy

  • weapon_index (Integer) (defaults to: 0)

    defaults to 0 which is it’s basic weapon for it’s current form

  • ability_id (Integer) (defaults to: nil)

    passing this will override weapon Api::AbilityId::*

Returns:

  • (Boolean)


439
440
441
442
443
444
445
446
447
448
449
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 439

def can_attack?(unit:, weapon_index: 0, ability_id: nil)
  if ability_id.nil?
    # weapon
    source_weapon = weapon(weapon_index)
    can_weapon_target_unit?(unit:, weapon: source_weapon)
  else
    # ability
    ability = @bot.ability_data(ability_id)
    can_ability_target_unit?(unit:, ability:)
  end
end

#can_weapon_target_unit?(unit:, weapon:) ⇒ Boolean

Checks whether a weapon can target a unit

Parameters:

Returns:

  • (Boolean)


463
464
465
466
467
468
469
470
471
472
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 463

def can_weapon_target_unit?(unit:, weapon:)
  # false if enemy is air and we can only shoot ground
  return false if unit.is_flying && weapon.type == :Ground # Api::Weapon::TargetType::Ground

  # false if enemy is ground and we can only shoot air
  return false if unit.is_ground? && weapon.type == :Air # A pi::Weapon::TargetType::Air

  # Check if weapon and unit models are in range
  in_attack_range?(unit:, range: weapon.range)
end

#debug_draw_placement(color = nil) ⇒ void

This method returns an undefined value.

Draws a placement outline noinspection RubyArgCount

Parameters:

  • color (Api::Color) (defaults to: nil)

    optional api color, default white



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 301

def debug_draw_placement(color = nil)
  # Slightly elevate the Z position so that the line doesn't clip into the terrain at same Z level
  z_elevated = pos.z + 0.01
  offset = footprint_radius
  # Box corners
  p0 = Api::Point.new(x: pos.x - offset, y: pos.y - offset, z: z_elevated)
  p1 = Api::Point.new(x: pos.x - offset, y: pos.y + offset, z: z_elevated)
  p2 = Api::Point.new(x: pos.x + offset, y: pos.y + offset, z: z_elevated)
  p3 = Api::Point.new(x: pos.x + offset, y: pos.y - offset, z: z_elevated)
  @bot.queue_debug_command Api::DebugCommand.new(
    draw: Api::DebugDraw.new(
      lines: [
        Api::DebugLine.new(
          color:,
          line: Api::Line.new(p0:, p1:)
        ),
        Api::DebugLine.new(
          color:,
          line: Api::Line.new(p0: p2, p1: p3)
        ),
        Api::DebugLine.new(
          color:,
          line: Api::Line.new(p0:, p1: p3)
        ),
        Api::DebugLine.new(
          color:,
          line: Api::Line.new(p0: p1, p1: p2)
        )
      ]
    )
  )
end

#debug_fire_range(weapon_index = 0, color = nil) ⇒ Object

Draws a sphere around the unit’s attack range

Parameters:

  • weapon_index (Api::Color) (defaults to: 0)

    default first weapon, see UnitTypeData.weapons

  • color (Api::Color) (defaults to: nil)

    optional api color, default red



337
338
339
340
341
342
343
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 337

def debug_fire_range(weapon_index = 0, color = nil)
  color = Api::Color.new(r: 255, b: 0, g: 0) if color.nil?
  attack_range = unit_data.weapons[weapon_index].range
  raised_position = pos.dup
  raised_position.z += 0.01
  @bot.debug_draw_sphere(point: raised_position, radius: attack_range, color:)
end

#distance_to(other) ⇒ Object

Calculates the distance between self and other



349
350
351
352
353
354
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 349

def distance_to(other)
  return 0.0 if other.nil? || other == self

  other = other.pos unless other.is_a? Sc2::Position
  pos.distance_to(other)
end

#footprint_radiusFloat

The placement size, by looking up unit’s creation ability, then game ability data This value should be correct for building placement math (unit.radius is not good for this)

Returns:

  • (Float)

    placement radius



513
514
515
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 513

def footprint_radius
  @bot.data.abilities[unit_data.ability_id].footprint_radius
end

#has_attribute?(attribute) ⇒ Boolean

Checks unit data for an attribute value

Examples:

unit.has_attribute?(Api::Attribute::Mechanical)
unit.has_attribute?(:Mechanical)

Returns:

  • (Boolean)

    whether unit has attribute



78
79
80
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 78

def has_attribute?(attribute)
  attributes.include? attribute
end

#has_buff?(buff_id) ⇒ Boolean

Whether unit is effected by buff_id

Examples:

unit.has_buff??(Api::BuffId::QUEENSPAWNLARVATIMER)

Parameters:

  • buff_id (Integer)

Returns:

  • (Boolean)


205
206
207
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 205

def has_buff?(buff_id)
  buff_ids.include?(buff_id)
end

#has_reactor?Boolean

Returns whether the structure has a reactor add-on

Returns:

  • (Boolean)

    if the unit has a reactor attached



541
542
543
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 541

def has_reactor?
  Sc2::UnitGroup::TYPE_REACTOR.include?(add_on&.unit_type)
end

#has_tech_lab?Boolean

Returns whether the structure has a tech lab add-on

Examples:

# Find the first Starport with a techlab
sp = structures.select_type(Api::UnitTypeId::STARPORT).find(&:has_tech_lab)
# Get the actual tech-lab with #add_on
sp.add_on.research ...

Returns:

  • (Boolean)

    if the unit has a tech lab attached



552
553
554
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 552

def has_tech_lab?
  Sc2::UnitGroup::TYPE_TECHLAB.include?(add_on&.unit_type)
end

#hashObject



8
9
10
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 8

def hash
  tag || super
end

#hold(queue_command: false) ⇒ Object Also known as: hold_position

Shorthand for performing action HOLDPOSITION

Parameters:

  • queue_command (Boolean) (defaults to: false)

    shift+command



241
242
243
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 241

def hold(queue_command: false)
  action(ability_id: Api::AbilityId::HOLDPOSITION, queue_command:)
end

#in_attack_range?(unit:, range: nil) ⇒ Boolean

Checks whether opposing unit is in the attack range.

Parameters:

  • unit (Api::Unit)
  • range (Float, nil) (defaults to: nil)

    nil. will use default weapon range if nothing provided

Returns:

  • (Boolean)


486
487
488
489
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 486

def in_attack_range?(unit:, range: nil)
  range = weapon.range if range.nil?
  distance_to(unit) <= radius + unit.radius + range
end

#in_circle?(point:, radius:) ⇒ Boolean

Detects whether a unit is within a given circle

Parameters:

Returns:

  • (Boolean)


375
376
377
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 375

def in_circle?(point:, radius:)
  distance_to(point) <= radius
end

#in_progress?Boolean

Returns true if build progress is < 100%

Returns:

  • (Boolean)


525
526
527
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 525

def in_progress?
  !is_completed?
end

#is_alive?Boolean

Returns whether a unit is alive or not Useful for cached Unit objects to see if they are still relevant.

Returns:

  • (Boolean)

    alive



48
49
50
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 48

def is_alive?
  !@bot.all_units[tag].nil?
end

#is_armored?Boolean

Checks if unit is armored

Returns:

  • (Boolean)

    whether unit has attribute :Armored



90
91
92
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 90

def is_armored?
  has_attribute?(:Armored)
end

#is_attacking?(target: nil) ⇒ Boolean

Returns whether unit is currently engaged with another

Parameters:

  • target (Api::Unit, Integer) (defaults to: nil)

    optionally check if unit is engaged with specific target

Returns:

  • (Boolean)


381
382
383
384
385
386
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 381

def is_attacking?(target: nil)
  is_performing_ability_on_target?(
    [Api::AbilityId::ATTACK_ATTACK, Api::AbilityId::ATTACK],
    target:
  )
end

#is_biological?Boolean

Checks if unit is biological

Returns:

  • (Boolean)

    whether unit has attribute :Biological



96
97
98
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 96

def is_biological?
  has_attribute?(:Biological)
end

#is_completed?Boolean

Returns true if build progress is 100%

Returns:

  • (Boolean)


519
520
521
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 519

def is_completed?
  build_progress == 1.0 # standard:disable Lint/FloatComparison
end

#is_engaged_with?(unit) ⇒ Boolean

Returns whether engaged_target_tag or the current order matches supplied unit

Parameters:

  • unit (Api::Unit, Integer)

    optionally check if unit is engaged with specific target

Returns:

  • (Boolean)


419
420
421
422
423
424
425
426
427
428
429
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 419

def is_engaged_with?(unit)
  # First match on unit#engaged_target_tag, since it's solid for attacks
  unit = unit.tag if unit.is_a? Api::Unit
  return true if engaged_target_tag == unit

  # Alternatively, check your order to see if your command ties you to the unit
  # It may not be in distance or actively performing, just yet.
  return orders.first.target_unit_tag == unit unless orders.empty?

  false
end

#is_harvesting?Boolean

Checks whether a unit is gathering or returning gathered minerals/gas

Returns:

  • (Boolean)

    true if either gathering or returning, false otherwise



400
401
402
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 400

def is_harvesting?
  is_performing_ability?([Api::AbilityId::HARVEST_GATHER, Api::AbilityId::HARVEST_RETURN])
end

#is_heroic?Boolean

Checks if unit is heroic

Returns:

  • (Boolean)

    whether unit has attribute :Heroic



138
139
140
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 138

def is_heroic?
  has_attribute?(:Heroic)
end

#is_hover?Boolean

Checks if unit is hover

Returns:

  • (Boolean)

    whether unit has attribute :Hover



132
133
134
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 132

def is_hover?
  has_attribute?(:Hover)
end

#is_idle?Boolean

Returns true if unit does not have orders

Returns:

  • (Boolean)

    whether unit is idle



614
615
616
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 614

def is_idle?
  orders.empty?
end

#is_light?Boolean

Checks if unit is light

Returns:

  • (Boolean)

    whether unit has attribute :Light



84
85
86
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 84

def is_light?
  has_attribute?(:Light)
end

#is_massive?Boolean

Checks if unit is massive

Returns:

  • (Boolean)

    whether unit has attribute :Massive



120
121
122
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 120

def is_massive?
  has_attribute?(:Massive)
end

#is_mechanical?Boolean

Checks if unit is mechanical

Returns:

  • (Boolean)

    whether unit has attribute :Mechanical



102
103
104
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 102

def is_mechanical?
  has_attribute?(:Mechanical)
end

#is_performing_ability?(ability_ids) ⇒ Boolean

Checks whether a unit’s first order for ability

Parameters:

  • ability_ids (Integer, Array<Integer>)

    accepts one or an array of Api::AbilityId

Returns:

  • (Boolean)


406
407
408
409
410
411
412
413
414
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 406

def is_performing_ability?(ability_ids)
  return false if orders.empty?

  if ability_ids.is_a? Array
    ability_ids.include?(orders.first&.ability_id)
  else
    ability_ids == orders.first&.ability_id
  end
end

#is_psionic?Boolean

Checks if unit is psionic

Returns:

  • (Boolean)

    whether unit has attribute :Psionic



114
115
116
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 114

def is_psionic?
  has_attribute?(:Psionic)
end

#is_repairing?(target: nil) ⇒ Boolean

Returns whether the unit’s current order is to repair and optionally check it’s target

Parameters:

  • target (Api::Unit, Integer) (defaults to: nil)

    optionally check if unit is engaged with specific target

Returns:

  • (Boolean)


391
392
393
394
395
396
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 391

def is_repairing?(target: nil)
  is_performing_ability_on_target?(
    [Api::AbilityId::EFFECT_REPAIR, Api::AbilityId::EFFECT_REPAIR_SCV, Api::AbilityId::EFFECT_REPAIR_MULE],
    target:
  )
end

#is_robotic?Boolean

Checks if unit is robotic

Returns:

  • (Boolean)

    whether unit has attribute :Robotic



108
109
110
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 108

def is_robotic?
  has_attribute?(:Robotic)
end

#is_structure?Boolean

Checks if unit is structure

Returns:

  • (Boolean)

    whether unit has attribute :Structure



126
127
128
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 126

def is_structure?
  has_attribute?(:Structure)
end

#is_summoned?Boolean

Checks if unit is summoned

Returns:

  • (Boolean)

    whether unit has attribute :Summoned



144
145
146
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 144

def is_summoned?
  has_attribute?(:Summoned)
end

#missing_harvestersInteger

For saturation counters on bases or gas, get the amount of missing harvesters required to saturate. For a unit to which this effect doesn’t apply, the amount is zero.

Returns:

  • (Integer)

    number of harvesters required to saturate this structure



503
504
505
506
507
508
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 503

def missing_harvesters
  return 0 if ideal_harvesters.zero?

  missing = ideal_harvesters - assigned_harvesters
  missing.positive? ? missing : 0
end

#move(target:, queue_command: false) ⇒ Object

Shorthand for performing action MOVE

Parameters:

  • target (Api::Unit, Integer, Api::Point2D)

    is a unit, unit tag or a Api::Point2D

  • queue_command (Boolean) (defaults to: false)

    shift+command



229
230
231
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 229

def move(target:, queue_command: false)
  action(ability_id: Api::AbilityId::MOVE, target:, queue_command:)
end

#nearest(units:, amount: nil) ⇒ Sc2::UnitGroup, ...

Gets the nearest amount of unit(s) from a group, relative to this unit Omitting amount returns a single Unit.

Parameters:

Returns:



361
362
363
364
365
366
367
368
369
370
371
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 361

def nearest(units:, amount: nil)
  amount = 1 if !amount.nil? && amount.to_i <= 0

  # Performs suboptimal if sending an array. Don't.
  if units.is_a? Array
    units = Sc2::UnitGroup.new(units)
    units.use_kdtree = false # we will not re-use it's distance cache
  end

  units.nearest_to(pos:, amount:)
end

#previousApi::Unit?

Get the unit as from the previous frame. Good for comparison.

Returns:

  • (Api::Unit, nil)

    this unit from the previous frame or nil if it wasn’t present



41
42
43
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 41

def previous
  @bot.previous.all_units[tag]
end

#refresh!Boolean

Replaces protobuf values with latest from game

Returns:

  • (Boolean)

    true if refreshed or false unchanged



54
55
56
57
58
59
60
61
62
63
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 54

def refresh!
  new_unit = @bot.all_units[tag]
  return false if new_unit.nil? || new_unit == self

  self.class.descriptor.entries.each do |entry|
    send(:"#{entry.name}=", new_unit.send(:method_missing, entry.name.to_sym))
  end

  true
end

#repair(target:, queue_command: false) ⇒ Object

Issues repair command on target

Parameters:

  • target (Api::Unit, Integer)

    is a unit or unit tag

  • queue_command (Boolean) (defaults to: false)

    shift+command



282
283
284
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 282

def repair(target:, queue_command: false)
  action(ability_id: Api::AbilityId::EFFECT_REPAIR, target:, queue_command:)
end

#research(upgrade_id:, queue_command: false) ⇒ Object

Research a specific upgrade

Parameters:

  • upgrade_id (Integer)

    Api::UnitTypeId the unit type you wish to research

  • queue_command (Boolean) (defaults to: false)

    shift+command



289
290
291
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 289

def research(upgrade_id:, queue_command: false)
  @bot.research(units: self, upgrade_id:, queue_command:)
end

#smart(target: nil, queue_command: false) ⇒ Object

Shorthand for performing action SMART (right-click)

Parameters:

  • target (Api::Unit, Integer, Api::Point2D) (defaults to: nil)

    is a unit, unit tag or a Api::Point2D

  • queue_command (Boolean) (defaults to: false)

    shift+command



222
223
224
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 222

def smart(target: nil, queue_command: false)
  action(ability_id: Api::AbilityId::SMART, target:, queue_command:)
end

#stop(queue_command: false) ⇒ Object

Shorthand for performing action STOP

Parameters:

  • queue_command (Boolean) (defaults to: false)

    shift+command



235
236
237
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 235

def stop(queue_command: false)
  action(ability_id: Api::AbilityId::STOP, queue_command:)
end

#tagInteger

Returns an integer unique identifier If the unit goes out of vision and is snapshot-able, they get a random id

  • Such a unit gets the same unit tag when it re-enters vision

Returns:

  • (Integer)


16
17
18
19
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 16

def tag
  # Perf: This speeds up hash and therefore common UnitGroup operations. Sometimes 3x!
  @tag ||= send(:method_missing, :tag)
end

#tag=(tag) ⇒ Integer

Sets unit tag

Returns:

  • (Integer)


23
24
25
26
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 23

def tag=(tag)
  send(:method_missing, :tag=, tag)
  @tag = tag
end

#unit_dataApi::UnitTypeData

Returns static [Api::UnitTypeData] for a unit

Returns:



35
36
37
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 35

def unit_data
  @bot.data.units[unit_type]
end

#warp(unit_type_id:, target:, queue_command: false) ⇒ Object

Warps in unit type at target (location or pylon) Only works if the source is a Warp Gate

Parameters:

  • unit_type_id (Integer)

    Api::UnitTypeId the unit type you wish to build

  • target (Api::Point2D)

    a point, which should be inside an energy source

  • queue_command (Boolean) (defaults to: false)

    shift+command



606
607
608
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 606

def warp(unit_type_id:, target:, queue_command: false)
  @bot.warp(units: self, unit_type_id:, target:, queue_command:)
end

#weapon(index = 0) ⇒ Api::Weapon

Gets a weapon for this unit at index (default weapon is index 0)

Parameters:

  • index (Integer) (defaults to: 0)

    default 0

Returns:



494
495
496
# File 'lib/sc2ai/protocol/extensions/unit.rb', line 494

def weapon(index = 0)
  unit_data.weapons[index]
end