From 653304b004892270a54a442e75bb3d4097f3550b Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Thu, 23 Nov 2023 17:59:18 +0200 Subject: [PATCH] Implemented accumulating timers, rename creature timer to unit timer --- client/NetPacksClient.cpp | 2 +- client/adventureMap/TurnTimerWidget.cpp | 4 +- client/lobby/OptionsTab.cpp | 10 ++- client/lobby/OptionsTabBase.cpp | 12 +-- lib/TurnTimerInfo.cpp | 2 +- lib/TurnTimerInfo.h | 9 ++- server/TurnTimerHandler.cpp | 103 +++++++++--------------- 7 files changed, 65 insertions(+), 77 deletions(-) diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index df4c66d1b..a6d0bff9a 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -901,7 +901,7 @@ void ApplyClientNetPackVisitor::visitPlayerEndsTurn(PlayerEndsTurn & pack) void ApplyClientNetPackVisitor::visitTurnTimeUpdate(TurnTimeUpdate & pack) { - logNetwork->debug("Server sets turn timer {turn: %d, base: %d, battle: %d, creature: %d} for %s", pack.turnTimer.turnTimer, pack.turnTimer.baseTimer, pack.turnTimer.battleTimer, pack.turnTimer.creatureTimer, pack.player.toString()); + logNetwork->debug("Server sets turn timer {turn: %d, base: %d, battle: %d, creature: %d} for %s", pack.turnTimer.turnTimer, pack.turnTimer.baseTimer, pack.turnTimer.battleTimer, pack.turnTimer.unitTimer, pack.player.toString()); } void ApplyClientNetPackVisitor::visitPlayerMessageClient(PlayerMessageClient & pack) diff --git a/client/adventureMap/TurnTimerWidget.cpp b/client/adventureMap/TurnTimerWidget.cpp index 0d3aaa571..41b77255a 100644 --- a/client/adventureMap/TurnTimerWidget.cpp +++ b/client/adventureMap/TurnTimerWidget.cpp @@ -128,9 +128,9 @@ void TurnTimerWidget::updateTimer(PlayerColor player, uint32_t msPassed) if(player.isValidPlayer() || (playerInfo && playerInfo->isHuman())) { if(time.isBattle) - timeCheckAndUpdate(time.creatureTimer); + timeCheckAndUpdate(time.baseTimer + time.turnTimer + time.battleTimer + time.unitTimer); else - timeCheckAndUpdate(time.turnTimer); + timeCheckAndUpdate(time.baseTimer + time.turnTimer); } else timeCheckAndUpdate(0); diff --git a/client/lobby/OptionsTab.cpp b/client/lobby/OptionsTab.cpp index a7f762965..e7698ba48 100644 --- a/client/lobby/OptionsTab.cpp +++ b/client/lobby/OptionsTab.cpp @@ -42,8 +42,16 @@ #include "../../lib/mapping/CMapInfo.h" #include "../../lib/mapping/CMapHeader.h" +static JsonPath optionsTabConfigLocation() +{ + if(settings["general"]["enableUiEnhancements"].Bool()) + return JsonPath::builtin("config/widgets/playerOptionsTab.json"); + else + return JsonPath::builtin("config/widgets/advancedOptionsTab.json"); +} + OptionsTab::OptionsTab() - : OptionsTabBase(JsonPath::builtin("config/widgets/playerOptionsTab.json")) + : OptionsTabBase(optionsTabConfigLocation()) , humanPlayers(0) { } diff --git a/client/lobby/OptionsTabBase.cpp b/client/lobby/OptionsTabBase.cpp index 18953eb97..185454ce2 100644 --- a/client/lobby/OptionsTabBase.cpp +++ b/client/lobby/OptionsTabBase.cpp @@ -34,7 +34,7 @@ OptionsTabBase::OptionsTabBase(const JsonPath & configPath) tinfo.baseTimer = tpreset.at(0).Integer() * 1000; tinfo.turnTimer = tpreset.at(1).Integer() * 1000; tinfo.battleTimer = tpreset.at(2).Integer() * 1000; - tinfo.creatureTimer = tpreset.at(3).Integer() * 1000; + tinfo.unitTimer = tpreset.at(3).Integer() * 1000; CSH->setTurnTimerInfo(tinfo); } }); @@ -133,7 +133,7 @@ OptionsTabBase::OptionsTabBase(const JsonPath & configPath) if(time >= 0) { TurnTimerInfo tinfo = SEL->getStartInfo()->turnTimerInfo; - tinfo.creatureTimer = time; + tinfo.unitTimer = time; CSH->setTurnTimerInfo(tinfo); } }); @@ -175,7 +175,7 @@ OptionsTabBase::OptionsTabBase(const JsonPath & configPath) tinfo.baseTimer = (*tObj)["default"].Vector().at(0).Integer() * 1000; tinfo.turnTimer = (*tObj)["default"].Vector().at(1).Integer() * 1000; tinfo.battleTimer = (*tObj)["default"].Vector().at(2).Integer() * 1000; - tinfo.creatureTimer = (*tObj)["default"].Vector().at(3).Integer() * 1000; + tinfo.unitTimer = (*tObj)["default"].Vector().at(3).Integer() * 1000; CSH->setTurnTimerInfo(tinfo); } } @@ -251,7 +251,7 @@ void OptionsTabBase::recreate() //classic timer if(auto turnSlider = widget("sliderTurnDuration")) { - if(!variables["timerPresets"].isNull() && !turnTimerRemote.battleTimer && !turnTimerRemote.creatureTimer && !turnTimerRemote.baseTimer) + if(!variables["timerPresets"].isNull() && !turnTimerRemote.battleTimer && !turnTimerRemote.unitTimer && !turnTimerRemote.baseTimer) { for(int idx = 0; idx < variables["timerPresets"].Vector().size(); ++idx) { @@ -281,11 +281,11 @@ void OptionsTabBase::recreate() if(auto ww = widget("chessFieldBattle")) ww->setText(timeToString(turnTimerRemote.battleTimer), false); if(auto ww = widget("chessFieldCreature")) - ww->setText(timeToString(turnTimerRemote.creatureTimer), false); + ww->setText(timeToString(turnTimerRemote.unitTimer), false); if(auto w = widget("timerModeSwitch")) { - if(turnTimerRemote.battleTimer || turnTimerRemote.creatureTimer || turnTimerRemote.baseTimer) + if(turnTimerRemote.battleTimer || turnTimerRemote.unitTimer || turnTimerRemote.baseTimer) { if(auto turnSlider = widget("sliderTurnDuration")) if(turnSlider->isActive()) diff --git a/lib/TurnTimerInfo.cpp b/lib/TurnTimerInfo.cpp index 0594fad65..c7fbcd936 100644 --- a/lib/TurnTimerInfo.cpp +++ b/lib/TurnTimerInfo.cpp @@ -19,7 +19,7 @@ bool TurnTimerInfo::isEnabled() const bool TurnTimerInfo::isBattleEnabled() const { - return creatureTimer > 0 || battleTimer > 0; + return unitTimer > 0 || battleTimer > 0; } VCMI_LIB_NAMESPACE_END diff --git a/lib/TurnTimerInfo.h b/lib/TurnTimerInfo.h index c708345b4..93d951538 100644 --- a/lib/TurnTimerInfo.h +++ b/lib/TurnTimerInfo.h @@ -17,7 +17,10 @@ struct DLL_LINKAGE TurnTimerInfo int turnTimer = 0; //in ms, counts down when player is making his turn on adventure map int baseTimer = 0; //in ms, counts down only when turn timer runs out int battleTimer = 0; //in ms, counts down during battles when creature timer runs out - int creatureTimer = 0; //in ms, counts down when player is choosing action in battle + int unitTimer = 0; //in ms, counts down when player is choosing action in battle + + bool accumulatingTurnTimer = false; + bool accumulatingUnitTimer = false; bool isActive = false; //is being counting down bool isBattle = false; //indicator for current timer mode @@ -31,7 +34,9 @@ struct DLL_LINKAGE TurnTimerInfo h & turnTimer; h & baseTimer; h & battleTimer; - h & creatureTimer; + h & unitTimer; + h & accumulatingTurnTimer; + h & accumulatingUnitTimer; h & isActive; h & isBattle; } diff --git a/server/TurnTimerHandler.cpp b/server/TurnTimerHandler.cpp index ebd51e826..fcf80c4f8 100644 --- a/server/TurnTimerHandler.cpp +++ b/server/TurnTimerHandler.cpp @@ -74,7 +74,7 @@ void TurnTimerHandler::onPlayerGetTurn(PlayerColor player) { endTurnAllowed[player] = true; auto & timer = timers[player]; - if(si->turnTimerInfo.baseTimer > 0) + if(si->turnTimerInfo.accumulatingTurnTimer > 0) timer.baseTimer += timer.turnTimer; timer.turnTimer = si->turnTimerInfo.turnTimer; @@ -127,17 +127,14 @@ void TurnTimerHandler::onPlayerMakingTurn(PlayerColor player, int waitTime) const auto * state = gameHandler.getPlayerState(player); if(state && state->human && timer.isActive && !timer.isBattle && state->status == EPlayerStatus::INGAME) { - if(!timerCountDown(timer.turnTimer, si->turnTimerInfo.turnTimer, player, waitTime)) - { - if(timer.baseTimer > 0) - { - timer.turnTimer = timer.baseTimer; - timer.baseTimer = 0; - onPlayerMakingTurn(player, 0); - } - else if(endTurnAllowed[state->color] && !gameHandler.queries->topQuery(state->color)) //wait for replies to avoid pending queries - gameHandler.turnOrder->onPlayerEndsTurn(state->color); - } + if(timerCountDown(timer.turnTimer, si->turnTimerInfo.turnTimer, player, waitTime)) + return; + + if(timerCountDown(timer.baseTimer, si->turnTimerInfo.baseTimer, player, waitTime)) + return; + + if(endTurnAllowed[state->color] && !gameHandler.queries->topQuery(state->color)) //wait for replies to avoid pending queries + gameHandler.turnOrder->onPlayerEndsTurn(state->color); } } @@ -176,8 +173,8 @@ void TurnTimerHandler::onBattleStart(const BattleID & battleID) auto & timer = timers[i]; timer.isBattle = true; timer.isActive = si->turnTimerInfo.isBattleEnabled(); - timer.battleTimer = (pvpBattle ? si->turnTimerInfo.battleTimer : 0); - timer.creatureTimer = (pvpBattle ? si->turnTimerInfo.creatureTimer : si->turnTimerInfo.battleTimer); + timer.battleTimer = si->turnTimerInfo.battleTimer; + timer.unitTimer = (pvpBattle ? si->turnTimerInfo.unitTimer : 0); sendTimerUpdate(i); } @@ -201,8 +198,6 @@ void TurnTimerHandler::onBattleEnd(const BattleID & battleID) auto attacker = gs->getBattle(battleID)->getSidePlayer(BattleSide::ATTACKER); auto defender = gs->getBattle(battleID)->getSidePlayer(BattleSide::DEFENDER); - bool pvpBattle = isPvpBattle(battleID); - for(auto i : {attacker, defender}) { if(i.isValidPlayer()) @@ -210,14 +205,6 @@ void TurnTimerHandler::onBattleEnd(const BattleID & battleID) auto & timer = timers[i]; timer.isBattle = false; timer.isActive = true; - if(!pvpBattle) - { - if(si->turnTimerInfo.baseTimer && timer.baseTimer == 0) - timer.baseTimer = timer.creatureTimer; - else if(si->turnTimerInfo.turnTimer && timer.turnTimer == 0) - timer.turnTimer = timer.creatureTimer; - } - sendTimerUpdate(i); } } @@ -242,9 +229,9 @@ void TurnTimerHandler::onBattleNextStack(const BattleID & battleID, const CStack auto player = stack.getOwner(); auto & timer = timers[player]; - if(timer.battleTimer == 0) - timer.battleTimer = timer.creatureTimer; - timer.creatureTimer = si->turnTimerInfo.creatureTimer; + if(timer.accumulatingUnitTimer) + timer.battleTimer += timer.unitTimer; + timer.unitTimer = si->turnTimerInfo.unitTimer; sendTimerUpdate(player); } @@ -283,56 +270,44 @@ void TurnTimerHandler::onBattleLoop(const BattleID & battleID, int waitTime) return; const auto * state = gameHandler.getPlayerState(player); - assert(state && state->status != EPlayerStatus::INGAME); + assert(state && state->status == EPlayerStatus::INGAME); if(!state || state->status != EPlayerStatus::INGAME || !state->human) return; auto & timer = timers[player]; - if(timer.isActive && timer.isBattle && !timerCountDown(timer.creatureTimer, si->turnTimerInfo.creatureTimer, player, waitTime)) + if(timer.isActive && timer.isBattle) { + if (timerCountDown(timer.unitTimer, si->turnTimerInfo.unitTimer, player, waitTime)) + return; + + if (timerCountDown(timer.battleTimer, si->turnTimerInfo.battleTimer, player, waitTime)) + return; + + if (timerCountDown(timer.turnTimer, si->turnTimerInfo.turnTimer, player, waitTime)) + return; + + if (timerCountDown(timer.baseTimer, si->turnTimerInfo.baseTimer, player, waitTime)) + return; + if(isPvpBattle(battleID)) { - if(timer.battleTimer > 0) - { - timer.creatureTimer = timer.battleTimer; - timerCountDown(timer.creatureTimer, timer.battleTimer, player, 0); - timer.battleTimer = 0; - } + BattleAction doNothing; + doNothing.side = side; + if(isTactisPhase) + doNothing.actionType = EActionType::END_TACTIC_PHASE; else { - BattleAction doNothing; - doNothing.side = side; - if(isTactisPhase) - doNothing.actionType = EActionType::END_TACTIC_PHASE; - else - { - doNothing.actionType = EActionType::DEFEND; - doNothing.stackNumber = stack->unitId(); - } - gameHandler.battles->makePlayerBattleAction(battleID, player, doNothing); + doNothing.actionType = EActionType::DEFEND; + doNothing.stackNumber = stack->unitId(); } + gameHandler.battles->makePlayerBattleAction(battleID, player, doNothing); } else { - if(timer.turnTimer > 0) - { - timer.creatureTimer = timer.turnTimer; - timerCountDown(timer.creatureTimer, timer.turnTimer, player, 0); - timer.turnTimer = 0; - } - else if(timer.baseTimer > 0) - { - timer.creatureTimer = timer.baseTimer; - timerCountDown(timer.creatureTimer, timer.baseTimer, player, 0); - timer.baseTimer = 0; - } - else - { - BattleAction retreat; - retreat.side = side; - retreat.actionType = EActionType::RETREAT; //harsh punishment - gameHandler.battles->makePlayerBattleAction(battleID, player, retreat); - } + BattleAction retreat; + retreat.side = side; + retreat.actionType = EActionType::RETREAT; //harsh punishment + gameHandler.battles->makePlayerBattleAction(battleID, player, retreat); } } }