sc2ai 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/data/sc2ai/protocol/common.proto +1 -1
  3. data/data/sc2ai/protocol/data.proto +4 -1
  4. data/data/sc2ai/protocol/debug.proto +5 -1
  5. data/data/sc2ai/protocol/error.proto +2 -1
  6. data/data/sc2ai/protocol/query.proto +1 -1
  7. data/data/sc2ai/protocol/raw.proto +8 -6
  8. data/data/sc2ai/protocol/sc2api.proto +21 -7
  9. data/data/sc2ai/protocol/score.proto +2 -1
  10. data/data/sc2ai/protocol/spatial.proto +2 -1
  11. data/data/sc2ai/protocol/ui.proto +4 -1
  12. data/lib/docker_build/Dockerfile.ruby +4 -2
  13. data/lib/sc2ai/api/ability_id.rb +6 -1
  14. data/lib/sc2ai/api/data.rb +15 -0
  15. data/lib/sc2ai/api/tech_tree.rb +1 -1
  16. data/lib/sc2ai/api/tech_tree_data.rb +54 -3
  17. data/lib/sc2ai/connection.rb +0 -1
  18. data/lib/sc2ai/overrides/async/process/child.rb +1 -1
  19. data/lib/sc2ai/player/debug.rb +36 -2
  20. data/lib/sc2ai/player/geo.rb +2 -2
  21. data/lib/sc2ai/player/units.rb +25 -1
  22. data/lib/sc2ai/player.rb +2 -7
  23. data/lib/sc2ai/ports.rb +0 -1
  24. data/lib/sc2ai/protocol/_meta_documentation.rb +249 -4
  25. data/lib/sc2ai/protocol/common_pb.rb +2 -23
  26. data/lib/sc2ai/protocol/data_pb.rb +2 -23
  27. data/lib/sc2ai/protocol/debug_pb.rb +2 -24
  28. data/lib/sc2ai/protocol/error_pb.rb +2 -23
  29. data/lib/sc2ai/protocol/extensions/point_2_d.rb +4 -0
  30. data/lib/sc2ai/protocol/extensions/position.rb +1 -1
  31. data/lib/sc2ai/protocol/extensions/unit.rb +44 -3
  32. data/lib/sc2ai/protocol/extensions/unit_type_data.rb +8 -0
  33. data/lib/sc2ai/protocol/query_pb.rb +2 -24
  34. data/lib/sc2ai/protocol/raw_pb.rb +2 -24
  35. data/lib/sc2ai/protocol/sc2api_pb.rb +2 -31
  36. data/lib/sc2ai/protocol/score_pb.rb +2 -23
  37. data/lib/sc2ai/protocol/spatial_pb.rb +2 -24
  38. data/lib/sc2ai/protocol/ui_pb.rb +2 -23
  39. data/lib/sc2ai/unit_group/filter_ext.rb +16 -1
  40. data/lib/sc2ai/version.rb +1 -1
  41. data/lib/templates/new/.ladderignore +15 -5
  42. data/lib/templates/new/my_bot.rb.tt +1 -1
  43. data/sig/minaswan.rbs +10323 -0
  44. data/sig/sc2ai.rbs +376 -34
  45. metadata +12 -12
  46. data/lib/sc2ai/protocol/extensions/unit_type.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7feb936b57c5b3e4c5cae670ea743f43ccb36a5111bf39abb88ad6e63702ffc5
4
- data.tar.gz: 3b25e577bae3d33255f4e648fa69a8005e67af47e207cffdb7d0e2c790b86961
3
+ metadata.gz: ff26842dae751021cefd5ec41520a100ee4590e38d10fc96e846513a2d112176
4
+ data.tar.gz: eec5d7f966b086a9b1f164097d15917c4d2e14fd0556215c33dda1f7a446ef1d
5
5
  SHA512:
