Skip to content

Commit

Permalink
MMAI: an ML-powered combat AI
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit 4475998
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 16 23:17:00 2024 +0300

    re-enable fail-fast

commit e19df1e
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 16 21:49:04 2024 +0300

    exclude MMAI mod if ENABLE_MMAI is not set

commit 62bd1a5
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 16 20:53:55 2024 +0300

    fix git workflow

commit 37ae3dd
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 16 19:07:04 2024 +0300

    fix win build

commit f84b53a
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 16 18:52:44 2024 +0300

    temporary disable fail-fast

commit 436fa6e
Merge: 5ed3168 c25aef8
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 16 18:51:31 2024 +0300

    Merge remote-tracking branch 'origin/develop' into mmai-play

commit 5ed3168
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 16 18:20:14 2024 +0300

    re-enable Androids (NDK25 seems still available on vcmi runners)

commit 52be591
Author: simo (windows) <s.manolloff@gmail.com>
Date:   Wed Oct 16 15:56:07 2024 +0300

    update submodules

commit 819523a
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Tue Oct 15 16:56:06 2024 +0300

    allow MMAI for neutrals only

commit 738f401
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 16 14:40:43 2024 +0300

    re-enable ubuntu build

commit ac5f1cf
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 16 03:43:27 2024 +0300

    Temporarily disable ubuntu build

commit b6badad
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 16 03:36:32 2024 +0300

    update submodules

commit ce2afaf
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Tue Oct 15 17:00:54 2024 +0300

    allow MMAI for neutrals only; update submodules

commit 1c95c3a
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Sat Oct 12 00:42:11 2024 +0300

    update submodule

commit 672174e
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Fri Oct 11 20:00:11 2024 +0300

    Update submodules

commit ae3ab95
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Fri Oct 11 15:14:11 2024 +0300

    remove redundant min/max schema macros

commit 09bfa2c
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Thu Oct 10 23:14:49 2024 +0300

    update submodules

commit 45ef3a1
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Thu Oct 10 19:09:45 2024 +0300

    fix issue with morale when game interface is not AAI

commit a402dfc
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Thu Oct 10 17:35:40 2024 +0300

    fix setting persistence

commit 7202c89
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Thu Oct 10 16:14:07 2024 +0300

    fix MMAI issue with cb->waitTillRealize

commit 77c8628
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Thu Oct 10 09:46:09 2024 +0300

    fix CI test

commit 830ffe5
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 9 18:07:47 2024 +0300

    disable Android (NDK25 is already removed from some GH runners)

    actions/runner-images#10614

commit 9df549f
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 9 17:46:33 2024 +0300

    test ci

commit 5c838f3
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 9 17:43:17 2024 +0300

    fix AI pre-selection in launcher

commit 1bfd9a8
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Thu Oct 10 23:12:01 2024 +0300

    Remove ML-related images

commit 773a7fb
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Thu Oct 10 23:11:48 2024 +0300

    simplify combobox value extraction

commit 50ce5c8
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 9 16:58:10 2024 +0300

    update Mods/MMAI

commit e33f0dd
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 9 16:53:21 2024 +0300

    Mark MMAI as experimental

commit fb3edb6
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 9 16:02:56 2024 +0300

    Revert AICombatOptions -> AutocombatPreferences

commit e6341ce
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 9 15:59:25 2024 +0300

    remove small redundant changes

commit 4e59e49
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 9 14:58:33 2024 +0300

    Removed ML-related code

commit 8d67463
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 9 14:39:03 2024 +0300

    Removed ML submodules

commit 98f2a04
Author: Simeon Manolov <s.manolloff@gmail.com>
Date:   Wed Oct 9 14:32:14 2024 +0300

    Squash-merge mmai branch
  • Loading branch information
smanolloff committed Oct 18, 2024
1 parent 6dc6cc4 commit aa5e6e3
Show file tree
Hide file tree
Showing 19 changed files with 188 additions and 49 deletions.
91 changes: 86 additions & 5 deletions .github/workflows/github.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,73 @@ jobs:
conan_profile: android-64-ndk
conan_prebuilts: dependencies-android-arm64-v8a
artifact_platform: arm64-v8a

