1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-26 03:52:01 +02:00

Merge pull request #1789 from IvanSavenko/beta_fixes

Fixes for 1.2 release
This commit is contained in:
Ivan Savenko 2023-03-30 00:09:51 +03:00 committed by GitHub
commit 8a3e1b0230
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 138 additions and 90 deletions

View File

@ -118,17 +118,17 @@
// few strings from WoG used by vcmi
"vcmi.stackExperience.description" : "» 经 验 获 得 明 细 «\n\n生物类型 ................... : %s\n经验等级 ................. : %s (%i)\n经验点数 ............... : %i\n下一个等级所需经验 .. : %i\n每次战斗最大获得经验 ... : %i%% (%i)\n获得经验的生物数量 .... : %i\n最大招募数量\n不会丢失经验升级 .... : %i\n经验倍数 ........... : %.2f\n升级倍数 .............. : %.2f\n10级后经验值 ........ : %i\n最大招募数量下\n 升级到10级所需经验数量: %i",
"vcmi.stackExperience.rank.1" : "新兵 1级",
"vcmi.stackExperience.rank.2" : "列兵 2级",
"vcmi.stackExperience.rank.3" : "下士 3级",
"vcmi.stackExperience.rank.4" : "中士 4级",
"vcmi.stackExperience.rank.5" : "上士 5级",
"vcmi.stackExperience.rank.6" : "少尉 6级",
"vcmi.stackExperience.rank.7" : "中尉 7级",
"vcmi.stackExperience.rank.8" : "上尉 8级",
"vcmi.stackExperience.rank.9" : "少校 9级",
"vcmi.stackExperience.rank.10" : "中校 10级",
"vcmi.stackExperience.rank.11" : "上校 11级",
"vcmi.stackExperience.rank.0" : "新兵 1级",
"vcmi.stackExperience.rank.1" : "列兵 2级",
"vcmi.stackExperience.rank.2" : "下士 3级",
"vcmi.stackExperience.rank.3" : "中士 4级",
"vcmi.stackExperience.rank.4" : "上士 5级",
"vcmi.stackExperience.rank.5" : "少尉 6级",
"vcmi.stackExperience.rank.6" : "中尉 7级",
"vcmi.stackExperience.rank.7" : "上尉 8级",
"vcmi.stackExperience.rank.8" : "少校 9级",
"vcmi.stackExperience.rank.9" : "中校 10级",
"vcmi.stackExperience.rank.10" : "上校 11级",
"core.bonus.ADDITIONAL_ATTACK.name": "双击",
"core.bonus.ADDITIONAL_ATTACK.description": "可以攻击两次",

View File

@ -142,17 +142,17 @@
// few strings from WoG used by vcmi
"vcmi.stackExperience.description" : "» S t a c k E x p e r i e n c e D e t a i l s «\n\nCreature Type ................... : %s\nExperience Rank ................. : %s (%i)\nExperience Points ............... : %i\nExperience Points to Next Rank .. : %i\nMaximum Experience per Battle ... : %i%% (%i)\nNumber of Creatures in stack .... : %i\nMaximum New Recruits\n without losing current Rank .... : %i\nExperience Multiplier ........... : %.2f\nUpgrade Multiplier .............. : %.2f\nExperience after Rank 10 ........ : %i\nMaximum New Recruits to remain at\n Rank 10 if at Maximum Experience : %i",
"vcmi.stackExperience.rank.1" : "Basic",
"vcmi.stackExperience.rank.2" : "Novice",
"vcmi.stackExperience.rank.3" : "Trained",
"vcmi.stackExperience.rank.4" : "Skilled",
"vcmi.stackExperience.rank.5" : "Proven",
"vcmi.stackExperience.rank.6" : "Veteran",
"vcmi.stackExperience.rank.7" : "Adept",
"vcmi.stackExperience.rank.8" : "Expert",
"vcmi.stackExperience.rank.9" : "Elite",
"vcmi.stackExperience.rank.10" : "Master",
"vcmi.stackExperience.rank.11" : "Ace",
"vcmi.stackExperience.rank.0" : "Basic",
"vcmi.stackExperience.rank.1" : "Novice",
"vcmi.stackExperience.rank.2" : "Trained",
"vcmi.stackExperience.rank.3" : "Skilled",
"vcmi.stackExperience.rank.4" : "Proven",
"vcmi.stackExperience.rank.5" : "Veteran",
"vcmi.stackExperience.rank.6" : "Adept",
"vcmi.stackExperience.rank.7" : "Expert",
"vcmi.stackExperience.rank.8" : "Elite",
"vcmi.stackExperience.rank.9" : "Master",
"vcmi.stackExperience.rank.10" : "Ace",
"core.bonus.ADDITIONAL_ATTACK.name": "Double Strike",
"core.bonus.ADDITIONAL_ATTACK.description": "Attacks twice",