6
- metadata.gz: 3c0d3dac4646702e85531561eb94d11ce8c5a5da53a255832a18803f34daad07f42958be0309f2b043a003581cdb5a9ac198b1326f13a93cd7a6f92211f75fa0
7
- data.tar.gz: 43baa9be2700f945f0f9aed19c81b9bd77ee21df9fa43a151caa2b7d09646de17f2fe69814d8cfd0384e1644106123d01d96b2e34a413563411da41d5f67b0c1
6
+ metadata.gz: 989364e2517ea677ff53f9da0764e8e6626b9569dee736ee7b3f69723e08e6f4a2fd3c3f864034f380c758c2c80b557adaeb4cae73e34217e437a9493b7860ed
7
+ data.tar.gz: d6836e0492d8df3f63f849b3b4e3710a292783c8250a5be4fe6bdd88a3507203576f9786e48c9196d2b6daaa1bfe53b9a03812a0ee384369882948222457b2f2
@@ -1,5 +1,5 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
@@ -1,5 +1,5 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
@@ -19,6 +19,7 @@ message AbilityData {
19
19
  optional uint32 remaps_to_ability_id = 7; // This ability id may be represented by the given more generic id.
20
20
 
21
21
  enum Target {
22
+ EnumTargetUnset = 0; // Proto3 compat
22
23
  None = 1; // Does not require a target.
23
24
  Point = 2; // Requires a target position.
24
25
  Unit = 3; // Requires a unit to target. Given by position using feature layers.
@@ -37,6 +38,7 @@ message AbilityData {
37
38
  }
38
39
 
39
40
  enum Attribute {
41
+ EnumAttributeUnset = 0; // Proto3 compat
40
42
  Light = 1;
41
43
  Armored = 2;
42
44
  Biological = 3;
@@ -57,6 +59,7 @@ message DamageBonus {
57
59
 
58
60
  message Weapon {
59
61
  enum TargetType {
62
+ EnumTargetTypeUnset = 0; // Proto3 compat
60
63
  Ground = 1;
61
64
  Air = 2;
62
65
  Any = 3;
@@ -1,5 +1,5 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
@@ -67,6 +67,7 @@ message DebugSphere {
67
67
  }
68
68
 
69
69
  enum DebugGameState {
70
+ EnumDebugGameStateUnset = 0; // Proto3 compat
70
71
  show_map = 1;
71
72
  control_enemy = 2;
72
73
  food = 3;
@@ -94,6 +95,7 @@ message DebugKillUnit {
94
95
 
95
96
  message DebugTestProcess {
96
97
  enum Test {
98
+ EnumTestUnset = 0; // Proto3 compat
97
99
  hang = 1;
98
100
  crash = 2;
99
101
  exit = 3;
@@ -108,6 +110,7 @@ message DebugSetScore {
108
110
 
109
111
  message DebugEndGame {
110
112
  enum EndResult {
113
+ EnumEndResultUnset = 0; // Proto3 compat
111
114
  Surrender = 1; // Default if nothing is set. The current player admits defeat.
112
115
  DeclareVictory = 2;
113
116
  }
@@ -116,6 +119,7 @@ message DebugEndGame {
116
119
 
117
120
  message DebugSetUnitValue {
118
121
  enum UnitValue {
122
+ EnumUnitValueUnset = 0; // Proto3 compat
119
123
  Energy = 1;
120
124
  Life = 2;
121
125
  Shields = 3;
@@ -1,9 +1,10 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
6
6
  enum ActionResult {
7
+ EnumActionResultUnset = 0; // Proto3 compat
7
8
  Success = 1;
8
9
  NotSupported = 2;
9
10
  Error = 3;
@@ -1,5 +1,5 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
@@ -1,5 +1,5 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
@@ -10,12 +10,12 @@ import "sc2ai/protocol/common.proto";
10
10
  //
11
11
 
12
12
  message StartRaw {
13
- optional Size2DI map_size = 1; // Width and height of the map.
13
+ optional Size2DI map_size = 1 [unverified_lazy=true]; // Width and height of the map.
14
14
  optional ImageData pathing_grid = 2; // 1 bit bitmap of the pathing grid.
15
- optional ImageData terrain_height = 3; // 1 byte bitmap of the terrain height.
16
- optional ImageData placement_grid = 4; // 1 bit bitmap of the building placement grid.
17
- optional RectangleI playable_area = 5; // The playable cells.
18
- repeated Point2D start_locations = 6; // Possible start locations for players.
15
+ optional ImageData terrain_height = 3 [unverified_lazy=true]; // 1 byte bitmap of the terrain height.
16
+ optional ImageData placement_grid = 4 [unverified_lazy=true]; // 1 bit bitmap of the building placement grid.
17
+ optional RectangleI playable_area = 5 [unverified_lazy=true]; // The playable cells.
18
+ repeated Point2D start_locations = 6 [unverified_lazy=true]; // Possible start locations for players.
19
19
  }
20
20
 
21
21
 
@@ -59,6 +59,7 @@ message UnitOrder {
59
59
  }
60
60
 
61
61
  enum DisplayType {
62
+ EnumDisplayTypeUnset = 0; // Proto3 compat
62
63
  Visible = 1; // Fully visible
63
64
  Snapshot = 2; // Dimmed version of unit left behind after entering fog of war
64
65
  Hidden = 3; // Fully hidden
@@ -66,6 +67,7 @@ enum DisplayType {
66
67
  }
67
68
 
68
69
  enum Alliance {
70
+ EnumAllianceUnset = 0; // Proto3 compat
69
71
  Self = 1;
70
72
  Ally = 2;
71
73
  Neutral = 3;
@@ -1,5 +1,5 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
@@ -155,6 +155,7 @@ message Response {
155
155
  }
156
156
 
157
157
  enum Status {
158
+ EnumStatusUnset = 0; // Proto3 compat
158
159
  launched = 1; // Game has been launch and is not yet doing anything.
159
160
  init_game = 2; // Create game has been called, and the host is awaiting players.
160
161
  in_game = 3; // In a single or multiplayer game.
@@ -191,6 +192,7 @@ message LocalMap {
191
192
 
192
193
  message ResponseCreateGame {
193
194
  enum Error {
195
+ EnumResponseCreateGameErrorUnset = 0; // Proto3 compat
194
196
  MissingMap = 1;
195
197
  InvalidMapPath = 2;
196
198
  InvalidMapData = 3;
@@ -231,6 +233,7 @@ message ResponseJoinGame {
231
233
  optional uint32 player_id = 1;
232
234
 
233
235
  enum Error {
236
+ EnumResponseJoinGameErrorUnset = 0; // Proto3 compat
234
237
  MissingParticipation = 1;
235
238
  InvalidObservedPlayerId = 2;
236
239
  MissingOptions = 3;
@@ -258,6 +261,7 @@ message RequestRestartGame {
258
261
  // The defaultRestartGameLoops is specified to be (1<<18) by default
259
262
  message ResponseRestartGame {
260
263
  enum Error {
264
+ EnumResponseRestartGameErrorUnset = 0; // Proto3 compat
261
265
  LaunchError = 1;
262
266
  }
263
267
  optional Error error = 1;
@@ -282,6 +286,7 @@ message RequestStartReplay {
282
286
 
283
287
  message ResponseStartReplay {
284
288
  enum Error {
289
+ EnumResponseStartReplayErrorUnset = 0; // Proto3 compat
285
290
  MissingReplay = 1;
286
291
  InvalidReplayPath = 2;
287
292
  InvalidReplayData = 3;
@@ -301,6 +306,7 @@ message RequestMapCommand {
301
306
 
302
307
  message ResponseMapCommand {
303
308
  enum Error {
309
+ EnumResponseMapCommandErrorUnset = 0; // Proto3 compat
304
310
  NoTriggerError = 1;
305
311
  }
306
312
  optional Error error = 1;
@@ -343,11 +349,11 @@ message RequestGameInfo {
343
349
 
344
350
  message ResponseGameInfo {
345
351
  optional string map_name = 1;
346
- repeated string mod_names = 6;
347
352
  optional string local_map_path = 2;
348
- repeated PlayerInfo player_info = 3;
353
+ repeated PlayerInfo player_info = 3 [unverified_lazy=true];
349
354
  optional StartRaw start_raw = 4; // Populated if Raw interface is enabled.
350
- optional InterfaceOptions options = 5;
355
+ optional InterfaceOptions options = 5 [unverified_lazy=true];
356
+ repeated string mod_names = 6;
351
357
  }
352
358
 
353
359
  //-----------------------------------------------------------------------------
@@ -360,7 +366,7 @@ message ResponseObservation {
360
366
  repeated Action actions = 1; // Actions this player did since the last Observation.
361
367
  repeated ActionError action_errors = 2; // Equivalent of UI "red text" errors.
362
368
  optional Observation observation = 3;
363
- repeated PlayerResult player_result = 4; // Only populated if the game ended during this step.
369
+ repeated PlayerResult player_result = 4 [unverified_lazy=true]; // Only populated if the game ended during this step.
364
370
  repeated ChatReceived chat = 5;
365
371
  }
366
372
 
@@ -453,6 +459,7 @@ message ResponseReplayInfo {
453
459
  optional uint32 base_build = 8;
454
460
 
455
461
  enum Error {
462
+ EnumResponseReplayInfoErrorUnset = 0; // Proto3 compat
456
463
  MissingReplay = 1;
457
464
  InvalidReplayPath = 2;
458
465
  InvalidReplayData = 3;
@@ -484,6 +491,7 @@ message RequestSaveMap {
484
491
 
485
492
  message ResponseSaveMap {
486
493
  enum Error {
494
+ EnumResponseSaveMapErrorUnset = 0; // Proto3 compat
487
495
  InvalidMapData = 1;
488
496
  }
489
497
  optional Error error = 1;
@@ -514,6 +522,7 @@ message ResponseDebug {
514
522
  //
515
523
 
516
524
  enum Difficulty {
525
+ EnumDifficultyUnset = 0; // Proto3 compat
517
526
  VeryEasy = 1;
518
527
  Easy = 2;
519
528
  Medium = 3;
@@ -527,12 +536,14 @@ enum Difficulty {
527
536
  }
528
537
 
529
538
  enum PlayerType {
539
+ EnumPlayerTypeUnset = 0; // Proto3 compat
530
540
  Participant = 1;
531
541
  Computer = 2;
532
542
  Observer = 3;
533
543
  }
534
544
 
535
545
  enum AIBuild {
546
+ EnumAIBuildUnset = 0; // Proto3 compat
536
547
  RandomBuild = 1;
537
548
  Rush = 2;
538
549
  Timing = 3;
@@ -619,11 +630,11 @@ message Observation {
619
630
  optional PlayerCommon player_common = 1;
620
631
  repeated Alert alerts = 10;
621
632
  repeated AvailableAbility abilities = 3; // Abilities available in the selection. Enabled if in this list, disabled otherwise.
622
- optional Score score = 4;
633
+ optional Score score = 4 [unverified_lazy=true];
623
634
 
624
635
  optional ObservationRaw raw_data = 5; // Populated if Raw interface is enabled.
625
636
  optional ObservationFeatureLayer feature_layer_data = 6; // Populated if Feature Layer interface is enabled.
626
- optional ObservationRender render_data = 7; // Populated if Render interface is enabled.
637
+ optional ObservationRender render_data = 7 [unverified_lazy=true]; // Populated if Render interface is enabled.
627
638
  optional ObservationUI ui_data = 8; // Populated if Feature Layer or Render interface is enabled.
628
639
  }
629
640
 
@@ -638,6 +649,7 @@ message Action {
638
649
 
639
650
  message ActionChat {
640
651
  enum Channel {
652
+ EnumChannelUnset = 0; // Proto3 compat
641
653
  Broadcast = 1;
642
654
  Team = 2;
643
655
  }
@@ -681,6 +693,7 @@ message ActionObserverCameraFollowUnits {
681
693
  }
682
694
 
683
695
  enum Alert {
696
+ EnumAlertUnset = 0; // Proto3 compat
684
697
  AlertError = 3;
685
698
  AddOnComplete = 4;
686
699
  BuildingComplete = 5;
@@ -706,6 +719,7 @@ enum Alert {
706
719
  }
707
720
 
708
721
  enum Result {
722
+ EnumResultUnset = 0; // Proto3 compat
709
723
  Victory = 1;
710
724
  Defeat = 2;
711
725
  Tie = 3;
@@ -1,10 +1,11 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
6
6
  message Score {
7
7
  enum ScoreType {
8
+ EnumScoreTypeUnset = 0; // Proto3 compat
8
9
  Curriculum = 1; // map generated score (from curriculum maps with special scoring)
9
10
  Melee = 2; // summation of in-progress and current units/buildings value + minerals + vespene
10
11
  }
@@ -1,5 +1,5 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
@@ -101,6 +101,7 @@ message ActionSpatialCameraMove {
101
101
  message ActionSpatialUnitSelectionPoint {
102
102
  optional PointI selection_screen_coord = 1;
103
103
  enum Type {
104
+ EnumActionSpatialUnitSelectionPointTypeUnset = 0; // Proto3 compat
104
105
  Select = 1; // Equivalent to normal click. Changes selection to unit.
105
106
  Toggle = 2; // Equivalent to shift+click. Toggle selection of unit.
106
107
  AllType = 3; // Equivalent to control+click. Selects all units of a given type.
@@ -1,5 +1,5 @@
1
1
 
2
- syntax = "proto2";
2
+ syntax = "proto3";
3
3
 
4
4
  package Api;
5
5
 
@@ -90,6 +90,7 @@ message ActionUI {
90
90
 
91
91
  message ActionControlGroup {
92
92
  enum ControlGroupAction {
93
+ EnumControlGroupActionUnset = 0; // Proto3 compat
93
94
  Recall = 1; // Equivalent to number hotkey. Replaces current selection with control group.
94
95
  Set = 2; // Equivalent to Control + number hotkey. Sets control group to current selection.
95
96
  Append = 3; // Equivalent to Shift + number hotkey. Adds current selection into control group.
@@ -113,6 +114,7 @@ message ActionSelectLarva {
113
114
 
114
115
  message ActionSelectIdleWorker {
115
116
  enum Type {
117
+ EnumActionSelectIdleWorkerTypeUnset = 0; // Proto3 compat
116
118
  Set = 1; // Equivalent to click with no modifiers. Replaces selection with single idle worker.
117
119
  Add = 2; // Equivalent to shift+click. Adds single idle worker to current selection.
118
120
  All = 3; // Equivalent to control+click. Selects all idle workers.
@@ -123,6 +125,7 @@ message ActionSelectIdleWorker {
123
125
 
124
126
  message ActionMultiPanel {
125
127
  enum Type {
128
+ EnumActionMultiPanelTypeUnset = 0; // Proto3 compat
126
129
  SingleSelect = 1; // Click on icon
127
130
  DeselectUnit = 2; // Shift Click on icon
128
131
  SelectAllOfType = 3; // Control Click on icon.
@@ -29,7 +29,7 @@ WORKDIR /root/ruby-builder
29
29
  RUN rm ruby-$RUBY_VERSION.tar.gz
30
30
  RUN rm -rf ./ruby-$RUBY_VERSION
31
31
  RUN rm yaml-0.2.5.tar.gz
32
- RUN rm -rf ./yaml-0.2.5
32
+ #RUN rm -rf ./yaml-0.2.5
33
33
 
34
34
  # Package config
35
35
  # numo-linalg needs openblas, copy to ruby-prefix/lib/ dir.
@@ -57,9 +57,11 @@ RUN gem install 'sc2ai'
57
57
 
58
58
  FROM debian:12-slim
59
59
  COPY --from=build /root/ruby-builder /root/ruby-builder
60
-
60
+ ENV AIARENA "true"
61
61
  RUN /root/ruby-builder/.ruby/bin/ruby --yjit -v
62
62
 
63
+ RUN /root/ruby-builder/.ruby/bin/bundle config set --global without test development
64
+
63
65
  RUN apt-get update
64
66
  RUN apt-get purge $(aptitude search '~i!~M!~prequired!~pimportant!~R~prequired!~R~R~prequired!~R~pimportant!~R~R~pimportant!busybox!grub!initramfs-tools' | awk '{print $2}') --assume-yes
65
67
  RUN apt-get purge aptitude --assume-yes
@@ -1305,7 +1305,12 @@ module Api
1305
1305
  # @param ability_id [Integer]
1306
1306
  # @return [Integer] either the current id if no remap or the remapped id
1307
1307
  def generic_id(ability_id)
1308
- remap_ids[ability_id] || ability_id
1308
+ @_non_remap_ids ||= {}
1309
+ if @_non_remap_ids[ability_id]
1310
+ @_non_remap_ids[ability_id]
1311
+ else
1312
+ remap_ids[ability_id] || (@_non_remap_ids[ability_id] = ability_id)
1313
+ end
1309
1314
  end
1310
1315
 
1311
1316
  private
@@ -107,6 +107,7 @@ module Sc2
107
107
  def override_unit_data
108
108
  correct_unit_type_costs
109
109
  correct_unit_type_sum
110
+ decorate_unit_type_placement_length
110
111
  end
111
112
 
112
113
  # @private
@@ -254,5 +255,19 @@ module Sc2
254
255
  unit_data
255
256
  end
256
257
  end
258
+
259
+ # @private
260
+ # Adds placement_length to units if applicable
261
+ private def decorate_unit_type_placement_length
262
+ @units.each_value do |unit_type_data|
263
+ unit_type_data.placement_length = 0
264
+ next unless unit_type_data.ability_id
265
+ next unless @abilities[unit_type_data.ability_id]
266
+ footprint_radius = @abilities[unit_type_data.ability_id].footprint_radius
267
+ if footprint_radius
268
+ unit_type_data.placement_length = (footprint_radius * 2.0).to_i
269
+ end
270
+ end
271
+ end
257
272
  end
258
273
  end
@@ -68,7 +68,7 @@ module Api
68
68
  # @param unit_type_id [Integer] the unit which you want to check
69
69
  # @return [Array<Integer>] returns an array of unit type ids as per Api:UnitTypeId
70
70
  def unit_created_from(unit_type_id:)
71
- unit_created_from_data[unit_type_id]
71
+ unit_created_from_data[unit_type_id] || []
72
72
  end
73
73
 
74
74
  # Returns what the unit type an upgrade is researched from
@@ -13,7 +13,13 @@ module Api
13
13
  {ability: Api::AbilityId::UPGRADETOORBITAL_ORBITALCOMMAND,
14
14
  required_building: Api::UnitTypeId::BARRACKS}},
15
15
  Api::UnitTypeId::BARRACKS =>
16
- {Api::UnitTypeId::MARINE =>
16
+ {Api::UnitTypeId::BARRACKSTECHLAB =>
17
+ {ability: Api::AbilityId::BUILD_TECHLAB_BARRACKS,
18
+ requires_placement_position: true},
19
+ Api::UnitTypeId::BARRACKSREACTOR =>
20
+ {ability: Api::AbilityId::BUILD_REACTOR_BARRACKS,
21
+ requires_placement_position: true},
22
+ Api::UnitTypeId::MARINE =>
17
23
  {ability: Api::AbilityId::BARRACKSTRAIN_MARINE},
18
24
  Api::UnitTypeId::REAPER =>
19
25
  {ability: Api::AbilityId::BARRACKSTRAIN_REAPER},
@@ -25,7 +31,13 @@ module Api
25
31
  {ability: Api::AbilityId::BARRACKSTRAIN_MARAUDER,
26
32
  requires_techlab: true}},
27
33
  Api::UnitTypeId::FACTORY =>
28
- {Api::UnitTypeId::HELLION =>
34
+ {Api::UnitTypeId::FACTORYTECHLAB =>
35
+ {ability: Api::AbilityId::BUILD_TECHLAB_FACTORY,
36
+ requires_placement_position: true},
37
+ Api::UnitTypeId::FACTORYREACTOR =>
38
+ {ability: Api::AbilityId::BUILD_REACTOR_FACTORY,
39
+ requires_placement_position: true},
40
+ Api::UnitTypeId::HELLION =>
29
41
  {ability: Api::AbilityId::FACTORYTRAIN_HELLION},
30
42
  Api::UnitTypeId::CYCLONE => {ability: Api::AbilityId::TRAIN_CYCLONE},
31
43
  Api::UnitTypeId::WIDOWMINE =>
@@ -41,7 +53,13 @@ module Api
41
53
  {ability: Api::AbilityId::TRAIN_HELLBAT,
42
54
  required_building: Api::UnitTypeId::ARMORY}},
43
55
  Api::UnitTypeId::STARPORT =>
44
- {Api::UnitTypeId::MEDIVAC =>
56
+ {Api::UnitTypeId::STARPORTTECHLAB =>
57
+ {ability: Api::AbilityId::BUILD_TECHLAB_STARPORT,
58
+ requires_placement_position: true},
59
+ Api::UnitTypeId::STARPORTREACTOR =>
60
+ {ability: Api::AbilityId::BUILD_REACTOR_STARPORT,
61
+ requires_placement_position: true},
62
+ Api::UnitTypeId::MEDIVAC =>
45
63
  {ability: Api::AbilityId::STARPORTTRAIN_MEDIVAC},
46
64
  Api::UnitTypeId::VIKINGFIGHTER =>
47
65
  {ability: Api::AbilityId::STARPORTTRAIN_VIKINGFIGHTER},
@@ -56,6 +74,20 @@ module Api
56
74
  {ability: Api::AbilityId::STARPORTTRAIN_BATTLECRUISER,
57
75
  requires_techlab: true,
58
76
  required_building: Api::UnitTypeId::FUSIONCORE}},
77
+ Api::UnitTypeId::FACTORYFLYING =>
78
+ {Api::UnitTypeId::FACTORYTECHLAB =>
79
+ {ability: Api::AbilityId::BUILD_TECHLAB_FACTORY,
80
+ requires_placement_position: true},
81
+ Api::UnitTypeId::FACTORYREACTOR =>
82
+ {ability: Api::AbilityId::BUILD_REACTOR_FACTORY,
83
+ requires_placement_position: true}},
84
+ Api::UnitTypeId::STARPORTFLYING =>
85
+ {Api::UnitTypeId::STARPORTTECHLAB =>
86
+ {ability: Api::AbilityId::BUILD_TECHLAB_STARPORT,
87
+ requires_placement_position: true},
88
+ Api::UnitTypeId::STARPORTREACTOR =>
89
+ {ability: Api::AbilityId::BUILD_REACTOR_STARPORT,
90
+ requires_placement_position: true}},
59
91
  Api::UnitTypeId::SCV =>
60
92
  {Api::UnitTypeId::COMMANDCENTER =>
61
93
  {ability: Api::AbilityId::TERRANBUILD_COMMANDCENTER,
@@ -104,6 +136,13 @@ module Api
104
136
  Api::UnitTypeId::FUSIONCORE =>
105
137
  {ability: Api::AbilityId::TERRANBUILD_FUSIONCORE,
106
138
  required_building: Api::UnitTypeId::STARPORT,
139
+ requires_placement_position: true}},
140
+ Api::UnitTypeId::BARRACKSFLYING =>
141
+ {Api::UnitTypeId::BARRACKSTECHLAB =>
142
+ {ability: Api::AbilityId::BUILD_TECHLAB_BARRACKS,
143
+ requires_placement_position: true},
144
+ Api::UnitTypeId::BARRACKSREACTOR =>
145
+ {ability: Api::AbilityId::BUILD_REACTOR_BARRACKS,
107
146
  requires_placement_position: true}},
108
147
  Api::UnitTypeId::RAVEN =>
109
148
  {Api::UnitTypeId::AUTOTURRET =>
@@ -780,16 +819,28 @@ module Api
780
819
  Api::UnitTypeId::ORBITALCOMMAND],
781
820
  Api::UnitTypeId::PLANETARYFORTRESS => [Api::UnitTypeId::COMMANDCENTER],
782
821
  Api::UnitTypeId::ORBITALCOMMAND => [Api::UnitTypeId::COMMANDCENTER],
822
+ Api::UnitTypeId::BARRACKSTECHLAB =>
823
+ [Api::UnitTypeId::BARRACKS, Api::UnitTypeId::BARRACKSFLYING],
824
+ Api::UnitTypeId::BARRACKSREACTOR =>
825
+ [Api::UnitTypeId::BARRACKS, Api::UnitTypeId::BARRACKSFLYING],
783
826
  Api::UnitTypeId::MARINE => [Api::UnitTypeId::BARRACKS],
784
827
  Api::UnitTypeId::REAPER => [Api::UnitTypeId::BARRACKS],
785
828
  Api::UnitTypeId::GHOST => [Api::UnitTypeId::BARRACKS],
786
829
  Api::UnitTypeId::MARAUDER => [Api::UnitTypeId::BARRACKS],
830
+ Api::UnitTypeId::FACTORYTECHLAB =>
831
+ [Api::UnitTypeId::FACTORY, Api::UnitTypeId::FACTORYFLYING],
832
+ Api::UnitTypeId::FACTORYREACTOR =>
833
+ [Api::UnitTypeId::FACTORY, Api::UnitTypeId::FACTORYFLYING],
787
834
  Api::UnitTypeId::HELLION => [Api::UnitTypeId::FACTORY],
788
835
  Api::UnitTypeId::CYCLONE => [Api::UnitTypeId::FACTORY],
789
836
  Api::UnitTypeId::WIDOWMINE => [Api::UnitTypeId::FACTORY],
790
837
  Api::UnitTypeId::SIEGETANK => [Api::UnitTypeId::FACTORY],
791
838
  Api::UnitTypeId::THOR => [Api::UnitTypeId::FACTORY],
792
839
  Api::UnitTypeId::HELLIONTANK => [Api::UnitTypeId::FACTORY],
840
+ Api::UnitTypeId::STARPORTTECHLAB =>
841
+ [Api::UnitTypeId::STARPORT, Api::UnitTypeId::STARPORTFLYING],
842
+ Api::UnitTypeId::STARPORTREACTOR =>
843
+ [Api::UnitTypeId::STARPORT, Api::UnitTypeId::STARPORTFLYING],
793
844
  Api::UnitTypeId::MEDIVAC => [Api::UnitTypeId::STARPORT],
794
845
  Api::UnitTypeId::VIKINGFIGHTER => [Api::UnitTypeId::STARPORT],
795
846
  Api::UnitTypeId::LIBERATOR => [Api::UnitTypeId::STARPORT],
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "async"
4
- require "async/io/stream"
5
4
  require "async/http/endpoint"
6
5
  require "async/websocket"
7
6
  require_relative "connection/requests"
@@ -8,7 +8,7 @@ module Async
8
8
  def initialize(*args, **options)
9
9
  # Setup a cross-thread notification pipe - nio4r can't monitor pids unfortunately:
10
10
  pipe = ::IO.pipe
11
- @input = Async::IO::Generic.new(pipe.first)
11
+ @input = pipe.first
12
12
  @output = pipe.last
13
13
 
14
14
  @exit_status = nil
@@ -121,8 +121,8 @@ module Sc2
121
121
  draw: Api::DebugDraw.new(
122
122
  boxes: [
123
123
  Api::DebugBox.new(
124
- min: Api::Point.new(x: point.x - radius, y: point.y - radius, z: point.z + 0.02),
125
- max: Api::Point.new(x: point.x + radius, y: point.y + radius, z: point.z + (radius * 2) + 0.02),
124
+ min: Api::Point.new(x: point.x - radius, y: point.y - radius, z: point.z + 0.03),
125
+ max: Api::Point.new(x: point.x + radius, y: point.y + radius, z: point.z + (radius * 2) + 0.03),
126
126
  color:
127
127
  )
128
128
  ]
@@ -149,6 +149,40 @@ module Sc2
149
149
  )
150
150
  end
151
151
 
152
+ # Renders a block on the floor, drawn by 4 lines
153
+ # Pass in either a pos (Position/Unit) or exact x * y coordinates
154
+ # Optional indentation adds padding on borders inward
155
+ # @param pos [Api::Unit, Api::Position]
156
+ # @param x [Float, Integer]
157
+ # @param y [Float, Integer]
158
+ # @param color [Api::Color]
159
+ # @param indent [Float] default 0.05. should be lower than < 1.0
160
+ # @example
161
+ # debug_tile(x: 12.3, y: 4.56, color: Api::Color.new(r: 255, g: 0, b: 0))
162
+ # debug_tile(some_unit)
163
+ # debug_tile(some_unit.pos)
164
+ def debug_tile(pos = nil, x: nil, y: nil, color: nil, indent: 0.05)
165
+ if pos.is_a?(Api::Unit)
166
+ x = pos.pos.x.floor
167
+ y = pos.pos.y.floor
168
+ elsif pos.is_a?(Sc2::Position)
169
+ x = pos.pos.x.floor
170
+ y = pos.pos.y.floor
171
+ end
172
+
173
+ # Raise above floor to prevent texture clipping
174
+ z = geo.terrain_height(x:, y:).to_f + 0.1
175
+ tl = Api::Point[x + indent, y + 1.0 - indent, z]
176
+ bl = Api::Point[x + indent, y + indent, z]
177
+ br = Api::Point[x + 1.0 - indent, y + indent, z]
178
+ tr = Api::Point[x + 1.0 - indent, y + 1.0 - indent, z]
179
+
180
+ debug_draw_line(p0: tl, p1: bl, color:)
181
+ debug_draw_line(p0: bl, p1: br, color:)
182
+ debug_draw_line(p0: br, p1: tr, color:)
183
+ debug_draw_line(p0: tr, p1: tl, color:)
184
+ end
185
+
152
186
  # Other Commands ---
153
187
 
154
188
  # @param command [Integer] one of Api::DebugGameState::*
@@ -111,10 +111,10 @@ module Sc2
111
111
  if bot.race == Api::Race::Zerg
112
112
  # Reserve one row lower, meaning (y-3) instead of (y-2)
113
113
  @expo_placement_grid[(y - 3).clamp(map_tile_range_y)..(y + 2).clamp(map_tile_range_y),
114
- (x - 2).clamp(map_tile_range_y)..(x + 2).clamp(map_tile_range_y)] = 1
114
+ (x - 2).clamp(map_tile_range_x)..(x + 2).clamp(map_tile_range_x)] = 1
115
115
  else
116
116
  @expo_placement_grid[(y - 2).clamp(map_tile_range_y)..(y + 2).clamp(map_tile_range_y),
117
- (x - 2).clamp(map_tile_range_y)..(x + 2).clamp(map_tile_range_y)] = 1
117
+ (x - 2).clamp(map_tile_range_x)..(x + 2).clamp(map_tile_range_x)] = 1
118
118
  end
119
119
  end
120
120
  end
@@ -91,6 +91,17 @@ module Sc2
91
91
  # For this unit type, tells you how many are in progress by checking orders for all it's sources.
92
92
  # @return [Integer]
93
93
  def units_in_progress(unit_type_id)
94
+ if unit_type_id == Api::UnitTypeId::REACTOR
95
+ return units_in_progress(Api::UnitTypeId::BARRACKSREACTOR) +
96
+ units_in_progress(Api::UnitTypeId::FACTORYREACTOR) +
97
+ units_in_progress(Api::UnitTypeId::STARPORTREACTOR)
98
+ elsif unit_type_id == Api::UnitTypeId::TECHLAB
99
+ return units_in_progress(Api::UnitTypeId::BARRACKSTECHLAB) +
100
+ units_in_progress(Api::UnitTypeId::FACTORYTECHLAB) +
101
+ units_in_progress(Api::UnitTypeId::STARPORTTECHLAB)
102
+ end
103
+
104
+ # Get source unit
94
105
  source_unit_types = Api::TechTree.unit_created_from(unit_type_id: unit_type_id)
95
106
 
96
107
  # When building from LARVA, check the intermediate models
@@ -119,9 +130,22 @@ module Sc2
119
130
  else
120
131
  units
121
132
  end
133
+ # For SCV, the structure might be completed but dangling order for a few frames.
134
+ source_is_scv = source_unit_types.include?(Api::UnitTypeId::SCV)
135
+
136
+ # Let's count orders matching the ability
122
137
  total_in_progress = origin.select_type(source_unit_types).sum do |source|
123
138
  source.orders.count do |order|
124
- true if order.ability_id == unit_create_ability
139
+ if order.ability_id == unit_create_ability
140
+ if source_is_scv
141
+ # If we are a SCV, do not count our order if the target is a completed structure pos
142
+ structures.select_type(unit_type_id).completed.none? do |structure|
143
+ structure.pos == order.target_world_space_pos
144
+ end
145
+ else
146
+ true
147
+ end
148
+ end
125
149
  end
126
150
  end
127
151
  total_in_progress *= 2 if unit_type_id == Api::UnitTypeId::ZERGLING