#
# MMAI builds
#
- platform: linux
os: ubuntu-20.04
test: 0
before_install: linux_qt5.sh
preset: linux-gcc-debug
mmai_deps: linux-x64
- platform: mac-intel
os: macos-13
test: 0
pack: 1
pack_type: Release
extension: dmg
before_install: macos.sh
preset: macos-conan-ninja-release
conan_profile: macos-intel
conan_prebuilts: dependencies-mac-intel
conan_options: --options with_apple_system_libs=True
artifact_platform: intel
mmai_deps: macos-x64
- platform: mac-arm
os: macos-13
test: 0
pack: 1
pack_type: Release
extension: dmg
before_install: macos.sh
preset: macos-arm-conan-ninja-release
conan_profile: macos-arm
conan_prebuilts: dependencies-mac-arm
conan_options: --options with_apple_system_libs=True
artifact_platform: arm
mmai_deps: macos-arm64
- platform: ios
os: macos-13
test: 0
pack: 1
pack_type: Release
extension: ipa
before_install: macos.sh
preset: ios-release-conan-ccache
conan_profile: ios-arm64
conan_prebuilts: dependencies-ios
conan_options: --options with_apple_system_libs=True
mmai_deps: ios-arm64
- platform: msvc
os: windows-latest
test: 0
pack: 1
pack_type: RelWithDebInfo
extension: exe
before_install: msvc.sh
preset: windows-msvc-release
mmai_deps: win-x64
- platform: android-64
os: ubuntu-24.04
extension: apk
preset: android-conan-ninja-release
before_install: android.sh
conan_profile: android-64-ndk
conan_prebuilts: dependencies-android-arm64-v8a
artifact_platform: arm64-v8a
mmai_deps: android-arm64

runs-on: ${{ matrix.os }}
defaults:
run:
Expand All @@ -136,6 +203,10 @@ jobs:
if: "${{ matrix.conan_prebuilts != '' }}"
run: source '${{github.workspace}}/CI/install_conan_dependencies.sh' '${{matrix.conan_prebuilts}}'

- name: Install MMAI dependencies
if: "${{ matrix.mmai_deps != '' }}"
run: source '${{github.workspace}}/CI/install_mmai_dependencies.sh' '${{matrix.mmai_deps}}'

# ensure the ccache for each PR is separate so they don't interfere with each other
# fall back to ccache of the vcmi/vcmi repo if no PR-specific ccache is found
- name: ccache for PRs
Expand Down Expand Up @@ -215,6 +286,9 @@ jobs:
- name: Build Number
run: |
source '${{github.workspace}}/CI/get_package_name.sh'
if [ '${{matrix.mmai_deps}}' ]; then
VCMI_PACKAGE_FILE_NAME+="-mmai"
fi
if [ '${{ matrix.artifact_platform }}' ]; then
VCMI_PACKAGE_FILE_NAME+="-${{ matrix.artifact_platform }}"
fi
Expand All @@ -226,17 +300,24 @@ jobs:

- name: Configure
run: |
if [ '${{matrix.mmai_deps}}' ]
then
MMAI_FLAGS="-DENABLE_MMAI=ON"
else
MMAI_FLAGS=""
fi
if [[ ${{matrix.preset}} == linux-gcc-test ]]
then
cmake -DENABLE_CCACHE:BOOL=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 --preset ${{ matrix.preset }}
cmake -DENABLE_CCACHE:BOOL=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 $MMAI_FLAGS --preset ${{ matrix.preset }}
elif [[ (${{matrix.preset}} == android-conan-ninja-release) && (${{github.ref}} != 'refs/heads/master') ]]
then
cmake -DENABLE_CCACHE:BOOL=ON -DANDROID_GRADLE_PROPERTIES="applicationIdSuffix=.daily;signingConfig=dailySigning;applicationLabel=VCMI daily" --preset ${{ matrix.preset }}
cmake -DENABLE_CCACHE:BOOL=ON -DANDROID_GRADLE_PROPERTIES="applicationIdSuffix=.daily;signingConfig=dailySigning;applicationLabel=VCMI daily" $MMAI_FLAGS --preset ${{ matrix.preset }}
elif [[ ${{matrix.platform}} != msvc ]]
then
cmake -DENABLE_CCACHE:BOOL=ON --preset ${{ matrix.preset }}
cmake -DENABLE_CCACHE:BOOL=ON $MMAI_FLAGS --preset ${{ matrix.preset }}
else
cmake --preset ${{ matrix.preset }}
cmake $MMAI_FLAGS --preset ${{ matrix.preset }}
fi
- name: Build
Expand Down Expand Up @@ -373,7 +454,7 @@ jobs:
run: |
find . -path ./.git -prune -o -path ./AI/FuzzyLite -prune -o -path ./test/googletest \
-o -path ./osx -prune -o -type f \
-not -name '*.png' -and -not -name '*.ttf' -and -not -name '*.wav' -and -not -name '*.webm' -and -not -name '*.ico' -and -not -name '*.bat' -print0 | \
-not -name '*.png' -and -not -name '*.ttf' -and -not -name '*.wav' -and -not -name '*.webm' -and -not -name '*.ico' -and -not -name '*.bat' -and -not -name '*.pt' -print0 | \
{ ! xargs -0 grep -l -z -P '\r\n'; }
- name: Validate JSON
Expand Down
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@
path = launcher/lib/innoextract
url = https://github.com/vcmi/innoextract.git
branch = vcmi
[submodule "AI/MMAI"]
path = AI/MMAI
url = git@github.com:smanolloff/vcmi-MMAI.git
[submodule "Mods/MMAI"]
path = Mods/MMAI
url = git@github.com:smanolloff/vcmi-MMAI-mod.git
3 changes: 3 additions & 0 deletions AI/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ add_subdirectory(EmptyAI)
if(ENABLE_NULLKILLER_AI)
add_subdirectory(Nullkiller)
endif()
if(ENABLE_MMAI)
add_subdirectory(MMAI)
endif()
1 change: 1 addition & 0 deletions AI/MMAI
Submodule MMAI added at 459900
2 changes: 2 additions & 0 deletions CI/before_install/msvc.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/bin/sh