View File

@ -143,17 +143,17 @@
// few strings from WoG used by vcmi
"vcmi.stackExperience.description" : "» D e t a i l s z u r S t a p e l e r f a h r u n g «\n\nKreatur-Typ ................... : %s\nErfahrungsrang ................. : %s (%i)\nErfahrungspunkte ............... : %i\nErfahrungspunkte für den nächsten Rang .. : %i\nMaximale Erfahrung pro Kampf ... : %i%% (%i)\nAnzahl der Kreaturen im Stapel .... : %i\nMaximale Anzahl neuer Rekruten\n ohne Verlust von aktuellem Rang .... : %i\nErfahrungs-Multiplikator ........... : %.2f\nUpgrade-Multiplikator .............. : %.2f\nErfahrung nach Rang 10 ........ : %i\nMaximale Anzahl der neuen Rekruten, die bei\n Rang 10 bei maximaler Erfahrung übrig sind : %i",
"vcmi.stackExperience.rank.1" : "Grundlagen",
"vcmi.stackExperience.rank.2" : "Neuling",
"vcmi.stackExperience.rank.3" : "Ausgebildet",
"vcmi.stackExperience.rank.4" : "Kompetent",
"vcmi.stackExperience.rank.5" : "Bewährt",
"vcmi.stackExperience.rank.6" : "Veteran",
"vcmi.stackExperience.rank.7" : "Gekonnt",
"vcmi.stackExperience.rank.8" : "Experte",
"vcmi.stackExperience.rank.9" : "Elite",
"vcmi.stackExperience.rank.10" : "Meister",
"vcmi.stackExperience.rank.11" : "Ass",
"vcmi.stackExperience.rank.0" : "Grundlagen",
"vcmi.stackExperience.rank.1" : "Neuling",
"vcmi.stackExperience.rank.2" : "Ausgebildet",
"vcmi.stackExperience.rank.3" : "Kompetent",
"vcmi.stackExperience.rank.4" : "Bewährt",
"vcmi.stackExperience.rank.5" : "Veteran",
"vcmi.stackExperience.rank.6" : "Gekonnt",
"vcmi.stackExperience.rank.7" : "Experte",
"vcmi.stackExperience.rank.8" : "Elite",
"vcmi.stackExperience.rank.9" : "Meister",
"vcmi.stackExperience.rank.10" : "Ass",
"core.bonus.ADDITIONAL_ATTACK.name": "Doppelschlag",
"core.bonus.ADDITIONAL_ATTACK.description": "Greift zweimal an",

View File

@ -145,17 +145,17 @@
// few strings from WoG used by vcmi
"vcmi.stackExperience.description" : "» О п ы т с у щ е с т в «\n\nТип существа ................... : %s\nРанг опыта ................. : %s (%i)\nОчки опыта ............... : %i\nДо следующего .. : %i\nМаксимум за битву ... : %i%% (%i)\nЧисло в отряде .... : %i\nМаксимум новичков\n без потери ранга .... : %i\nМножитель опыта ........... : %.2f\nМножитель улучшения .......... : %.2f\nОпыт после 10 ранга ........ : %i\nМаксимум новичков для сохранения\n ранга 10 при максимальном опыте : %i",
"vcmi.stackExperience.rank.1" : "Рекрут",
"vcmi.stackExperience.rank.2" : "Новичок",
"vcmi.stackExperience.rank.3" : "Тренирован",
"vcmi.stackExperience.rank.4" : "Знающий",
"vcmi.stackExperience.rank.5" : "Подтвержденный",
"vcmi.stackExperience.rank.6" : "Ветеран",
"vcmi.stackExperience.rank.7" : "Адепт",
"vcmi.stackExperience.rank.8" : "Эксперт",
"vcmi.stackExperience.rank.9" : "Элита",
"vcmi.stackExperience.rank.10" : "Мастер",
"vcmi.stackExperience.rank.11" : "Ас",
"vcmi.stackExperience.rank.0" : "Рекрут",
"vcmi.stackExperience.rank.1" : "Новичок",
"vcmi.stackExperience.rank.2" : "Тренирован",
"vcmi.stackExperience.rank.3" : "Знающий",
"vcmi.stackExperience.rank.4" : "Подтвержденный",
"vcmi.stackExperience.rank.5" : "Ветеран",
"vcmi.stackExperience.rank.6" : "Адепт",
"vcmi.stackExperience.rank.7" : "Эксперт",
"vcmi.stackExperience.rank.8" : "Элита",
"vcmi.stackExperience.rank.9" : "Мастер",
"vcmi.stackExperience.rank.10" : "Ас",
"core.bonus.ADDITIONAL_ATTACK.name": "Двойной удар",
"core.bonus.ADDITIONAL_ATTACK.description": "Бьет дважды",

