mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-13 13:18:43 +02:00
Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
commit
a70f5de8c6
5
.github/workflows/github.yml
vendored
5
.github/workflows/github.yml
vendored
@ -3,7 +3,6 @@ name: VCMI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- features/*
|
||||
- beta
|
||||
- master
|
||||
- develop
|
||||
@ -76,6 +75,7 @@ jobs:
|
||||
os: windows-latest
|
||||
test: 0
|
||||
pack: 1
|
||||
upload: 1
|
||||
pack_type: RelWithDebInfo
|
||||
extension: exe
|
||||
before_install: msvc.sh
|
||||
@ -92,7 +92,6 @@ jobs:
|
||||
os: ubuntu-24.04
|
||||
test: 0
|
||||
pack: 1
|
||||
upload: 1
|
||||
pack_type: Release
|
||||
extension: exe
|
||||
cmake_args: -G Ninja
|
||||
@ -342,7 +341,7 @@ jobs:
|
||||
${{github.workspace}}/**/*.pdb
|
||||
|
||||
- name: Upload build
|
||||
if: ${{ (matrix.upload == 1) && (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta' || github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/features/')) }}
|
||||
if: ${{ (matrix.upload == 1) && (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta' || github.ref == 'refs/heads/master') }}
|
||||
continue-on-error: true
|
||||
run: |
|
||||
if [ -z '${{ env.ANDROID_APK_PATH }}' ] ; then
|
||||
|
@ -1055,7 +1055,7 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance
|
||||
//FIXME: why are the above possible to be null?
|
||||
|
||||
bool emptySlotFound = false;
|
||||
for(auto slot : artifact->artType->getPossibleSlots().at(target->bearerType()))
|
||||
for(auto slot : artifact->getType()->getPossibleSlots().at(target->bearerType()))
|
||||
{
|
||||
if(target->isPositionFree(slot) && artifact->canBePutAt(target, slot, true)) //combined artifacts are not always allowed to move
|
||||
{
|
||||
@ -1068,7 +1068,7 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance
|
||||
}
|
||||
if(!emptySlotFound) //try to put that atifact in already occupied slot
|
||||
{
|
||||
for(auto slot : artifact->artType->getPossibleSlots().at(target->bearerType()))
|
||||
for(auto slot : artifact->getType()->getPossibleSlots().at(target->bearerType()))
|
||||
{
|
||||
auto otherSlot = target->getSlot(slot);
|
||||
if(otherSlot && otherSlot->artifact) //we need to exchange artifact for better one
|
||||
@ -1079,8 +1079,8 @@ void AIGateway::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance
|
||||
{
|
||||
logAi->trace(
|
||||
"Exchange artifacts %s <-> %s",
|
||||
artifact->artType->getNameTranslated(),
|
||||
otherSlot->artifact->artType->getNameTranslated());
|
||||
artifact->getType()->getNameTranslated(),
|
||||
otherSlot->artifact->getType()->getNameTranslated());
|
||||
|
||||
if(!otherSlot->artifact->canBePutAt(artHolder, location.slot, true))
|
||||
{
|
||||
@ -1129,10 +1129,10 @@ void AIGateway::recruitCreatures(const CGDwelling * d, const CArmedInstance * re
|
||||
{
|
||||
for(auto stack : recruiter->Slots())
|
||||
{
|
||||
if(!stack.second->type)
|
||||
if(!stack.second->getType())
|
||||
continue;
|
||||
|
||||
auto duplicatingSlot = recruiter->getSlotFor(stack.second->type);
|
||||
auto duplicatingSlot = recruiter->getSlotFor(stack.second->getCreature());
|
||||
|
||||
if(duplicatingSlot != stack.first)
|
||||
{
|
||||
|
@ -193,7 +193,7 @@ bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater)
|
||||
{
|
||||
// TODO: Such information should be provided by pathfinder
|
||||
// Tile must be free or with unoccupied boat
|
||||
if(!t->blocked)
|
||||
if(!t->blocked())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -267,8 +267,8 @@ bool compareArmyStrength(const CArmedInstance * a1, const CArmedInstance * a2)
|
||||
|
||||
bool compareArtifacts(const CArtifactInstance * a1, const CArtifactInstance * a2)
|
||||
{
|
||||
auto art1 = a1->artType;
|
||||
auto art2 = a2->artType;
|
||||
auto art1 = a1->getType();
|
||||
auto art2 = a2->getType();
|
||||
|
||||
if(art1->getPrice() == art2->getPrice())
|
||||
return art1->valOfBonuses(BonusType::PRIMARY_SKILL) > art2->valOfBonuses(BonusType::PRIMARY_SKILL);
|
||||
@ -312,7 +312,7 @@ int getDuplicatingSlots(const CArmedInstance * army)
|
||||
|
||||
for(auto stack : army->Slots())
|
||||
{
|
||||
if(stack.second->type && army->getSlotFor(stack.second->type) != stack.first)
|
||||
if(stack.second->getCreature() && army->getSlotFor(stack.second->getCreature()) != stack.first)
|
||||
duplicatingSlots++;
|
||||
}
|
||||
|
||||
@ -387,7 +387,7 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject
|
||||
{
|
||||
for(auto slot : h->Slots())
|
||||
{
|
||||
if(slot.second->type->hasUpgrades())
|
||||
if(slot.second->getType()->hasUpgrades())
|
||||
return true; //TODO: check price?
|
||||
}
|
||||
return false;
|
||||
|
@ -90,7 +90,7 @@ std::vector<SlotInfo> ArmyManager::getSortedSlots(const CCreatureSet * target, c
|
||||
{
|
||||
for(auto & i : armyPtr->Slots())
|
||||
{
|
||||
auto cre = dynamic_cast<const CCreature*>(i.second->type);
|
||||
auto cre = dynamic_cast<const CCreature*>(i.second->getType());
|
||||
auto & slotInfp = creToPower[cre];
|
||||
|
||||
slotInfp.creature = cre;
|
||||
|
@ -170,10 +170,10 @@ uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHero
|
||||
for (auto c : creatures)
|
||||
{
|
||||
//Only if hero has slot for this creature in the army
|
||||
auto ccre = dynamic_cast<const CCreature*>(c.data.type);
|
||||
auto ccre = dynamic_cast<const CCreature*>(c.data.getType());
|
||||
if (hero->getSlotFor(ccre).validSlot() || duplicatingSlots > 0)
|
||||
{
|
||||
result += (c.data.type->getAIValue() * c.data.count) * c.chance;
|
||||
result += (c.data.getType()->getAIValue() * c.data.count) * c.chance;
|
||||
}
|
||||
/*else
|
||||
{
|
||||
@ -309,7 +309,7 @@ uint64_t RewardEvaluator::getArmyReward(
|
||||
case Obj::SPELL_SCROLL:
|
||||
//FALL_THROUGH
|
||||
case Obj::ARTIFACT:
|
||||
return evaluateArtifactArmyValue(dynamic_cast<const CGArtifact *>(target)->storedArtifact->artType);
|
||||
return evaluateArtifactArmyValue(dynamic_cast<const CGArtifact *>(target)->storedArtifact->getType());
|
||||
case Obj::HERO:
|
||||
return relations == PlayerRelations::ENEMIES
|
||||
? enemyArmyEliminationRewardRatio * dynamic_cast<const CGHeroInstance *>(target)->getArmyStrength()
|
||||
|
@ -130,10 +130,10 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
|
||||
for(pos.y = 0; pos.y < sizes.y; ++pos.y)
|
||||
{
|
||||
const TerrainTile & tile = gs->map->getTile(pos);
|
||||
if (!tile.terType->isPassable())
|
||||
if (!tile.getTerrain()->isPassable())
|
||||
continue;
|
||||
|
||||
if (tile.terType->isWater())
|
||||
if (tile.isWater())
|
||||
{
|
||||
resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs));
|
||||
if (useFlying)
|
||||
|
@ -186,7 +186,7 @@ bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater)
|
||||
{
|
||||
// TODO: Such information should be provided by pathfinder
|
||||
// Tile must be free or with unoccupied boat
|
||||
if(!t->blocked)
|
||||
if(!t->blocked())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -247,8 +247,8 @@ bool compareArmyStrength(const CArmedInstance * a1, const CArmedInstance * a2)
|
||||
|
||||
bool compareArtifacts(const CArtifactInstance * a1, const CArtifactInstance * a2)
|
||||
{
|
||||
auto art1 = a1->artType;
|
||||
auto art2 = a2->artType;
|
||||
auto art1 = a1->getType();
|
||||
auto art2 = a2->getType();
|
||||
|
||||
if(art1->getPrice() == art2->getPrice())
|
||||
return art1->valOfBonuses(BonusType::PRIMARY_SKILL) > art2->valOfBonuses(BonusType::PRIMARY_SKILL);
|
||||
|
@ -36,7 +36,7 @@ std::vector<SlotInfo> ArmyManager::getSortedSlots(const CCreatureSet * target, c
|
||||
{
|
||||
for(auto & i : armyPtr->Slots())
|
||||
{
|
||||
auto cre = dynamic_cast<const CCreature*>(i.second->type);
|
||||
auto cre = dynamic_cast<const CCreature*>(i.second->getType());
|
||||
auto & slotInfp = creToPower[cre];
|
||||
|
||||
slotInfp.creature = cre;
|
||||
|
@ -162,7 +162,7 @@ TGoalVec CompleteQuest::missionArmy() const
|
||||
|
||||
for(auto creature : q.quest->mission.creatures)
|
||||
{
|
||||
solutions.push_back(sptr(GatherTroops(creature.type->getId(), creature.count)));
|
||||
solutions.push_back(sptr(GatherTroops(creature.getId(), creature.count)));
|
||||
}
|
||||
|
||||
return solutions;
|
||||
|
@ -92,7 +92,7 @@ std::optional<int> MapObjectsEvaluator::getObjectValue(const CGObjectInstance *
|
||||
else if(obj->ID == Obj::ARTIFACT)
|
||||
{
|
||||
auto artifactObject = dynamic_cast<const CGArtifact *>(obj);
|
||||
switch(artifactObject->storedArtifact->artType->aClass)
|
||||
switch(artifactObject->storedArtifact->getType()->aClass)
|
||||
{
|
||||
case CArtifact::EartClass::ART_TREASURE:
|
||||
return 2000;
|
||||
|
@ -46,10 +46,10 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
|
||||
for(pos.y=0; pos.y < sizes.y; ++pos.y)
|
||||
{
|
||||
const TerrainTile & tile = gs->map->getTile(pos);
|
||||
if(!tile.terType->isPassable())
|
||||
if(!tile.getTerrain()->isPassable())
|
||||
continue;
|
||||
|
||||
if(tile.terType->isWater())
|
||||
if(tile.getTerrain()->isWater())
|
||||
{
|
||||
resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs));
|
||||
if(useFlying)
|
||||
|
@ -1180,7 +1180,7 @@ void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * ot
|
||||
//FIXME: why are the above possible to be null?
|
||||
|
||||
bool emptySlotFound = false;
|
||||
for(auto slot : artifact->artType->getPossibleSlots().at(target->bearerType()))
|
||||
for(auto slot : artifact->getType()->getPossibleSlots().at(target->bearerType()))
|
||||
{
|
||||
if(target->isPositionFree(slot) && artifact->canBePutAt(target, slot, true)) //combined artifacts are not always allowed to move
|
||||
{
|
||||
@ -1193,7 +1193,7 @@ void VCAI::pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * ot
|
||||
}
|
||||
if(!emptySlotFound) //try to put that atifact in already occupied slot
|
||||
{
|
||||
for(auto slot : artifact->artType->getPossibleSlots().at(target->bearerType()))
|
||||
for(auto slot : artifact->getType()->getPossibleSlots().at(target->bearerType()))
|
||||
{
|
||||
auto otherSlot = target->getSlot(slot);
|
||||
if(otherSlot && otherSlot->artifact) //we need to exchange artifact for better one
|
||||
@ -2818,7 +2818,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
|
||||
{
|
||||
for(auto slot : h->Slots())
|
||||
{
|
||||
if(slot.second->type->hasUpgrades())
|
||||
if(slot.second->getType()->hasUpgrades())
|
||||
return true; //TODO: check price?
|
||||
}
|
||||
return false;
|
||||
|
@ -28,6 +28,13 @@
|
||||
"vcmi.adventureMap.movementPointsHeroInfo" : "(Body pohybu: %REMAINING / %POINTS)",
|
||||
"vcmi.adventureMap.replayOpponentTurnNotImplemented" : "Omlouváme se, přehrání tahu soupeře ještě není implementováno!",
|
||||
|
||||
"vcmi.bonusSource.artifact" : "Artefakt",
|
||||
"vcmi.bonusSource.creature" : "Schopnost",
|
||||
"vcmi.bonusSource.spell" : "Kouzlo",
|
||||
"vcmi.bonusSource.hero" : "Hrdina",
|
||||
"vcmi.bonusSource.commander" : "Velitel",
|
||||
"vcmi.bonusSource.other" : "Ostatní",
|
||||
|
||||
"vcmi.capitalColors.0" : "Červený",
|
||||
"vcmi.capitalColors.1" : "Modrý",
|
||||
"vcmi.capitalColors.2" : "Hnědý",
|
||||
@ -106,6 +113,12 @@
|
||||
"vcmi.lobby.handicap.resource" : "Dává hráčům odpovídající zdroje navíc k běžným startovním zdrojům. Jsou povoleny záporné hodnoty, ale jsou omezeny na celkovou hodnotu 0 (hráč nikdy nezačíná se zápornými zdroji).",
|
||||
"vcmi.lobby.handicap.income" : "Mění různé příjmy hráče podle procent. Výsledek je zaokrouhlen nahoru.",
|
||||
"vcmi.lobby.handicap.growth" : "Mění rychlost růstu jednotel v městech vlastněných hráčem. Výsledek je zaokrouhlen nahoru.",
|
||||
"vcmi.lobby.deleteUnsupportedSave" : "Nalezeny nepodporované uložené hry (např. z předchozích verzí).\n\nChcete je odstranit?",
|
||||
"vcmi.lobby.deleteSaveGameTitle" : "Vyberte uloženou hru k odstranění",
|
||||
"vcmi.lobby.deleteMapTitle" : "Vyberte scénář k odstranění",
|
||||
"vcmi.lobby.deleteFile" : "Chcete smazat následující soubor?",
|
||||
"vcmi.lobby.deleteFolder" : "Chcete smazat následující složku?",
|
||||
"vcmi.lobby.deleteMode" : "Přepnout do režimu mazání a zpět",
|
||||
|
||||
"vcmi.lobby.login.title" : "Online lobby VCMI",
|
||||
"vcmi.lobby.login.username" : "Uživatelské jméno:",
|
||||
@ -113,7 +126,7 @@
|
||||
"vcmi.lobby.login.error" : "Chyba při připojování: %s",
|
||||
"vcmi.lobby.login.create" : "Nový účet",
|
||||
"vcmi.lobby.login.login" : "Přihlásit se",
|
||||
"vcmi.lobby.login.as" : "Přilásit se jako %s",
|
||||
"vcmi.lobby.login.as" : "Přihlásit se jako %s",
|
||||
"vcmi.lobby.header.rooms" : "Herní místnosti - %d",
|
||||
"vcmi.lobby.header.channels" : "Kanály konverzace",
|
||||
"vcmi.lobby.header.chat.global" : "Globální konverzace hry - %s", // %s -> language name
|
||||
@ -175,6 +188,7 @@
|
||||
"vcmi.server.errors.modsToEnable" : "{Následující modifikace jsou nutné pro načtení hry}",
|
||||
"vcmi.server.errors.modsToDisable" : "{Následující modifikace musí být zakázány}",
|
||||
"vcmi.server.errors.modNoDependency" : "Nelze načíst modifikaci {'%s'}!\n Závisí na modifikaci {'%s'}, která není aktivní!\n",
|
||||
"vcmi.server.errors.modDependencyLoop" : "Nelze načíst modifikaci {'%s'}!\n Modifikace může být součástí (nepřímé) závislostní smyčky.",
|
||||
"vcmi.server.errors.modConflict" : "Nelze načíst modifikaci {'%s'}!\n Je v kolizi s aktivní modifikací {'%s'}!\n",
|
||||
"vcmi.server.errors.unknownEntity" : "Nelze načíst uloženou pozici! Neznámá entita '%s' nalezena v uložené pozici! Uložná pozice nemusí být kompatibilní s aktuálními verzemi modifikací!",
|
||||
|
||||
@ -552,6 +566,8 @@
|
||||
"core.seerhut.quest.reachDate.visit.4" : "Zavřeno do %s.",
|
||||
"core.seerhut.quest.reachDate.visit.5" : "Zavřeno do %s.",
|
||||
|
||||
"mapObject.core.hillFort.object.description" : "Zde můžeš vylepšit jednotky. Vylepšení jednotek úrovně 1 až 4 je zde levnější než v jejich domovském městě.",
|
||||
|
||||
"core.bonus.ADDITIONAL_ATTACK.name": "Dvojitý útok",
|
||||
"core.bonus.ADDITIONAL_ATTACK.description": "Útočí dvakrát",
|
||||
"core.bonus.ADDITIONAL_RETALIATION.name": "Další odvetné útoky",
|
@ -707,6 +707,8 @@
|
||||
"core.bonus.DISINTEGRATE.description": "No corpse remains after death",
|
||||
"core.bonus.INVINCIBLE.name": "Invincible",
|
||||
"core.bonus.INVINCIBLE.description": "Cannot be affected by anything",
|
||||
"core.bonus.MECHANICAL.name": "Mechanical",
|
||||
"core.bonus.MECHANICAL.description": "Immunity to many effects, repairable",
|
||||
"core.bonus.PRISM_HEX_ATTACK_BREATH.name": "Prism Breath",
|
||||
"core.bonus.PRISM_HEX_ATTACK_BREATH.description": "Prism Breath Attack (three directions)"
|
||||
}
|
@ -706,6 +706,9 @@
|
||||
"core.bonus.DISINTEGRATE.description": "Nenhum corpo permanece após a morte",
|
||||
"core.bonus.INVINCIBLE.name": "Invencível",
|
||||
"core.bonus.INVINCIBLE.description": "Não pode ser afetado por nada",
|
||||
"core.bonus.PRISM_HEX_ATTACK_BREATH.name" : "Sopro Prismático",
|
||||
"core.bonus.PRISM_HEX_ATTACK_BREATH.description" : "Ataque de Sopro Prismático (três direções)",
|
||||
"vcmi.server.errors.modDependencyLoop" : "Falha ao carregar o mod {'%s'}!\n Ele pode estar em um ciclo de dependência.",
|
||||
|
||||
"spell.core.castleMoat.name": "Fosso",
|
||||
"spell.core.castleMoatTrigger.name": "Fosso",
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user