curl -LfsS -o "vcpkg-export-${VCMI_BUILD_PLATFORM}-windows-v143.7z" \
"https://github.com/vcmi/vcmi-deps-windows/releases/download/v1.7/vcpkg-export-${VCMI_BUILD_PLATFORM}-windows-v143.7z"
7z x "vcpkg-export-${VCMI_BUILD_PLATFORM}-windows-v143.7z"
Expand Down
8 changes: 8 additions & 0 deletions CI/install_mmai_dependencies.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

platform=$1
ARCHIVE_URL="https://github.com/smanolloff/vcmi-libtorch-builds/releases/download/v1.0/vcmi-libtorch-$platform.txz"

curl -fL "$ARCHIVE_URL" | tar -xJ -C AI/MMAI

[ -d AI/MMAI/libtorch ] || { ls -lah AI/MMAI; echo "failed to extract libtorch"; exit 1; }
11 changes: 10 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ else()
option(ENABLE_SINGLE_APP_BUILD "Builds client and launcher as single executable" OFF)
option(ENABLE_TEST "Enable compilation of unit tests" OFF)
option(ENABLE_LOBBY "Enable compilation of lobby server" OFF)
option(ENABLE_MMAI "Enable compilation of MMAI AI library" OFF)
endif()

# ERM depends on LUA implicitly
Expand Down Expand Up @@ -255,6 +256,10 @@ if(ENABLE_GOLDMASTER)
add_definitions(-DENABLE_GOLDMASTER)
endif()

if(ENABLE_MMAI)
add_definitions(-DENABLE_MMAI)
endif()

if(APPLE_IOS)
set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_OSX_DEPLOYMENT_TARGET 12.0)
Expand Down Expand Up @@ -712,7 +717,11 @@ if(ANDROID)
else()
install(DIRECTORY config DESTINATION ${DATA_DIR})
if (ENABLE_CLIENT OR ENABLE_SERVER)
install(DIRECTORY Mods DESTINATION ${DATA_DIR})
if (ENABLE_MMAI)
install(DIRECTORY Mods DESTINATION ${DATA_DIR})
else()
install(DIRECTORY Mods DESTINATION ${DATA_DIR} PATTERN "MMAI" EXCLUDE)
endif()
endif()
endif()
if(ENABLE_LUA)
Expand Down
1 change: 1 addition & 0 deletions Mods/MMAI
Submodule MMAI added at 604ea3
3 changes: 3 additions & 0 deletions client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,9 @@ if(NOT ENABLE_STATIC_LIBS)
if(ENABLE_NULLKILLER_AI)
add_dependencies(vcmiclientcommon Nullkiller)
endif()
if(ENABLE_MMAI)
add_dependencies(vcmiclientcommon MMAI)
endif()
endif()
if(APPLE_IOS)
if(ENABLE_ERM)
Expand Down
23 changes: 14 additions & 9 deletions client/CPlayerInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -628,15 +628,7 @@ void CPlayerInterface::battleStart(const BattleID & battleID, const CCreatureSet

if ((replayAllowed && useQuickCombat) || forceQuickCombat)
{
autofightingAI = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());

AutocombatPreferences autocombatPreferences = AutocombatPreferences();
autocombatPreferences.enableSpellsUsage = settings["battle"]["enableAutocombatSpells"].Bool();

autofightingAI->initBattleInterface(env, cb, autocombatPreferences);
autofightingAI->battleStart(battleID, army1, army2, tile, hero1, hero2, side, false);
isAutoFightOn = true;
cb->registerBattleInterface(autofightingAI);
prepareAutoFightingAI(battleID, army1, army2, tile, hero1, hero2, side);
}