View File

@ -131,17 +131,17 @@
// few strings from WoG used by vcmi
"vcmi.stackExperience.description" : "» D e t a l l e s d e E x p e r i e n c i a d e l G r u p o «\n\nTipo de Criatura ................ : %s\nRango de Experiencia ............ : %s (%i)\nPuntos de Experiencia ............ : %i\nPuntos de Experiencia para el\nSiguiente Rango ............... : %i\nExperiencia Máxima por Batalla .. : %i%% (%i)\nNúmero de Criaturas en el grupo .. : %i\nMáximo de Nuevos Reclutas sin\nPerder el Rango Actual ......... : %i\nMultiplicador de Experiencia .... : %.2f\nMultiplicador de Actualización .. : %.2f\nExperiencia después del Rango 10 : %i\nMáximo de Nuevos Reclutas para\nMantener el Rango 10 si\nEstá en la Experiencia Máxima : %i",
"vcmi.stackExperience.rank.1" : "Básico",
"vcmi.stackExperience.rank.2" : "Novato",
"vcmi.stackExperience.rank.3" : "Entrenado",
"vcmi.stackExperience.rank.4" : "Hábil",
"vcmi.stackExperience.rank.5" : "Probado",
"vcmi.stackExperience.rank.6" : "Veterano",
"vcmi.stackExperience.rank.7" : "Experto",
"vcmi.stackExperience.rank.8" : "Experto Superior",
"vcmi.stackExperience.rank.9" : "Élite",
"vcmi.stackExperience.rank.10" : "Maestro",
"vcmi.stackExperience.rank.11" : "As",
"vcmi.stackExperience.rank.0" : "Básico",
"vcmi.stackExperience.rank.1" : "Novato",
"vcmi.stackExperience.rank.2" : "Entrenado",
"vcmi.stackExperience.rank.3" : "Hábil",
"vcmi.stackExperience.rank.4" : "Probado",
"vcmi.stackExperience.rank.5" : "Veterano",
"vcmi.stackExperience.rank.6" : "Experto",
"vcmi.stackExperience.rank.7" : "Experto Superior",
"vcmi.stackExperience.rank.8" : "Élite",
"vcmi.stackExperience.rank.9" : "Maestro",
"vcmi.stackExperience.rank.10" : "As",
"core.bonus.ADDITIONAL_ATTACK.name": "Doble Ataque",
"core.bonus.ADDITIONAL_ATTACK.description": "Ataca dos veces",

View File

@ -295,15 +295,15 @@
"core.bonus.LIMITED_SHOOTING_RANGE.description" : "Не може стріляти по цілях на відстані більше ${val} гексів",
"vcmi.stackExperience.description" : "» S t a c k E x p e r i e n c e D e t a i l s «\n\nCreature Type ................... : %s\nExperience Rank ................. : %s (%i)\nExperience Points ............... : %i\nExperience Points to Next Rank .. : %i\nMaximum Experience per Battle ... : %i%% (%i)\nNumber of Creatures in stack .... : %i\nMaximum New Recruits\n without losing current Rank .... : %i\nExperience Multiplier ........... : %.2f\nUpgrade Multiplier .............. : %.2f\nExperience after Rank 10 ........ : %i\nMaximum New Recruits to remain at\n Rank 10 if at Maximum Experience : %i",
"vcmi.stackExperience.rank.1" : "Початковий",
"vcmi.stackExperience.rank.2" : "Новачок",
"vcmi.stackExperience.rank.3" : "Підготовлений",
"vcmi.stackExperience.rank.4" : "Досвідчений",
"vcmi.stackExperience.rank.5" : "Випробуваний",
"vcmi.stackExperience.rank.6" : "Ветеран",
"vcmi.stackExperience.rank.7" : "Адепт",
"vcmi.stackExperience.rank.8" : "Експерт",
"vcmi.stackExperience.rank.9" : "Еліта",
"vcmi.stackExperience.rank.10" : "Майстер",
"vcmi.stackExperience.rank.11" : "Профі",
"vcmi.stackExperience.rank.0" : "Початковий",
"vcmi.stackExperience.rank.1" : "Новачок",
"vcmi.stackExperience.rank.2" : "Підготовлений",
"vcmi.stackExperience.rank.3" : "Досвідчений",
"vcmi.stackExperience.rank.4" : "Випробуваний",
"vcmi.stackExperience.rank.5" : "Ветеран",
"vcmi.stackExperience.rank.6" : "Адепт",
"vcmi.stackExperience.rank.7" : "Експерт",
"vcmi.stackExperience.rank.8" : "Еліта",
"vcmi.stackExperience.rank.9" : "Майстер",
"vcmi.stackExperience.rank.10" : "Профі",
}

