
syntax = "proto2";

package SC2APIProtocol;

//
// Observation
//

message ObservationUI {
  repeated ControlGroup groups = 1;
  oneof panel {
    SinglePanel single = 2;
    MultiPanel multi = 3;
    CargoPanel cargo = 4;
    ProductionPanel production = 5;
  }
}

message ControlGroup {
  optional uint32 control_group_index = 1;
  optional uint32 leader_unit_type = 2;
  optional uint32 count = 3;
}

message UnitInfo {
  optional uint32 unit_type = 1;
  optional uint32 player_relative = 2;
  optional int32 health = 3;
  optional int32 shields = 4;
  optional int32 energy = 5;
  optional int32 transport_slots_taken = 6;
  optional float build_progress = 7;    // Range: [0.0, 1.0]
  optional UnitInfo add_on = 8;
  optional int32 max_health = 9;
  optional int32 max_shields = 10;
  optional int32 max_energy = 11;
}

message SinglePanel {
  optional UnitInfo unit = 1;
  optional int32 attack_upgrade_level = 2;
  optional int32 armor_upgrade_level = 3;
  optional int32 shield_upgrade_level = 4;
  repeated int32 buffs = 5;
}

message MultiPanel {
  repeated UnitInfo units = 1;
}

message CargoPanel {
  optional UnitInfo unit = 1;
  repeated UnitInfo passengers = 2;
  optional int32 slots_available = 3;       // TODO: Change to cargo size
}

message BuildItem {
  optional uint32 ability_id = 1;
  optional float build_progress = 2;    // Range: [0.0, 1.0]
}

message ProductionPanel {
  optional UnitInfo unit = 1;

  // build_queue ONLY gives information about units that are being produced.
  // Use production_queue instead to see both units being trained as well as research in the queue.
  repeated UnitInfo build_queue = 2;
  repeated BuildItem production_queue = 3;
}


//
// Action
//

message ActionUI {
  oneof action {
    ActionControlGroup control_group = 1;
    ActionSelectArmy select_army = 2;
    ActionSelectWarpGates select_warp_gates = 3;
    ActionSelectLarva select_larva = 4;
    ActionSelectIdleWorker select_idle_worker = 5;
    ActionMultiPanel multi_panel = 6;
    ActionCargoPanelUnload cargo_panel = 7;
    ActionProductionPanelRemoveFromQueue production_panel = 8;
    ActionToggleAutocast toggle_autocast = 9;
  }
}

message ActionControlGroup {
  enum ControlGroupAction {
    Recall = 1;             // Equivalent to number hotkey. Replaces current selection with control group.
    Set = 2;                // Equivalent to Control + number hotkey. Sets control group to current selection.
    Append = 3;             // Equivalent to Shift + number hotkey. Adds current selection into control group.
    SetAndSteal = 4;        // Equivalent to Control + Alt + number hotkey. Sets control group to current selection. Units are removed from other control groups.
    AppendAndSteal = 5;     // Equivalent to Shift + Alt + number hotkey. Adds current selection into control group. Units are removed from other control groups.
  }
  optional ControlGroupAction action = 1;
  optional uint32 control_group_index = 2;
}

message ActionSelectArmy {
  optional bool selection_add = 1;
}

message ActionSelectWarpGates {
  optional bool selection_add = 1;
}

message ActionSelectLarva {
}

message ActionSelectIdleWorker {
  enum Type {
    Set = 1;        // Equivalent to click with no modifiers. Replaces selection with single idle worker.
    Add = 2;        // Equivalent to shift+click. Adds single idle worker to current selection.
    All = 3;        // Equivalent to control+click. Selects all idle workers.
    AddAll = 4;     // Equivalent to shift+control+click. Adds all idle workers to current selection.
  }
  optional Type type = 1;
}

message ActionMultiPanel {
  enum Type {
    SingleSelect = 1;         // Click on icon
    DeselectUnit = 2;         // Shift Click on icon
    SelectAllOfType = 3;      // Control Click on icon.
    DeselectAllOfType = 4;    // Control+Shift Click on icon.
  }
  optional Type type = 1;
  optional int32 unit_index = 2;
}

message ActionCargoPanelUnload {
  optional int32 unit_index = 1;
}

message ActionProductionPanelRemoveFromQueue {
  optional int32 unit_index = 1;
}

message ActionToggleAutocast {
  optional int32 ability_id = 1;
}