waitForAllDialogs();
Expand Down Expand Up @@ -1800,6 +1792,19 @@ bool CPlayerInterface::capturedAllEvents()
return false;
}

void CPlayerInterface::prepareAutoFightingAI(const BattleID &bid, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, BattleSide side)
{
autofightingAI = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());

AutocombatPreferences autocombatPreferences = AutocombatPreferences();
autocombatPreferences.enableSpellsUsage = settings["battle"]["enableAutocombatSpells"].Bool();

autofightingAI->initBattleInterface(env, cb, autocombatPreferences);
autofightingAI->battleStart(bid, army1, army2, tile, hero1, hero2, side, false);
isAutoFightOn = true;
cb->registerBattleInterface(autofightingAI);
}

void CPlayerInterface::showWorldViewEx(const std::vector<ObjectPosInfo>& objectPositions, bool showTerrain)
{
EVENT_HANDLER_CALLED_BY_CLIENT;
Expand Down
2 changes: 2 additions & 0 deletions client/CPlayerInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ class CPlayerInterface : public CGameInterface, public IUpdateable
///returns true if all events are processed internally
bool capturedAllEvents();

void prepareAutoFightingAI(const BattleID &bid, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, BattleSide side);

CPlayerInterface(PlayerColor Player);
~CPlayerInterface();

Expand Down
24 changes: 2 additions & 22 deletions client/battle/BattleWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,16 +696,7 @@ void BattleWindow::bAutofightf()
owner.curInt->isAutoFightOn = true;
blockUI(true);

auto ai = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());

AutocombatPreferences autocombatPreferences = AutocombatPreferences();
autocombatPreferences.enableSpellsUsage = settings["battle"]["enableAutocombatSpells"].Bool();

ai->initBattleInterface(owner.curInt->env, owner.curInt->cb, autocombatPreferences);
ai->battleStart(owner.getBattleID(), owner.army1, owner.army2, int3(0,0,0), owner.attackingHeroInstance, owner.defendingHeroInstance, owner.getBattle()->battleGetMySide(), false);
owner.curInt->autofightingAI = ai;
owner.curInt->cb->registerBattleInterface(ai);