View File

@ -142,11 +142,13 @@ Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound, bool cache)
int CSoundHandler::ambientDistToVolume(int distance) const
{
if(distance >= ambientConfig["distances"].Vector().size())
const auto & distancesVector = ambientConfig["distances"].Vector();
if(distance >= distancesVector.size())
return 0;
int volume = static_cast<int>(ambientConfig["distances"].Vector()[distance].Integer());
return volume * (int)ambientConfig["volume"].Integer() * getVolume() / 10000;
int volume = static_cast<int>(distancesVector[distance].Integer());
return volume * (int)ambientConfig["volume"].Integer() / 100;
}
void CSoundHandler::ambientStopSound(std::string soundId)
@ -211,7 +213,20 @@ void CSoundHandler::setVolume(ui32 percent)
CAudioBase::setVolume(percent);
if (initialized)
{
setChannelVolume(-1, volume);
for (auto const & channel : channelVolumes)
updateChannelVolume(channel.first);
}
}
void CSoundHandler::updateChannelVolume(int channel)
{
if (channelVolumes.count(channel))
setChannelVolume(channel, getVolume() * channelVolumes[channel] / 100);
else
setChannelVolume(channel, getVolume());
}
// Sets the sound volume, from 0 (mute) to 100
@ -258,29 +273,40 @@ void CSoundHandler::ambientUpdateChannels(std::map<std::string, int> soundsArg)
std::vector<std::string> stoppedSounds;
for(auto & pair : ambientChannels)
{
if(!vstd::contains(soundsArg, pair.first))
const std::string & soundId = pair.first;
const int channel = pair.second;
if(!vstd::contains(soundsArg, soundId))
{
ambientStopSound(pair.first);
stoppedSounds.push_back(pair.first);
ambientStopSound(soundId);
stoppedSounds.push_back(soundId);
}
else
{
int volume = ambientDistToVolume(soundsArg[pair.first]);
CCS->soundh->setChannelVolume(pair.second, volume);
int volume = ambientDistToVolume(soundsArg[soundId]);
channelVolumes[channel] = volume;
updateChannelVolume(channel);
}
}
for(auto soundId : stoppedSounds)
{
channelVolumes.erase(ambientChannels[soundId]);
ambientChannels.erase(soundId);
}
for(auto & pair : soundsArg)
{
if(!vstd::contains(ambientChannels, pair.first))
{
int channel = CCS->soundh->playSound(pair.first, -1);
int volume = ambientDistToVolume(pair.second);
const std::string & soundId = pair.first;
const int distance = pair.second;
CCS->soundh->setChannelVolume(channel, volume);
CCS->soundh->ambientChannels.insert(std::make_pair(pair.first, channel));
if(!vstd::contains(ambientChannels, soundId))
{
int channel = playSound(soundId, -1);
int volume = ambientDistToVolume(distance);
channelVolumes[channel] = volume;
updateChannelVolume(channel);
ambientChannels[soundId] = channel;
}
}
}
@ -293,6 +319,7 @@ void CSoundHandler::ambientStopAllChannels()
{
ambientStopSound(ch.first);
}
channelVolumes.clear();
ambientChannels.clear();
}

View File

@ -51,9 +51,12 @@ private:
int ambientDistToVolume(int distance) const;
void ambientStopSound(std::string soundId);
void updateChannelVolume(int channel);
const JsonNode ambientConfig;
std::map<std::string, int> ambientChannels;
std::map<int, int> channelVolumes;
public:
CSoundHandler();

