Ejemplo n.º 1
0
 //--------------------------------------------- ISSUE COMMAND ----------------------------------------------
 void UnitImpl::setLastImmediateCommand(const UnitCommand &command)
 {
   // Set last immediate command and immediate command frame
   if ( command.type != UnitCommandTypes::Cloak && 
        command.type != UnitCommandTypes::Decloak && 
        command.type != UnitCommandTypes::Unload &&
        !command.isQueued() )
   {
     static_cast<UnitImpl*>(command.unit)->lastImmediateCommand = command;
     static_cast<UnitImpl*>(command.unit)->lastImmediateCommandFrame = BroodwarImpl.frameCount;
   }
 }
Ejemplo n.º 2
0
bool CommandOptimizer::add(UnitCommand command)
{
  // ignore queued and invalid commands, or return if optimizer is disabled
  if (level == 0 ||
    command.isQueued() ||
    command.getType() >= UnitCommandTypes::None)
    return false;

  // Store some commonly accessed variables
  UnitCommandType uct = command.getType();
  Unit utarg = command.getTarget();
  UnitType  targType = utarg ? utarg->getType() : UnitTypes::None;
  Unit uthis = command.getUnit();
  UnitType  thisType = uthis ? uthis->getType() : UnitTypes::None;

  //  Exclude commands that cannot be optimized.
  if (uct == UnitCommandTypes::Build_Addon ||
    uct == UnitCommandTypes::Land ||
    uct == UnitCommandTypes::Build ||
    uct == UnitCommandTypes::Place_COP ||
    uct == UnitCommandTypes::Research ||
    uct == UnitCommandTypes::Upgrade ||
    (level < 4 &&
    uct == UnitCommandTypes::Use_Tech_Unit &&
    (command.getTechType() == TechTypes::Archon_Warp ||
    command.getTechType() == TechTypes::Dark_Archon_Meld)))
    return false;


  // Simplify some commands if possible to decrease their size
  if (uct == UnitCommandTypes::Attack_Unit)
  {
    // Use Right Click for Attack Unit
    if (thisType.canAttack() && utarg && Broodwar->self() && Broodwar->self()->isEnemy(utarg->getPlayer()))
      command.type = UnitCommandTypes::Right_Click_Unit;
  }
  else if (uct == UnitCommandTypes::Move)
  {
    // Use Right Click for Move
    command = UnitCommand::rightClick(uthis, command.getTargetPosition());
  }
  else if (uct == UnitCommandTypes::Gather)
  {
    // Use Right Click for gather
    if (targType.isResourceContainer())
      command = UnitCommand::rightClick(uthis, utarg);
  }
  else if (uct == UnitCommandTypes::Set_Rally_Position)
  {
    // Use Right Click for Set Rally
    if (thisType.canProduce() &&
      thisType != UnitTypes::Protoss_Carrier && thisType != UnitTypes::Hero_Gantrithor &&
      thisType != UnitTypes::Protoss_Reaver  && thisType != UnitTypes::Hero_Warbringer)
      command = UnitCommand::rightClick(uthis, command.getTargetPosition());
  }
  else if (uct == UnitCommandTypes::Set_Rally_Unit)
  {
    // Use Right Click for Set Rally
    if (thisType.canProduce() &&
      thisType != UnitTypes::Protoss_Carrier && thisType != UnitTypes::Hero_Gantrithor &&
      thisType != UnitTypes::Protoss_Reaver  && thisType != UnitTypes::Hero_Warbringer)
      command = UnitCommand::rightClick(uthis, utarg);
  }
  else if (uct == UnitCommandTypes::Use_Tech_Unit)
  {
    // Use Right Click for infestation
    if (command.getTechType() == TechTypes::Infestation &&
      (thisType == UnitTypes::Zerg_Queen || thisType == UnitTypes::Hero_Matriarch) &&
      targType == UnitTypes::Terran_Command_Center)
      command = UnitCommand::rightClick(uthis, utarg);
  }
  else if (uct == UnitCommandTypes::Train)
  {
    // Create a single placeholder since we assume it stores an interceptor or scarab when it's not important
    if (thisType == UnitTypes::Protoss_Carrier ||
      thisType == UnitTypes::Hero_Gantrithor ||
      thisType == UnitTypes::Protoss_Reaver ||
      thisType == UnitTypes::Hero_Warbringer)
      command = UnitCommand::train(uthis, UnitTypes::Protoss_Interceptor);
  }
  else if (uct == UnitCommandTypes::Use_Tech)
  {
    // Simplify siege/cloak/burrow tech to their specific commands to allow grouping them
    switch (command.getTechType())
    {
    case TechTypes::Enum::Tank_Siege_Mode:
      if (command.unit && command.unit->isSieged())
        command = UnitCommand::unsiege(uthis);
      else
        command = UnitCommand::siege(uthis);
      break;
    case TechTypes::Enum::Personnel_Cloaking:
    case TechTypes::Enum::Cloaking_Field:
      if (command.unit && command.unit->isCloaked())
        command = UnitCommand::decloak(uthis);
      else
        command = UnitCommand::cloak(uthis);
      break;
    case TechTypes::Enum::Burrowing:
      if (command.unit && command.unit->isBurrowed())
        command = UnitCommand::unburrow(uthis);
      else
        command = UnitCommand::burrow(uthis);
      break;
    }
  }

  // Exclude commands not optimized at optimizer level 1 (no multi-select buildings)
  if (level <= 1 && thisType < UnitTypes::None && thisType.isBuilding())
    return false;

  // Exclude commands not optimized at or below optimizer level 2 (no position commands)
  if (level <= 2 &&
    (uct == UnitCommandTypes::Attack_Move ||
    uct == UnitCommandTypes::Move ||
    uct == UnitCommandTypes::Patrol ||
    uct == UnitCommandTypes::Right_Click_Position ||
    uct == UnitCommandTypes::Set_Rally_Position ||
    uct == UnitCommandTypes::Unload_All_Position ||
    uct == UnitCommandTypes::Use_Tech_Position))
    return false;

  if (level >= 4)
  {
    // Convert tech unit target to tech position target commands so that they can be
    // optimized with nearby tech position commands of the same type.
    if (uct == UnitCommandTypes::Use_Tech_Unit && command.getTechType().targetsPosition() && utarg)
      command = UnitCommand::useTech(uthis, command.getTechType(), utarg->getPosition());

    // Align locations to 32 pixels
    if (uct == UnitCommandTypes::Attack_Move ||
      uct == UnitCommandTypes::Move ||
      uct == UnitCommandTypes::Patrol ||
      uct == UnitCommandTypes::Right_Click_Position ||
      uct == UnitCommandTypes::Set_Rally_Position ||
      uct == UnitCommandTypes::Unload_All_Position ||
      uct == UnitCommandTypes::Use_Tech_Position)
      command = UnitCommand(uthis, uct, utarg, command.x & (~0x1F), command.y & (~0x1F), command.extra);
    else if (uct == UnitCommandTypes::Use_Tech_Unit &&   // Group Archon & Dark Archon merging
      (command.getTechType() == TechTypes::Archon_Warp ||
      command.getTechType() == TechTypes::Dark_Archon_Meld))
      command = UnitCommand::useTech(uthis, command.getTechType(), nullptr);
  }

  // Set last immediate command again in case it was altered when inserting it into the optimizer
  static_cast<UnitImpl*>(command.unit)->setLastImmediateCommand(command);

  // Add command to the command optimizer buffer and unload it later (newest commands first)
  optimizerQueue[command.getType().getID()].push_front(command);
  return true;
}