owner.curInt->prepareAutoFightingAI(owner.getBattleID(), owner.army1, owner.army2, int3(0,0,0), owner.attackingHeroInstance, owner.defendingHeroInstance, owner.getBattle()->battleGetMySide());
owner.requestAutofightingAIToTakeAction();
}
}
Expand Down Expand Up @@ -896,18 +887,7 @@ void BattleWindow::endWithAutocombat()
[this]()
{
owner.curInt->isAutoFightEndBattle = true;

auto ai = CDynLibHandler::getNewBattleAI(settings["server"]["friendlyAI"].String());

AutocombatPreferences autocombatPreferences = AutocombatPreferences();
autocombatPreferences.enableSpellsUsage = settings["battle"]["enableAutocombatSpells"].Bool();

ai->initBattleInterface(owner.curInt->env, owner.curInt->cb, autocombatPreferences);
ai->battleStart(owner.getBattleID(), owner.army1, owner.army2, int3(0,0,0), owner.attackingHeroInstance, owner.defendingHeroInstance, owner.getBattle()->battleGetMySide(), false);

owner.curInt->isAutoFightOn = true;
owner.curInt->cb->registerBattleInterface(ai);
owner.curInt->autofightingAI = ai;
owner.curInt->prepareAutoFightingAI(owner.getBattleID(), owner.army1, owner.army2, int3(0,0,0), owner.attackingHeroInstance, owner.defendingHeroInstance, owner.getBattle()->battleGetMySide());

owner.requestAutofightingAIToTakeAction();

Expand Down
2 changes: 2 additions & 0 deletions include/vstd/CLoggerBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ class DLL_LINKAGE CLoggerBase
virtual bool isDebugEnabled() const = 0;
virtual bool isTraceEnabled() const = 0;

virtual ELogLevel::ELogLevel getLevel() const = 0;

template<typename T, typename ... Args>
void log(ELogLevel::ELogLevel level, const std::string & format, T t, Args ... args) const
{
Expand Down
41 changes: 30 additions & 11 deletions launcher/settingsView/csettingsview_moc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ void CSettingsView::loadSettings()
else
ui->comboBoxFullScreen->setCurrentIndex(settings["video"]["fullscreen"].Bool());
#endif

#ifdef ENABLE_MMAI
// Can play only as defender for now
ui->comboBoxNeutralAI->addItem("MMAI (experimental)", "MMAI");
// ui->comboBoxFriendlyAI->addItem("MMAI (experimental)", "MMAI");
// ui->comboBoxEnemyAI->addItem("MMAI (experimental)", "MMAI");
#endif

fillValidScalingRange();

ui->buttonScalingAuto->setChecked(settings["video"]["resolution"]["scaling"].Integer() == 0);
Expand All @@ -137,12 +145,20 @@ void CSettingsView::loadSettings()
ui->spinBoxFramerateLimit->setDisabled(settings["video"]["vsync"].Bool());
ui->sliderReservedArea->setValue(std::round(settings["video"]["reservedWidth"].Float() * 100));

ui->comboBoxFriendlyAI->setCurrentText(QString::fromStdString(settings["server"]["friendlyAI"].String()));
ui->comboBoxNeutralAI->setCurrentText(QString::fromStdString(settings["server"]["neutralAI"].String()));
ui->comboBoxEnemyAI->setCurrentText(QString::fromStdString(settings["server"]["enemyAI"].String()));
// Find an entry by value and select it
auto setValue = [](QComboBox * box, std::string value)
{
auto qstr = QString::fromStdString(value);
int index = box->findData(qstr);
index >= 0 ? box->setCurrentIndex(index) : box->setCurrentText(qstr);
};

setValue(ui->comboBoxFriendlyAI, settings["server"]["friendlyAI"].String());
setValue(ui->comboBoxNeutralAI, settings["server"]["neutralAI"].String());
setValue(ui->comboBoxEnemyAI, settings["server"]["enemyAI"].String());

ui->comboBoxEnemyPlayerAI->setCurrentText(QString::fromStdString(settings["server"]["playerAI"].String()));
ui->comboBoxAlliedPlayerAI->setCurrentText(QString::fromStdString(settings["server"]["alliedAI"].String()));
setValue(ui->comboBoxEnemyPlayerAI, settings["server"]["playerAI"].String());
setValue(ui->comboBoxAlliedPlayerAI, settings["server"]["alliedAI"].String());

ui->spinBoxNetworkPort->setValue(settings["server"]["localPort"].Integer());

Expand Down Expand Up @@ -434,22 +450,25 @@ void CSettingsView::on_comboBoxDisplayIndex_currentIndexChanged(int index)
fillValidResolutionsForScreen(index);
}

void CSettingsView::on_comboBoxFriendlyAI_currentTextChanged(const QString & arg1)
void CSettingsView::on_comboBoxFriendlyAI_currentTextChanged(const QString & text)
{
Settings node = settings.write["server"]["friendlyAI"];
node->String() = arg1.toUtf8().data();
auto value = ui->comboBoxFriendlyAI->currentData().toString();
node->String() = value.isEmpty() ? text.toUtf8().data() : value.toUtf8().data();
}

void CSettingsView::on_comboBoxNeutralAI_currentTextChanged(const QString & arg1)
void CSettingsView::on_comboBoxNeutralAI_currentTextChanged(const QString & text)
{
Settings node = settings.write["server"]["neutralAI"];
node->String() = arg1.toUtf8().data();
auto value = ui->comboBoxNeutralAI->currentData().toString();
node->String() = value.isEmpty() ? text.toUtf8().data() : value.toUtf8().data();
}

void CSettingsView::on_comboBoxEnemyAI_currentTextChanged(const QString & arg1)
void CSettingsView::on_comboBoxEnemyAI_currentTextChanged(const QString & text)
{
Settings node = settings.write["server"]["enemyAI"];
node->String() = arg1.toUtf8().data();
auto value = ui->comboBoxEnemyAI->currentData().toString();
node->String() = value.isEmpty() ? text.toUtf8().data() : value.toUtf8().data();
}

void CSettingsView::on_spinBoxNetworkPort_valueChanged(int arg1)
Expand Down
Loading

0 comments on commit aa5e6e3

Please sign in to comment.