View File

@ -119,7 +119,10 @@ BattleActionsController::BattleActionsController(BattleInterface & owner):
void BattleActionsController::endCastingSpell()
{
if(heroSpellToCast)
{
heroSpellToCast.reset();
owner.windowObject->blockUI(false);
}
if(owner.stacksController->getActiveStack())
possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack()); //restore actions after they were cleared
@ -287,6 +290,8 @@ void BattleActionsController::castThisSpell(SpellID spellID)
possibleActions.push_back (spellSelMode); //only this one action can be performed at the moment
GH.fakeMouseMove();//update cursor
}
owner.windowObject->blockUI(true);
}
const CSpell * BattleActionsController::getHeroSpellToCast( ) const

View File

@ -756,7 +756,15 @@ void ShootingAnimation::createProjectile(const Point & from, const Point & dest)
uint32_t ShootingAnimation::getAttackClimaxFrame() const
{
const CCreature *shooterInfo = getCreature();
return shooterInfo->animation.attackClimaxFrame;
uint32_t maxFrames = stackAnimation(attackingStack)->framesInGroup(getGroup());
uint32_t climaxFrame = shooterInfo->animation.attackClimaxFrame;
uint32_t selectedFrame = vstd::clamp(shooterInfo->animation.attackClimaxFrame, 1, maxFrames);
if (climaxFrame != selectedFrame)
logGlobal->warn("Shooter %s has ranged attack climax frame set to %d, but only %d available!", shooterInfo->getNamePluralTranslated(), climaxFrame, maxFrames);
return selectedFrame - 1; // H3 counts frames from 1
}
ECreatureAnimType ShootingAnimation::getUpwardsGroup() const

View File

@ -541,11 +541,8 @@ void BattleWindow::blockUI(bool on)
w->block(on || owner.tacticsMode);
if(auto w = widget<CButton>("alternativeAction"))
w->block(on || owner.tacticsMode);
// block only if during enemy turn and auto-fight is off
// otherwise - crash on accessing non-exisiting active stack
if(auto w = widget<CButton>("options"))
w->block(!owner.curInt->isAutoFightOn && !owner.stacksController->getActiveStack());
if(auto w = widget<CButton>("autofight"))
w->block(owner.actionsController->spellcastingModeActive());
auto btactEnd = widget<CButton>("tacticEnd");
auto btactNext = widget<CButton>("tacticNext");

View File

@ -727,6 +727,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil
switch(subID)
{
case BuildingSubID::NONE:
enterBuilding(building);
break;
case BuildingSubID::MYSTIC_POND:

View File

@ -104,7 +104,7 @@
"index": 10,
"faction" : "dungeon",
"defaultTavern" : 5,
"affinity" : "might",
"affinity" : "magic",
"commander" : "medusaQueen",
"mapObject" : { "templates" : { "default" : { "animation" : "AH11_.def", "editorAnimation": "AH11_E.def" } } },
"animation": { "battle" : { "male" : "CH010.DEF", "female" : "CH11.DEF" } }
@ -114,7 +114,7 @@
"index": 11,
"faction" : "dungeon",
"defaultTavern" : 5,
"affinity" : "magic",
"affinity" : "might",
"commander" : "medusaQueen",
"mapObject" : { "templates" : { "default" : { "animation" : "AH10_.def", "editorAnimation": "AH10_E.def" } } },
"animation": { "battle" : { "male" : "CH010.DEF", "female" : "CH11.DEF" } }

View File

@ -215,7 +215,7 @@
"handler" : "whirlpool",
"base" : {
"sounds" : {
"ambient" : ["LOOPWHIRL"],
"ambient" : ["LOOPWHIR"],
"visit" : ["DANGER"]
}
},

View File

@ -32,7 +32,11 @@
},
"animation": {
"type": "string",
"description": "Image resource"
"description": "Image resource",
"anyOf" : [
{ "format" : "defFile" },
{ "format" : "imageFile" }
]
},
"unknown": {
"type": "number",

View File

@ -380,6 +380,9 @@ bool CGarrisonDialogQuery::blocksPack(const CPack * pack) const
if(auto upgrade = dynamic_ptr_cast<UpgradeCreature>(pack))
return !vstd::contains(ourIds, upgrade->id);
if(auto formation = dynamic_ptr_cast<SetFormation>(pack))
return !vstd::contains(ourIds, formation->hid);
return CDialogQuery::blocksPack(pack);
}