sc2ai 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/data.json +1 -1
- data/data/data_readable.json +31 -28
- data/lib/sc2ai/api/data.rb +162 -2
- data/lib/sc2ai/api/tech_tree.rb +22 -0
- data/lib/sc2ai/api/tech_tree_data.rb +19 -8
- data/lib/sc2ai/connection.rb +1 -1
- data/lib/sc2ai/local_play/client_manager.rb +9 -1
- data/lib/sc2ai/player/actions.rb +17 -0
- data/lib/sc2ai/player/debug.rb +1 -0
- data/lib/sc2ai/player/geometry.rb +6 -0
- data/lib/sc2ai/player/previous_state.rb +2 -2
- data/lib/sc2ai/player/units.rb +75 -6
- data/lib/sc2ai/protocol/_meta_documentation.rb +2 -0
- data/lib/sc2ai/protocol/extensions/point_2_d.rb +6 -0
- data/lib/sc2ai/protocol/extensions/unit.rb +10 -3
- data/lib/sc2ai/protocol/extensions/unit_type_data.rb +20 -0
- data/lib/sc2ai/unit_group/action_ext.rb +9 -0
- data/lib/sc2ai/unit_group/filter_ext.rb +6 -0
- data/lib/sc2ai/unit_group.rb +9 -1
- data/lib/sc2ai/version.rb +1 -1
- data/lib/templates/new/run_example_match.rb.tt +1 -1
- data/sig/sc2ai.rbs +226 -27
- metadata +19 -4
data/lib/sc2ai/player/units.rb
CHANGED
@@ -30,6 +30,53 @@ module Sc2
|
|
30
30
|
# @return [Sc2::UnitGroup] a group of neutral units
|
31
31
|
attr_accessor :effects # not a unit
|
32
32
|
|
33
|
+
# Returns the upgrade ids you have acquired such as weapon upgrade and armor upgrade ids.
|
34
|
+
# Shorthand for observation.raw_data.player.upgrade_ids
|
35
|
+
# @!attribute [r] upgrades_completed
|
36
|
+
# @return [Array<Integer>] a group of neutral units
|
37
|
+
def upgrades_completed = observation&.raw_data&.player&.upgrade_ids.to_a || [] # not a unit
|
38
|
+
|
39
|
+
# Returns the upgrade ids which are researching or queued
|
40
|
+
# Not set for enemy.
|
41
|
+
# @return [Array<Integer>]
|
42
|
+
def upgrades_in_progress
|
43
|
+
# We need to scan every structure which performs upgrades for any order with an upgrade ability
|
44
|
+
|
45
|
+
result = []
|
46
|
+
# Loop every upgrade structure
|
47
|
+
structures
|
48
|
+
.select_type(Api::TechTree.upgrade_structure_unit_type_ids)
|
49
|
+
.each do |structure|
|
50
|
+
next unless structure.is_active? # Skip idle
|
51
|
+
|
52
|
+
# Check if any order at a structure contains an upgrade ability
|
53
|
+
structure.orders.each do |order|
|
54
|
+
Api::TechTree.upgrade_ability_data(structure.unit_type).each do |upgrade_id, update_info|
|
55
|
+
if update_info[:ability] == order.ability_id
|
56
|
+
# Save the upgrade_id
|
57
|
+
result << upgrade_id
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# If the API told use it's complete, but an order still lingers, trust the API
|
64
|
+
result - upgrades_completed
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the upgrade ids which are researching or queued
|
68
|
+
# @return [Boolean]
|
69
|
+
def upgrade_in_progress?(upgrade_id)
|
70
|
+
structure_unit_type_id = Api::TechTree.upgrade_researched_from(upgrade_id: upgrade_id)
|
71
|
+
research_ability_id = Api::TechTree.upgrade_research_ability_id(upgrade_id: upgrade_id)
|
72
|
+
structures.select_type(structure_unit_type_id).each do |structure|
|
73
|
+
structure.orders.each do |order|
|
74
|
+
return true if order.ability_id == research_ability_id
|
75
|
+
end
|
76
|
+
end
|
77
|
+
false
|
78
|
+
end
|
79
|
+
|
33
80
|
# An array of Protoss power sources, which have a point, radius and unit tag
|
34
81
|
# @!attribute power_sources
|
35
82
|
# @return [Array<Api::PowerSource>] an array of power sources
|
@@ -107,6 +154,13 @@ module Sc2
|
|
107
154
|
data.abilities[ability_id]
|
108
155
|
end
|
109
156
|
|
157
|
+
# Returns static [Api::UpgradeData] for an upgrade id
|
158
|
+
# @param upgrade_id [Integer] Api::UpgradeId::*
|
159
|
+
# @return [Api::UpgradeData]
|
160
|
+
def upgrade_data(upgrade_id)
|
161
|
+
data.upgrades[upgrade_id]
|
162
|
+
end
|
163
|
+
|
110
164
|
# Checks unit data for an attribute value
|
111
165
|
# @param unit [Integer,Api::Unit] Api::UnitTypeId or Api::Unit
|
112
166
|
# @param attribute [Symbol] Api::Attribute, i.e. Api::Attribute::Mechanical or :Mechanical
|
@@ -141,17 +195,13 @@ module Sc2
|
|
141
195
|
def subtract_cost(unit_type_id)
|
142
196
|
unit_type_data = unit_data(unit_type_id)
|
143
197
|
|
144
|
-
# food_required is a float. ensure half units are counted as full
|
145
|
-
# TODO: Extend UnitTypeData message. def food_required = unit_id == Api::UnitTypeId::ZERGLING ? 1 : send("method_missing", :food_required)
|
146
|
-
supply_cost = unit_type_data.food_required
|
147
|
-
supply_cost = 1 if unit_type_id == Api::UnitTypeId::ZERGLING
|
148
|
-
|
149
198
|
@spent_minerals += unit_type_data.mineral_cost
|
150
199
|
@spent_vespene += unit_type_data.vespene_cost
|
151
|
-
@spent_supply +=
|
200
|
+
@spent_supply += unit_type_data.food_required
|
152
201
|
end
|
153
202
|
|
154
203
|
# Checks whether you have the resources to construct quantity of unit type
|
204
|
+
# @return [Boolean]
|
155
205
|
def can_afford?(unit_type_id:, quantity: 1)
|
156
206
|
unit_type_data = unit_data(unit_type_id)
|
157
207
|
return false if unit_type_data.nil?
|
@@ -178,6 +228,25 @@ module Sc2
|
|
178
228
|
true
|
179
229
|
end
|
180
230
|
|
231
|
+
# Checks whether you have the resources to
|
232
|
+
# @return [Boolean]
|
233
|
+
def can_afford_upgrade?(upgrade_id)
|
234
|
+
unit_type_data = upgrade_data(upgrade_id)
|
235
|
+
return false if unit_type_data.nil?
|
236
|
+
|
237
|
+
mineral_cost = unit_type_data.mineral_cost
|
238
|
+
if common.minerals - spent_minerals < mineral_cost
|
239
|
+
return false # not enough minerals
|
240
|
+
end
|
241
|
+
|
242
|
+
vespene_cost = unit_type_data.vespene_cost
|
243
|
+
if common.vespene - spent_vespene < vespene_cost
|
244
|
+
return false # you require more vespene gas
|
245
|
+
end
|
246
|
+
|
247
|
+
true
|
248
|
+
end
|
249
|
+
|
181
250
|
private
|
182
251
|
|
183
252
|
# @private
|
@@ -21,6 +21,8 @@
|
|
21
21
|
# class Point < Google::Protobuf::AbstractMessage; end;
|
22
22
|
# # Protobuf virtual class.
|
23
23
|
# class Unit < Google::Protobuf::AbstractMessage; end;
|
24
|
+
# # Protobuf virtual class.
|
25
|
+
# class UnitTypeData < Google::Protobuf::AbstractMessage; end;
|
24
26
|
# end
|
25
27
|
|
26
28
|
# Protobuf enums ---
|
@@ -10,6 +10,12 @@ module Api
|
|
10
10
|
self.class == other.class && hash == other.hash
|
11
11
|
end
|
12
12
|
|
13
|
+
# Create a new 3d Point, by adding a y axis.
|
14
|
+
# @return [Api::Point]
|
15
|
+
def to_3d(z:)
|
16
|
+
Api::Point[x, y, z]
|
17
|
+
end
|
18
|
+
|
13
19
|
# Adds additional functionality to message class Api::Point2D
|
14
20
|
module ClassMethods
|
15
21
|
# Shorthand for creating an instance for [x, y]
|
@@ -37,9 +37,8 @@ module Api
|
|
37
37
|
# Checks unit data for an attribute value
|
38
38
|
# @return [Boolean] whether unit has attribute
|
39
39
|
# @example
|
40
|
-
# has_attribute?(Api::
|
41
|
-
# has_attribute?(
|
42
|
-
# has_attribute?(Api::UnitTypeId::SCV, :Mechanical)
|
40
|
+
# unit.has_attribute?(Api::Attribute::Mechanical)
|
41
|
+
# unit.has_attribute?(:Mechanical)
|
43
42
|
def has_attribute?(attribute)
|
44
43
|
attributes.include? attribute
|
45
44
|
end
|
@@ -233,10 +232,18 @@ module Api
|
|
233
232
|
|
234
233
|
# Issues repair command on target
|
235
234
|
# @param target [Api::Unit, Integer] is a unit or unit tag
|
235
|
+
# @param queue_command [Boolean] shift+command
|
236
236
|
def repair(target:, queue_command: false)
|
237
237
|
action(ability_id: Api::AbilityId::EFFECT_REPAIR, target:, queue_command:)
|
238
238
|
end
|
239
239
|
|
240
|
+
# Research a specific upgrade
|
241
|
+
# @param upgrade_id [Integer] Api::UnitTypeId the unit type which will do the creation
|
242
|
+
# @param queue_command [Boolean] shift+command
|
243
|
+
def research(upgrade_id:, queue_command: false)
|
244
|
+
@bot.research(units: self, upgrade_id:, queue_command:)
|
245
|
+
end
|
246
|
+
|
240
247
|
# @!endgroup Actions
|
241
248
|
#
|
242
249
|
# Debug ----
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Api
|
4
|
+
# Adds additional functionality to message object Api::UnitTypeData
|
5
|
+
module UnitTypeDataExtension
|
6
|
+
# @!attribute mineral_cost_sum
|
7
|
+
# Sum of all morphs mineral cost
|
8
|
+
# i.e. 550M Orbital command = 400M CC + 150M Upgrade
|
9
|
+
# i.e. 350M Hatchery = 50M Drone + 300M Build
|
10
|
+
# @return [Integer] sum of mineral costs
|
11
|
+
attr_accessor :mineral_cost_sum
|
12
|
+
|
13
|
+
# @!attribute vespene_cost_sum
|
14
|
+
# Sum of all morphs vespene gas cost
|
15
|
+
# i.e. 250G Broodlord = 100G Corruptor + 150G Morph
|
16
|
+
# @return [Integer] sum of vespene gas costs
|
17
|
+
attr_accessor :vespene_cost_sum
|
18
|
+
end
|
19
|
+
end
|
20
|
+
Api::UnitTypeData.include Api::UnitTypeDataExtension
|
@@ -49,6 +49,15 @@ module Sc2
|
|
49
49
|
bot&.warp(units: self, unit_type_id:, target:, queue_command:)
|
50
50
|
end
|
51
51
|
|
52
|
+
# Research a specific upgrade at one of these structures
|
53
|
+
# @param upgrade_id [Integer] Api::UpgradeId to research
|
54
|
+
# @param queue_command [Boolean] shift+command
|
55
|
+
def research(upgrade_id:, queue_command: false)
|
56
|
+
return if size.zero?
|
57
|
+
|
58
|
+
bot&.research(units: self, upgrade_id:, queue_command:)
|
59
|
+
end
|
60
|
+
|
52
61
|
# Shorthand for performing action SMART (right-click)
|
53
62
|
# @param target [Api::Unit, Integer, Api::Point2D] is a unit, unit tag or a Api::Point2D
|
54
63
|
# @param queue_command [Boolean] shift+command
|
@@ -229,6 +229,12 @@ module Sc2
|
|
229
229
|
alias_method :extractors, :gas
|
230
230
|
alias_method :assimilators, :gas
|
231
231
|
|
232
|
+
# Selects only units which have finished constructing, i.o.w. build_progress == 1.0
|
233
|
+
# @return [UnitGroup] gas structures
|
234
|
+
def completed
|
235
|
+
select(&:is_completed?)
|
236
|
+
end
|
237
|
+
|
232
238
|
# NEUTRAL ------------------------------------------
|
233
239
|
|
234
240
|
# Selects mineral fields
|
data/lib/sc2ai/unit_group.rb
CHANGED
@@ -227,12 +227,20 @@ module Sc2
|
|
227
227
|
UnitGroup.new(@units.except(...))
|
228
228
|
end
|
229
229
|
|
230
|
-
# Returns a
|
230
|
+
# Returns a new unit group containing the entries for given tag(s).
|
231
231
|
# @return [Sc2::UnitGroup] new unit group
|
232
232
|
def slice(...)
|
233
233
|
UnitGroup.new(@units.slice(...))
|
234
234
|
end
|
235
235
|
|
236
|
+
# Returns a new unit group containing each element found both in self and in all of the given other_arrays; duplicates are omitted; items are compared using eql? (items must also implement hash correctly):
|
237
|
+
# @param other_unit_group [UnitGroup]
|
238
|
+
# @return [UnitGroup] new unit group
|
239
|
+
def intersection(other_unit_group)
|
240
|
+
slice(*other_unit_group.tags)
|
241
|
+
end
|
242
|
+
alias_method :&, :intersection
|
243
|
+
|
236
244
|
# Selects a single random Unit without a parameter or an array of Units with a param, i.e. self.random(2)
|
237
245
|
# @return [Api::Unit]
|
238
246
|
def sample(...)
|
data/lib/sc2ai/version.rb
CHANGED