void SimFieldView::mouseMoveEvent(QMouseEvent* me) {
    FieldView::mouseMoveEvent(me);
    switch (_dragMode) {
        case DRAG_SHOOT:
            _dragTo = _worldToTeam * _screenToWorld * me->pos();
            break;

        case DRAG_PLACE:
            if (_dragRobot >= 0) {
                SimCommand cmd;
                SimCommand::Robot* r = cmd.add_robots();
                r->set_shell(_dragRobot);
                r->set_blue_team(_dragRobotBlue);
                r->mutable_pos()->CopyFrom(_screenToWorld * me->pos());
                r->mutable_vel()->set_x(0);
                r->mutable_vel()->set_y(0);
                sendSimCommand(cmd);
            } else {
                placeBall(me->pos());
            }
            break;

        default:
            break;
    }
    update();
}
void MainWindow::on_actionQuicksaveRobotLocations_triggered() {
    _ui.actionQuickloadRobotLocations->setEnabled(true);
    _quickLoadCmd.reset();
    for (OurRobot* robot : state()->self) {
        if (robot->visible) {
            SimCommand::Robot* r = _quickLoadCmd.add_robots();
            r->set_shell(robot->shell());
            r->set_blue_team(processor()->blueTeam());
            Geometry2d::Point newPos =
                _ui.fieldView->getTeamToWorld() * robot->pos;
            r->mutable_pos()->set_x(newPos.x);
            r->mutable_pos()->set_y(newPos.y);
            r->mutable_vel()->set_x(0);
            r->mutable_vel()->set_y(0);
            r->set_w(0);
        }
    }
    for (OpponentRobot* robot : state()->opp) {
        if (robot->visible) {
            SimCommand::Robot* r = _quickLoadCmd.add_robots();
            r->set_shell(robot->shell());
            r->set_blue_team(!processor()->blueTeam());
            Geometry2d::Point newPos =
                _ui.fieldView->getTeamToWorld() * robot->pos;
            r->mutable_pos()->set_x(newPos.x);
            r->mutable_pos()->set_y(newPos.y);
            r->mutable_vel()->set_x(0);
            r->mutable_vel()->set_y(0);
            r->set_w(0);
        }
    }

    Geometry2d::Point ballPos =
        _ui.fieldView->getTeamToWorld() * state()->ball.pos;
    _quickLoadCmd.mutable_ball_pos()->set_x(ballPos.x);
    _quickLoadCmd.mutable_ball_pos()->set_y(ballPos.y);
    _quickLoadCmd.mutable_ball_vel()->set_x(0);
    _quickLoadCmd.mutable_ball_vel()->set_y(0);
}
void MainWindow::on_actionStopRobots_triggered() {
    SimCommand cmd;
    // TODO: check that this handles threads properly
    for (OurRobot* robot : state()->self) {
        if (robot->visible) {
            SimCommand::Robot* r = cmd.add_robots();
            r->set_shell(robot->shell());
            r->set_blue_team(processor()->blueTeam());
            Geometry2d::Point newPos =
                _ui.fieldView->getTeamToWorld() * robot->pos;
            r->mutable_pos()->set_x(newPos.x);
            r->mutable_pos()->set_y(newPos.y);
            r->mutable_vel()->set_x(0);
            r->mutable_vel()->set_y(0);
            r->set_w(0);
        }
    }
    for (OpponentRobot* robot : state()->opp) {
        if (robot->visible) {
            SimCommand::Robot* r = cmd.add_robots();
            r->set_shell(robot->shell());
            r->set_blue_team(!processor()->blueTeam());
            Geometry2d::Point newPos =
                _ui.fieldView->getTeamToWorld() * robot->pos;
            r->mutable_pos()->set_x(newPos.x);
            r->mutable_pos()->set_y(newPos.y);
            r->mutable_vel()->set_x(0);
            r->mutable_vel()->set_y(0);
            r->set_w(0);
        }
    }
    _ui.fieldView->sendSimCommand(cmd);
}