1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-15 11:46:56 +02:00

Merge pull request #2327 from IvanSavenko/bugfixing_from_stream

Fix accumulated minor bugs
This commit is contained in:
Ivan Savenko 2023-07-15 21:55:19 +03:00 committed by GitHub
commit a4ba5a9b65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 383 additions and 162 deletions

View File

@ -443,7 +443,8 @@ void playIntro()
{
if(CCS->videoh->openAndPlayVideo("3DOLOGO.SMK", 0, 1, true, true))
{
CCS->videoh->openAndPlayVideo("AZVS.SMK", 0, 1, true, true);
if (CCS->videoh->openAndPlayVideo("NWCLOGO.SMK", 0, 1, true, true))
CCS->videoh->openAndPlayVideo("H3INTRO.SMK", 0, 1, true, true);
}
}

View File

@ -398,7 +398,10 @@ void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
EVENT_HANDLER_CALLED_BY_CLIENT;
LOG_TRACE_PARAMS(logGlobal, "Hero %s killed handler for player %s", hero->getNameTranslated() % playerID);
localState->removeWanderingHero(hero);
// if hero is not in town garrison
if (vstd::contains(localState->getWanderingHeroes(), hero))
localState->removeWanderingHero(hero);
adventureInt->onHeroChanged(hero);
localState->erasePath(hero);
}
@ -500,7 +503,7 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
if(town->garrisonHero) //wandering hero moved to the garrison
{
// This method also gets called on hero recruitment -> garrisoned hero is already in garrison
if(town->garrisonHero->tempOwner == playerID && !vstd::contains(localState->getWanderingHeroes(), town->visitingHero))
if(town->garrisonHero->tempOwner == playerID && vstd::contains(localState->getWanderingHeroes(), town->garrisonHero))
localState->removeWanderingHero(town->garrisonHero);
}
@ -520,7 +523,9 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
castleInt->garr->setArmy(town->visitingHero, 1);
castleInt->garr->recreateSlots();
castleInt->heroes->update();
castleInt->redraw();
// Perform totalRedraw to update hero list on adventure map
GH.windows().totalRedraw();
}
for (auto ki : GH.windows().findWindows<CKingdomInterface>())
@ -587,9 +592,11 @@ void CPlayerInterface::garrisonsChanged(std::vector<const CGObjectInstance *> ob
void CPlayerInterface::buildChanged(const CGTownInstance *town, BuildingID buildingID, int what) //what: 1 - built, 2 - demolished
{
EVENT_HANDLER_CALLED_BY_CLIENT;
adventureInt->onTownChanged(town);
if (castleInt)
{
castleInt->townlist->update(town);
castleInt->townlist->updateElement(town);
if (castleInt->town == town)
{
@ -604,8 +611,10 @@ void CPlayerInterface::buildChanged(const CGTownInstance *town, BuildingID build
break;
}
}
// Perform totalRedraw in order to force redraw of updated town list icon from adventure map
GH.windows().totalRedraw();
}
adventureInt->onTownChanged(town);
}
void CPlayerInterface::battleStartBefore(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2)
@ -1473,6 +1482,13 @@ void CPlayerInterface::objectRemovedAfter()
{
EVENT_HANDLER_CALLED_BY_CLIENT;
adventureInt->onMapTilesChanged(boost::none);
// visiting or garrisoned hero removed - recreate castle window
if (castleInt)
openTownWindow(castleInt->town);
for (auto ki : GH.windows().findWindows<CKingdomInterface>())
ki->heroRemoved();
}
void CPlayerInterface::playerBlocked(int reason, bool start)
@ -1971,8 +1987,17 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
int soundChannel = -1;
std::string soundName;
auto getMovementSoundFor = [&](const CGHeroInstance * hero, int3 posPrev, int3 posNext) -> std::string
auto getMovementSoundFor = [&](const CGHeroInstance * hero, int3 posPrev, int3 posNext, EPathNodeAction moveType) -> std::string
{
if (moveType == EPathNodeAction::TELEPORT_BATTLE || moveType == EPathNodeAction::TELEPORT_BLOCKING_VISIT || moveType == EPathNodeAction::TELEPORT_NORMAL)
return "";
if (moveType == EPathNodeAction::EMBARK || moveType == EPathNodeAction::DISEMBARK)
return "";
if (moveType == EPathNodeAction::BLOCKING_VISIT)
return "";
// flying movement sound
if (hero->hasBonusOfType(BonusType::FLYING_MOVEMENT))
return "HORSE10.wav";
@ -2024,8 +2049,11 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
}
if(i != path.nodes.size() - 1)
{
soundName = getMovementSoundFor(h, prevCoord, nextCoord);
soundChannel = CCS->soundh->playSound(soundName, -1);
soundName = getMovementSoundFor(h, prevCoord, nextCoord, path.nodes[i-1].action);
if (!soundName.empty())
soundChannel = CCS->soundh->playSound(soundName, -1);
else
soundChannel = -1;
}
continue;
}
@ -2038,14 +2066,17 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
{
// Start a new sound for the hero movement or let the existing one carry on.
std::string newSoundName = getMovementSoundFor(h, prevCoord, nextCoord);
std::string newSoundName = getMovementSoundFor(h, prevCoord, nextCoord, path.nodes[i-1].action);
if(newSoundName != soundName)
{
soundName = newSoundName;
CCS->soundh->stopSound(soundChannel);
soundChannel = CCS->soundh->playSound(soundName, -1);
if (!soundName.empty())
soundChannel = CCS->soundh->playSound(soundName, -1);
else
soundChannel = -1;
}
}

View File

@ -92,7 +92,7 @@ void AdventureMapInterface::onHeroMovementStarted(const CGHeroInstance * hero)
void AdventureMapInterface::onHeroChanged(const CGHeroInstance *h)
{
widget->getHeroList()->update(h);
widget->getHeroList()->updateElement(h);
if (h && h == LOCPLINT->localState->getCurrentHero() && !widget->getInfoBar()->showingComponents())
widget->getInfoBar()->showSelection();
@ -102,7 +102,7 @@ void AdventureMapInterface::onHeroChanged(const CGHeroInstance *h)
void AdventureMapInterface::onTownChanged(const CGTownInstance * town)
{
widget->getTownList()->update(town);
widget->getTownList()->updateElement(town);
if (town && town == LOCPLINT->localState->getCurrentTown() && !widget->getInfoBar()->showingComponents())
widget->getInfoBar()->showSelection();
@ -365,8 +365,8 @@ void AdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID)
widget->getInfoBar()->showSelection();
}
widget->getHeroList()->update();
widget->getTownList()->update();
widget->getHeroList()->updateWidget();
widget->getTownList()->updateWidget();
const CGHeroInstance * heroToSelect = nullptr;
@ -827,5 +827,8 @@ void AdventureMapInterface::onScreenResize()
widget->getMinimap()->update();
widget->getInfoBar()->showSelection();
if (LOCPLINT && LOCPLINT->localState->getCurrentArmy())
widget->getMapView()->onCenteredObject(LOCPLINT->localState->getCurrentArmy());
adjustActiveness();
}

View File

@ -280,21 +280,15 @@ void CHeroList::select(const CGHeroInstance * hero)
selectIndex(vstd::find_pos(LOCPLINT->localState->getWanderingHeroes(), hero));
}
void CHeroList::update(const CGHeroInstance * hero)
void CHeroList::updateElement(const CGHeroInstance * hero)
{
//this hero is already present, update its status
for(auto & elem : listBox->getItems())
{
auto item = std::dynamic_pointer_cast<CHeroItem>(elem);
if(item && item->hero == hero && vstd::contains(LOCPLINT->localState->getWanderingHeroes(), hero))
{
item->update();
return;
}
}
//simplest solution for now: reset list and restore selection
updateWidget();
}
void CHeroList::updateWidget()
{
listBox->resize(LOCPLINT->localState->getWanderingHeroes().size());
listBox->reset();
if (LOCPLINT->localState->getCurrentHero())
select(LOCPLINT->localState->getCurrentHero());
@ -363,14 +357,17 @@ void CTownList::select(const CGTownInstance * town)
selectIndex(vstd::find_pos(LOCPLINT->localState->getOwnedTowns(), town));
}
void CTownList::update(const CGTownInstance *)
void CTownList::updateElement(const CGTownInstance * town)
{
//simplest solution for now: reset list and restore selection
updateWidget();
}
void CTownList::updateWidget()
{
listBox->resize(LOCPLINT->localState->getOwnedTowns().size());
listBox->reset();
if (LOCPLINT->localState->getCurrentTown())
select(LOCPLINT->localState->getCurrentTown());
CList::update();
}

View File

@ -77,6 +77,9 @@ protected:
virtual std::shared_ptr<CIntObject> createItem(size_t index) = 0;
/// should be called when list is invalidated
void update();
public:
/// functions that will be called when selection changes
CFunctionList<void()> onSelect;
@ -87,8 +90,6 @@ public:
void setScrollUpButton(std::shared_ptr<CButton> button);
void setScrollDownButton(std::shared_ptr<CButton> button);
/// should be called when list is invalidated
void update();
/// set of methods to switch selection
void selectIndex(int which);
@ -137,7 +138,10 @@ public:
void select(const CGHeroInstance * hero = nullptr);
/// Update hero. Will add or remove it from the list if needed
void update(const CGHeroInstance * hero = nullptr);
void updateElement(const CGHeroInstance * hero);
/// Update all heroes
void updateWidget();
};
/// List of towns which is shown at the right of the adventure map screen or in the town screen
@ -167,6 +171,9 @@ public:
void select(const CGTownInstance * town = nullptr);
/// Update town. Will add or remove it from the list if needed
void update(const CGTownInstance * town = nullptr);
void updateElement(const CGTownInstance * town);
/// Update all towns
void updateWidget();
};

View File

@ -305,6 +305,7 @@ CKeyShortcut::CKeyShortcut()
CKeyShortcut::CKeyShortcut(EShortcut key)
: assignedKey(key)
, shortcutPressed(false)
{
}

View File

@ -37,4 +37,7 @@ public:
/// Converts provided rect from logical coordinates into coordinates within window, accounting for scaling and viewport
virtual Rect convertLogicalPointsToWindow(const Rect & input) const = 0;
/// Dimensions of render output
virtual Point getRenderResolution() const = 0;
};

View File

@ -46,7 +46,7 @@ std::tuple<int, int> ScreenHandler::getSupportedScalingRange() const
// arbitrary limit on *downscaling*. Allow some downscaling, if requested by user. Should be generally limited to 100+ for all but few devices
static const double minimalScaling = 50;
Point renderResolution = getActualRenderResolution();
Point renderResolution = getRenderResolution();
double reservedAreaWidth = settings["video"]["reservedWidth"].Float();
Point availableResolution = Point(renderResolution.x * (1 - reservedAreaWidth), renderResolution.y);
@ -85,7 +85,7 @@ Rect ScreenHandler::convertLogicalPointsToWindow(const Rect & input) const
Point ScreenHandler::getPreferredLogicalResolution() const
{
Point renderResolution = getActualRenderResolution();
Point renderResolution = getRenderResolution();
double reservedAreaWidth = settings["video"]["reservedWidth"].Float();
Point availableResolution = Point(renderResolution.x * (1 - reservedAreaWidth), renderResolution.y);
@ -99,7 +99,7 @@ Point ScreenHandler::getPreferredLogicalResolution() const
return logicalResolution;
}
Point ScreenHandler::getActualRenderResolution() const
Point ScreenHandler::getRenderResolution() const
{
assert(mainRenderer != nullptr);

View File

@ -39,9 +39,6 @@ class ScreenHandler final : public IScreenHandler
/// This value is what player views as window size
Point getPreferredWindowResolution() const;
/// Dimensions of render output, usually same as window size except for high-DPI screens on macOS / iOS
Point getActualRenderResolution() const;
EWindowMode getPreferredWindowMode() const;
/// Returns index of display on which window should be created
@ -86,6 +83,9 @@ public:
/// Fills screen with black color, erasing any existing content
void clearScreen() final;
/// Dimensions of render output, usually same as window size except for high-DPI screens on macOS / iOS
Point getRenderResolution() const final;
std::vector<Point> getSupportedResolutions() const final;
std::vector<Point> getSupportedResolutions(int displayIndex) const;
std::tuple<int, int> getSupportedScalingRange() const final;

View File

@ -319,9 +319,6 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
noDismiss = true;
}
for(auto ki : GH.windows().findWindows<CKingdomInterface>())
noDismiss = true;
//if player only have one hero and no towns
if(!LOCPLINT->cb->howManyTowns() && LOCPLINT->cb->howManyHeroes() == 1)
noDismiss = true;
@ -329,7 +326,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
if(curHero->isMissionCritical())
noDismiss = true;
dismissButton->block(!!curHero->visitedTown || noDismiss);
dismissButton->block(noDismiss);
if(curHero->valOfBonuses(Selector::type()(BonusType::BEFORE_BATTLE_REPOSITION)) == 0)
{

View File

@ -15,6 +15,7 @@
#include "../CGameInfo.h"
#include "../CPlayerInterface.h"
#include "../PlayerLocalState.h"
#include "../adventureMap/CResDataBar.h"
#include "../gui/CGuiHandler.h"
#include "../gui/Shortcut.h"
@ -638,6 +639,11 @@ void CKingdomInterface::townChanged(const CGTownInstance *town)
townList->townChanged(town);
}
void CKingdomInterface::heroRemoved()
{
tabArea->reset();
}
void CKingdomInterface::updateGarrisons()
{
if(auto garrison = std::dynamic_pointer_cast<CGarrisonHolder>(tabArea->getItem()))
@ -694,11 +700,12 @@ void CKingdHeroList::updateGarrisons()
std::shared_ptr<CIntObject> CKingdHeroList::createHeroItem(size_t index)
{
ui32 picCount = 4; // OVSLOT contains 4 images
size_t heroesCount = LOCPLINT->cb->howManyHeroes(false);
if(index < heroesCount)
auto heroesList = LOCPLINT->localState->getWanderingHeroes();
if(index < heroesList.size())
{
auto hero = std::make_shared<CHeroItem>(LOCPLINT->cb->getHeroBySerial((int)index, false));
auto hero = std::make_shared<CHeroItem>(heroesList[index]);
addSet(hero->heroArts);
return hero;
}
@ -745,10 +752,11 @@ void CKingdTownList::updateGarrisons()
std::shared_ptr<CIntObject> CKingdTownList::createTownItem(size_t index)
{
ui32 picCount = 4; // OVSLOT contains 4 images
size_t townsCount = LOCPLINT->cb->howManyTowns();
if(index < townsCount)
return std::make_shared<CTownItem>(LOCPLINT->cb->getTownBySerial((int)index));
auto townsList = LOCPLINT->localState->getOwnedTowns();
if(index < townsList.size())
return std::make_shared<CTownItem>(townsList[index]);
else
return std::make_shared<CAnimImage>("OVSLOT", (index-2) % picCount );
}

View File

@ -246,6 +246,7 @@ public:
CKingdomInterface();
void townChanged(const CGTownInstance *town);
void heroRemoved();
void updateGarrisons() override;
void artifactRemoved(const ArtifactLocation &artLoc) override;
void artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc, bool withRedraw) override;

View File

@ -158,23 +158,33 @@ void CRecruitmentWindow::select(std::shared_ptr<CCreatureCard> card)
void CRecruitmentWindow::buy()
{
CreatureID crid = selected->creature->getId();
SlotID dstslot = dst-> getSlotFor(crid);
SlotID dstslot = dst->getSlotFor(crid);
if(!dstslot.validSlot() && (selected->creature->warMachine == ArtifactID::NONE)) //no available slot
{
std::string txt;
if(dst->ID == Obj::HERO)
std::pair<SlotID, SlotID> toMerge;
bool allowMerge = CGI->settings()->getBoolean(EGameSettings::DWELLINGS_ACCUMULATE_WHEN_OWNED);
if (allowMerge && dst->mergableStacks(toMerge))
{
txt = CGI->generaltexth->allTexts[425]; //The %s would join your hero, but there aren't enough provisions to support them.
boost::algorithm::replace_first(txt, "%s", slider->getValue() > 1 ? CGI->creh->objects[crid]->getNamePluralTranslated() : CGI->creh->objects[crid]->getNameSingularTranslated());
LOCPLINT->cb->mergeStacks( dst, dst, toMerge.first, toMerge.second);
}
else
{
txt = CGI->generaltexth->allTexts[17]; //There is no room in the garrison for this army.
}
std::string txt;
if(dst->ID == Obj::HERO)
{
txt = CGI->generaltexth->allTexts[425]; //The %s would join your hero, but there aren't enough provisions to support them.
boost::algorithm::replace_first(txt, "%s", slider->getValue() > 1 ? CGI->creh->objects[crid]->getNamePluralTranslated() : CGI->creh->objects[crid]->getNameSingularTranslated());
}
else
{
txt = CGI->generaltexth->allTexts[17]; //There is no room in the garrison for this army.
}
LOCPLINT->showInfoDialog(txt);
return;
LOCPLINT->showInfoDialog(txt);
return;
}
}
onRecruit(crid, slider->getValue());

View File

@ -224,25 +224,19 @@ void GeneralOptionsTab::updateResolutionSelector()
std::shared_ptr<CButton> resolutionButton = widget<CButton>("resolutionButton");
std::shared_ptr<CLabel> resolutionLabel = widget<CLabel>("resolutionLabel");
if (settings["video"]["fullscreen"].Bool() && !settings["video"]["realFullscreen"].Bool())
if (resolutionButton)
{
if (resolutionButton)
if (settings["video"]["fullscreen"].Bool() && !settings["video"]["realFullscreen"].Bool())
resolutionButton->disable();
if (resolutionLabel)
resolutionLabel->setText(resolutionToLabelString(GH.screenDimensions().x, GH.screenDimensions().y));
}
else
{
const auto & currentResolution = settings["video"]["resolution"];
if (resolutionButton)
else
resolutionButton->enable();
if (resolutionLabel)
resolutionLabel->setText(resolutionToLabelString(currentResolution["width"].Integer(), currentResolution["height"].Integer()));
}
if (resolutionLabel)
{
Point resolution = GH.screenHandler().getRenderResolution();
resolutionLabel->setText(resolutionToLabelString(resolution.x, resolution.y));
}
}
void GeneralOptionsTab::selectGameResolution()
@ -370,6 +364,11 @@ void GeneralOptionsTab::setGameScaling(int index)
gameRes["scaling"].Float() = scaling;
widget<CLabel>("scalingLabel")->setText(scalingToLabelString(scaling));
GH.dispatchMainThread([](){
boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim);
GH.onScreenResize();
});
}
void GeneralOptionsTab::selectLongTouchDuration()

View File

@ -4,12 +4,12 @@
{
"name" : "attackerLoose", // loose formation, attacker
"levels": [
[ 86 ],
[ 35, 137 ],
[ 35, 86, 137 ],
[ 1, 69, 103, 171 ],
[ 1, 35, 86, 137, 171 ],
[ 1, 35, 69, 103, 137, 171 ],
[ 86 ],
[ 35, 137 ],
[ 35, 86, 137 ],
[ 1, 69, 103, 171 ],
[ 1, 35, 86, 137, 171 ],
[ 1, 35, 69, 103, 137, 171 ],
[ 1, 35, 69, 86, 103, 137, 171 ]
]
},
@ -17,12 +17,12 @@
{
"name" : "defenderLoose", // loose formation, defender
"levels": [
[ 100 ],
[ 49, 151 ],
[ 49, 100, 151 ],
[ 15, 83, 117, 185 ],
[ 15, 49, 100, 151, 185 ],
[ 15, 49, 83, 117, 151, 185 ],
[ 100 ],
[ 49, 151 ],
[ 49, 100, 151 ],
[ 15, 83, 117, 185 ],
[ 15, 49, 100, 151, 185 ],
[ 15, 49, 83, 117, 151, 185 ],
[ 15, 49, 83, 100, 117, 151, 185 ]
]
},
@ -30,26 +30,26 @@
{
"name" : "attackerTight", // tight formation, attacker
"levels": [
[ 86 ],
[ 69, 103 ],
[ 69, 86, 103 ],
[ 52, 69, 103, 120 ],
[ 52, 69, 86, 103, 120 ],
[ 35, 52, 69, 103, 120, 137 ],
[ 35, 52, 69, 86, 103, 120, 137 ]
[ 86 ],
[ 69, 103 ],
[ 69, 86, 103 ],
[ 35, 69, 103, 137 ],
[ 35, 69, 86, 103, 137 ],
[ 1, 35, 69, 103, 137, 171 ],
[ 1, 35, 69, 86, 103, 137, 171 ]
]
},
{
"name" : "defenderTight", // tight formation, defender
"levels": [
[ 100 ],
[ 83, 117 ],
[ 83, 100, 117 ],
[ 66, 83, 117, 134 ],
[ 66, 83, 100, 117, 134 ],
[ 49, 66, 83, 117, 134, 151 ],
[ 49, 66, 83, 100, 117, 134, 151 ]
[ 100 ],
[ 83, 117 ],
[ 83, 100, 117 ],
[ 49, 83, 117, 151 ],
[ 49, 83, 100, 117, 151 ],
[ 15, 49, 83, 117, 151, 185 ],
[ 15, 49, 83, 100, 117, 151, 185 ]
]
},

View File

@ -9,25 +9,25 @@
{
"DATA/" :
[
{"type" : "lod", "path" : "Data/H3ab_bmp.lod"},
{"type" : "lod", "path" : "Data/H3bitmap.lod"},
{"type" : "lod", "path" : "Data/h3abp_bm.lod"}, // Polish version of H3 only
{"type" : "lod", "path" : "Data/H3pbitma.lod"}, // Polish version of H3 only
{"type" : "lod", "path" : "Data/H3ab_bmp.lod"}, // Contains H3:AB data
{"type" : "lod", "path" : "Data/h3abp_bm.lod"}, // Localized versions only, contains H3:AB patch data
{"type" : "lod", "path" : "Data/H3bitmap.lod"}, // Contains H3:SoD data (overrides H3:AB data)
{"type" : "lod", "path" : "Data/H3pbitma.lod"}, // Localized versions only, contains H3:SoD patch data
{"type" : "dir", "path" : "Data"}
],
"SPRITES/":
[
{"type" : "lod", "path" : "Data/H3ab_spr.lod"},
{"type" : "lod", "path" : "Data/H3sprite.lod"},
{"type" : "lod", "path" : "Data/h3abp_sp.lod"}, // Polish version of H3 only
{"type" : "lod", "path" : "Data/H3psprit.lod"}, // Polish version of H3 only
{"type" : "lod", "path" : "Data/H3ab_spr.lod"}, // Contains H3:AB data
{"type" : "lod", "path" : "Data/H3sprite.lod"}, // Localized versions only, contains H3:AB patch data
{"type" : "lod", "path" : "Data/h3abp_sp.lod"}, // Contains H3:SoD data (overrides H3:AB data)
// {"type" : "lod", "path" : "Data/H3psprit.lod"}, // Localized versions only, contains H3:SoD patch data. Unused? Has corrupted data, e.g. lock icon for artifacts
{"type" : "dir", "path" : "Sprites"}
],
"SOUNDS/":
[
{"type" : "snd", "path" : "Data/H3ab_ahd.snd"},
{"type" : "snd", "path" : "Data/Heroes3-cd2.snd"},
{"type" : "snd", "path" : "Data/Heroes3.snd"},
{"type" : "snd", "path" : "Data/Heroes3-cd2.snd"},
//WoG have overriden sounds with .82m extension in Data
{"type" : "dir", "path" : "Data", "depth": 0}
],

View File

@ -311,6 +311,8 @@
"accumulateWhenNeutral" : false,
// if enabled, dwellings owned by players will accumulate creatures
"accumulateWhenOwned" : false
// if enabled, game will attempt to merge slots in army on recruit if all slots in hero army are in use
"mergeOnRecruit" : true
},
"markets" :

View File

@ -59,12 +59,12 @@
},
"language" : {
"type" : "string",
"enum" : [ "english", "czech", "chinese", "german", "hungarian", "italian", "korean", "polish", "russian", "spanish", "ukrainian" ],
"enum" : [ "english", "czech", "chinese", "french", "german", "hungarian", "italian", "korean", "polish", "russian", "spanish", "ukrainian" ],
"default" : "english"
},
"gameDataLanguage" : {
"type" : "string",
"enum" : [ "auto", "english", "czech", "chinese", "german", "hungarian", "italian", "korean", "polish", "russian", "spanish", "ukrainian", "other_cp1250", "other_cp1251", "other_cp1252" ],
"enum" : [ "auto", "english", "czech", "chinese", "french", "german", "hungarian", "italian", "korean", "polish", "russian", "spanish", "ukrainian", "other_cp1250", "other_cp1251", "other_cp1252" ],
"default" : "auto"
},
"lastSave" : {

View File

@ -245,7 +245,7 @@
]
},
{
"index": 12,
"index": 9,
"type": "toggleButton",
"image": "settingsWindow/button46",
"help": "vcmi.battleOptions.animationsSpeed5",
@ -261,7 +261,7 @@
]
},
{
"index": 24,
"index": 18,
"type": "toggleButton",
"image": "settingsWindow/button46",
"help": "vcmi.battleOptions.animationsSpeed6",

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>745</width>
<height>389</height>
<height>397</height>
</rect>
</property>
<property name="windowTitle">
@ -96,7 +96,7 @@
<item>
<widget class="QStackedWidget" name="installerTabs">
<property name="currentIndex">
<number>0</number>
<number>2</number>
</property>
<widget class="QWidget" name="pageLanguageSelect">
<layout class="QGridLayout" name="gridLayout_3">
@ -616,7 +616,7 @@ Heroes® of Might and Magic® III HD is currently not supported!</string>
<string>Horn of the Abyss</string>
</property>
<property name="wordWrap">
<bool>true</bool>
<bool>false</bool>
</property>
</widget>
</item>
@ -638,7 +638,7 @@ Heroes® of Might and Magic® III HD is currently not supported!</string>
<string>Heroes III Translation</string>
</property>
<property name="wordWrap">
<bool>true</bool>
<bool>false</bool>
</property>
</widget>
</item>
@ -699,10 +699,10 @@ Heroes® of Might and Magic® III HD is currently not supported!</string>
</font>
</property>
<property name="text">
<string>High Definition Support</string>
<string>Interface Improvements</string>
</property>
<property name="wordWrap">
<bool>true</bool>
<bool>false</bool>
</property>
</widget>
</item>
@ -724,7 +724,7 @@ Heroes® of Might and Magic® III HD is currently not supported!</string>
<string>In The Wake of Gods</string>
</property>
<property name="wordWrap">
<bool>true</bool>
<bool>false</bool>
</property>
</widget>
</item>
@ -769,7 +769,7 @@ Heroes® of Might and Magic® III HD is currently not supported!</string>
</sizepolicy>
</property>
<property name="text">
<string>Install support for playing Heroes III in resolutions higher than 800x600</string>
<string>Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles</string>
</property>
<property name="wordWrap">
<bool>true</bool>

View File

@ -153,6 +153,7 @@ void MainWindow::enterSetup()
ui->startEditorButton->setEnabled(false);
ui->lobbyButton->setEnabled(false);
ui->settingsButton->setEnabled(false);
ui->aboutButton->setEnabled(false);
ui->modslistButton->setEnabled(false);
ui->tabListWidget->setCurrentIndex(TabRows::SETUP);
}
@ -166,6 +167,7 @@ void MainWindow::exitSetup()
ui->startEditorButton->setEnabled(true);
ui->lobbyButton->setEnabled(true);
ui->settingsButton->setEnabled(true);
ui->aboutButton->setEnabled(true);
ui->modslistButton->setEnabled(true);
ui->tabListWidget->setCurrentIndex(TabRows::MODS);
}

View File

@ -273,12 +273,6 @@ void CSettingsView::on_comboBoxDisplayIndex_currentIndexChanged(int index)
fillValidResolutionsForScreen(index);
}
void CSettingsView::on_comboBoxPlayerAI_currentTextChanged(const QString & arg1)
{
Settings node = settings.write["server"]["playerAI"];
node->String() = arg1.toUtf8().data();
}
void CSettingsView::on_comboBoxFriendlyAI_currentTextChanged(const QString & arg1)
{
Settings node = settings.write["server"]["friendlyAI"];
@ -493,3 +487,16 @@ void CSettingsView::on_spinBoxFramerateLimit_valueChanged(int arg1)
node->Float() = arg1;
}
void CSettingsView::on_comboBoxEnemyPlayerAI_currentTextChanged(const QString &arg1)
{
Settings node = settings.write["server"]["playerAI"];
node->String() = arg1.toUtf8().data();
}
void CSettingsView::on_comboBoxAlliedPlayerAI_currentTextChanged(const QString &arg1)
{
Settings node = settings.write["server"]["alliedAI"];
node->String() = arg1.toUtf8().data();
}

View File

@ -35,7 +35,6 @@ public slots:
private slots:
void on_comboBoxResolution_currentTextChanged(const QString & arg1);
void on_comboBoxFullScreen_currentIndexChanged(int index);
void on_comboBoxPlayerAI_currentTextChanged(const QString & arg1);
void on_comboBoxFriendlyAI_currentTextChanged(const QString & arg1);
void on_comboBoxNeutralAI_currentTextChanged(const QString & arg1);
void on_comboBoxEnemyAI_currentTextChanged(const QString & arg1);
@ -63,6 +62,10 @@ private slots:
void on_spinBoxFramerateLimit_valueChanged(int arg1);
void on_comboBoxEnemyPlayerAI_currentTextChanged(const QString &arg1);
void on_comboBoxAlliedPlayerAI_currentTextChanged(const QString &arg1);
private:
Ui::CSettingsView * ui;

View File

@ -710,6 +710,11 @@ Heroes® of Might and Magic® III HD is currently not supported!</source>
<source>The automatic detection of the Heroes III language has failed. Please select the language of your Heroes III manually</source>
<translation>33</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>Interface Improvements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="740"/>
<source>Install a translation of Heroes III in your preferred language</source>
@ -722,8 +727,12 @@ Heroes® of Might and Magic® III HD is currently not supported!</source>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="772"/>
<source>Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Install support for playing Heroes III in resolutions higher than 800x600</source>
<translation>3800x600以上分辨率支持</translation>
<translation type="vanished">3800x600以上分辨率支持</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="788"/>
@ -813,9 +822,8 @@ Heroes® of Might and Magic® III HD is currently not supported!</source>
<translation>3</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>High Definition Support</source>
<translation></translation>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="724"/>

View File

@ -678,6 +678,11 @@ Heroes® of Might and Magic® III HD is currently not supported!</source>
<source>The automatic detection of the Heroes III language has failed. Please select the language of your Heroes III manually</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>Interface Improvements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="740"/>
<source>Install a translation of Heroes III in your preferred language</source>
@ -690,7 +695,7 @@ Heroes® of Might and Magic® III HD is currently not supported!</source>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="772"/>
<source>Install support for playing Heroes III in resolutions higher than 800x600</source>
<source>Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles</source>
<translation type="unfinished"></translation>
</message>
<message>
@ -780,11 +785,6 @@ Heroes® of Might and Magic® III HD is currently not supported!</source>
<source>Heroes III Translation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>High Definition Support</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="724"/>
<source>In The Wake of Gods</source>

View File

@ -257,7 +257,7 @@
<translation>Impressions écran</translation>
</message>
<message>
<location filename="../modManager/cmodlistview_moc.ui" line="323"/>
<location filename="../modManager/cmodlistview_moc.ui" line="324"/>
<source> %p% (%v KB out of %m KB)</source>
<translation> %p% (%v Ko sur %m Ko)</translation>
</message>
@ -780,9 +780,8 @@ Mode exclusif plein écran - le jeu couvrira l&quot;intégralité de votre écra
</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="772"/>
<source>Install support for playing Heroes III in resolutions higher than 800x600</source>
<translation>Installer un support pour jouer à Heroes III avec des résolutions supérieures à 800x600
<translation type="vanished">Installer un support pour jouer à Heroes III avec des résolutions supérieures à 800x600
</translation>
</message>
<message>
@ -860,7 +859,7 @@ Heroes® of Might and Magic® III HD n&quot;est actuellement pas pris en charge
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="346"/>
<source>If you don&apos;t have a copy of Heroes III installed, you can use our automatic installation tool &apos;vcmibuilder&apos;, which only requires the GoG.com Heroes III installer. Please visit our wiki for detailed instructions.</source>
<translation>Si vous n&quot;avez pas installé de copie de Heroes III, vous pouvez utiliser notre outil d&quot;installation automatique "vcmibuilder", qui ne nécessite que le programme d&quot;installation de GoG.com Heroes III. Veuillez visiter notre wiki pour des instructions détaillées.</translation>
<translation>Si vous n&quot;avez pas installé de copie de Heroes III, vous pouvez utiliser notre outil d&quot;installation automatique &quot;vcmibuilder&quot;, qui ne nécessite que le programme d&quot;installation de GoG.com Heroes III. Veuillez visiter notre wiki pour des instructions détaillées.</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="362"/>
@ -920,8 +919,12 @@ Heroes® of Might and Magic® III HD n&quot;est actuellement pas pris en charge
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>Interface Improvements</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>High Definition Support</source>
<translation>Support de Haute Définition</translation>
<translation type="vanished">Support de Haute Définition</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="724"/>
@ -933,6 +936,11 @@ Heroes® of Might and Magic® III HD n&quot;est actuellement pas pris en charge
<source>Optionally, you can install additional mods either now, or at any point later, using the VCMI Launcher</source>
<translation>En option, vous pouvez installer des mods supplémentaires soit maintenant, soit à tout moment plus tard, à l&quot;aide du lanceur VCMI</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="772"/>
<source>Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="788"/>
<source>Install compatible version of &quot;Horn of the Abyss&quot;, a fan-made Heroes III expansion ported by the VCMI team</source>

View File

@ -714,6 +714,11 @@ Heroes III: HD Edition wird derzeit nicht unterstützt</translation>
<source>The automatic detection of the Heroes III language has failed. Please select the language of your Heroes III manually</source>
<translation>Automatische Erkennung der Sprache fehlgeschlagen. Bitte wählen Sie die Sprache Ihrer Heroes III Kopie</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>Interface Improvements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="740"/>
<source>Install a translation of Heroes III in your preferred language</source>
@ -726,8 +731,12 @@ Heroes III: HD Edition wird derzeit nicht unterstützt</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="772"/>
<source>Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Install support for playing Heroes III in resolutions higher than 800x600</source>
<translation>Installieren Sie Unterstützung für das Spielen von Heroes III in anderen Auflösungen als 800x600</translation>
<translation type="vanished">Installieren Sie Unterstützung für das Spielen von Heroes III in anderen Auflösungen als 800x600</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="788"/>
@ -817,9 +826,8 @@ Heroes III: HD Edition wird derzeit nicht unterstützt</translation>
<translation>Heroes III Übersetzung</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>High Definition Support</source>
<translation>Unterstützung für hohe Auflösungen</translation>
<translation type="vanished">Unterstützung für hohe Auflösungen</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="724"/>

View File

@ -714,6 +714,11 @@ Heroes III: HD Edition nie jest obecnie wspierane!</translation>
<source>The automatic detection of the Heroes III language has failed. Please select the language of your Heroes III manually</source>
<translation>Automatyczna detekcja języka nie powiodła się. Proszę wybrać język twojego Heroes III</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>Interface Improvements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="740"/>
<source>Install a translation of Heroes III in your preferred language</source>
@ -726,8 +731,12 @@ Heroes III: HD Edition nie jest obecnie wspierane!</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="772"/>
<source>Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Install support for playing Heroes III in resolutions higher than 800x600</source>
<translation>Zainstaluj wsparcie dla grania w Heroes III w rozdzielczości innej niż 800x600</translation>
<translation type="vanished">Zainstaluj wsparcie dla grania w Heroes III w rozdzielczości innej niż 800x600</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="788"/>
@ -817,9 +826,8 @@ Heroes III: HD Edition nie jest obecnie wspierane!</translation>
<translation>Tłumaczenie Heroes III</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>High Definition Support</source>
<translation>Wsparcie High Definition</translation>
<translation type="vanished">Wsparcie High Definition</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="724"/>

View File

@ -708,6 +708,11 @@ Heroes® of Might and Magic® III HD is currently not supported!</source>
<source>The automatic detection of the Heroes III language has failed. Please select the language of your Heroes III manually</source>
<translation>Язык Героев III не был определен. Пожалуйста, выберите язык вашей копии Героев III</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>Interface Improvements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="740"/>
<source>Install a translation of Heroes III in your preferred language</source>
@ -720,8 +725,12 @@ Heroes® of Might and Magic® III HD is currently not supported!</source>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="772"/>
<source>Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Install support for playing Heroes III in resolutions higher than 800x600</source>
<translation>Установить поддержку запуска Героев III в разрешениях, отличных от 800x600</translation>
<translation type="vanished">Установить поддержку запуска Героев III в разрешениях, отличных от 800x600</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="788"/>
@ -811,9 +820,8 @@ Heroes® of Might and Magic® III HD is currently not supported!</source>
<translation>Перевод Героев III</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>High Definition Support</source>
<translation>Поддержка высоких разрешений</translation>
<translation type="vanished">Поддержка высоких разрешений</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="724"/>

View File

@ -702,6 +702,16 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
<source>Your Heroes III language has been successfully detected.</source>
<translation>Se ha detectado con éxito el idioma de tu Heroes III.</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>Interface Improvements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="772"/>
<source>Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="127"/>
<source>Select your language</source>
@ -781,9 +791,8 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi
<translation>Traducción de Heroes III.</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>High Definition Support</source>
<translation>Soporte para resoluciones en Alta Definición</translation>
<translation type="vanished">Soporte para resoluciones en Alta Definición</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="724"/>
@ -801,9 +810,8 @@ Ten en cuenta que para usar VCMI debes ser dueño de los archivos de datos origi
<translation>Opcionalmente, puedes instalar mods adicionales ya sea ahora o en cualquier momento posterior, utilizando el lanzador de VCMI.</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="772"/>
<source>Install support for playing Heroes III in resolutions higher than 800x600</source>
<translation>Instalar soporte para jugar Heroes III en resoluciones superiores a 800x600</translation>
<translation type="vanished">Instalar soporte para jugar Heroes III en resoluciones superiores a 800x600</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="788"/>

View File

@ -718,6 +718,11 @@ Heroes® of Might and Magic® III HD наразі не підтримуєтьс
<source>The automatic detection of the Heroes III language has failed. Please select the language of your Heroes III manually</source>
<translation>Не вдалося визначити мову гри. Будь ласка, виберіть мову вашої копії Heroes III</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>Interface Improvements</source>
<translation>Удосконалення нтерфейсу</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="740"/>
<source>Install a translation of Heroes III in your preferred language</source>
@ -730,8 +735,12 @@ Heroes® of Might and Magic® III HD наразі не підтримуєтьс
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="772"/>
<source>Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles</source>
<translation>Встановити різноманітні покращення інтерфейсу, такі як покращений інтерфейс випадкових карт та вибір варіантів дій у боях</translation>
</message>
<message>
<source>Install support for playing Heroes III in resolutions higher than 800x600</source>
<translation>Встановити підтримку для гри в Heroes III у роздільних здатностях, більших за 800x600</translation>
<translation type="vanished">Встановити підтримку для гри в Heroes III у роздільних здатностях, більших за 800x600</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="788"/>
@ -821,9 +830,8 @@ Heroes® of Might and Magic® III HD наразі не підтримуєтьс
<translation>Переклад Heroes III</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="702"/>
<source>High Definition Support</source>
<translation>Підтримка високих роздільних здатностей</translation>
<translation type="vanished">Підтримка високих роздільних здатностей</translation>
</message>
<message>
<location filename="../firstLaunch/firstlaunch_moc.ui" line="724"/>

View File

@ -68,6 +68,7 @@ void GameSettings::load(const JsonNode & input)
{EGameSettings::CREATURES_WEEKLY_GROWTH_PERCENT, "creatures", "weeklyGrowthPercent" },
{EGameSettings::DWELLINGS_ACCUMULATE_WHEN_NEUTRAL, "dwellings", "accumulateWhenNeutral" },
{EGameSettings::DWELLINGS_ACCUMULATE_WHEN_OWNED, "dwellings", "accumulateWhenOwned" },
{EGameSettings::DWELLINGS_MERGE_ON_RECRUIT, "dwellings", "mergeOnRecruit" },
{EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP, "heroes", "perPlayerOnMapCap" },
{EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP, "heroes", "perPlayerTotalCap" },
{EGameSettings::HEROES_RETREAT_ON_WIN_WITHOUT_TROOPS, "heroes", "retreatOnWinWithoutTroops" },

View File

@ -32,6 +32,7 @@ enum class EGameSettings
CREATURES_WEEKLY_GROWTH_PERCENT,
DWELLINGS_ACCUMULATE_WHEN_NEUTRAL,
DWELLINGS_ACCUMULATE_WHEN_OWNED,
DWELLINGS_MERGE_ON_RECRUIT,
HEROES_PER_PLAYER_ON_MAP_CAP,
HEROES_PER_PLAYER_TOTAL_CAP,
HEROES_RETREAT_ON_WIN_WITHOUT_TROOPS,

View File

@ -1124,7 +1124,16 @@ void RemoveObject::applyGs(CGameState *gs)
PlayerState * p = gs->getPlayerState(beatenHero->tempOwner);
gs->map->heroesOnMap -= beatenHero;
p->heroes -= beatenHero;
beatenHero->detachFrom(*beatenHero->whereShouldBeAttachedOnSiege(gs));
auto * siegeNode = beatenHero->whereShouldBeAttachedOnSiege(gs);
// FIXME: workaround:
// hero should be attached to siegeNode after battle
// however this code might also be called on dismissing hero while in town
if (siegeNode && vstd::contains(beatenHero->getParentNodes(), siegeNode))
beatenHero->detachFrom(*siegeNode);
beatenHero->tempOwner = PlayerColor::NEUTRAL; //no one owns beaten hero
vstd::erase_if(beatenHero->artifactsInBackpack, [](const ArtSlotInfo& asi)
{

View File

@ -57,6 +57,8 @@ CObjectClassesHandler::CObjectClassesHandler()
SET_HANDLER_CLASS("shrine", ShrineInstanceConstructor);
SET_HANDLER_CLASS("hillFort", HillFortInstanceConstructor);
SET_HANDLER_CLASS("shipyard", ShipyardInstanceConstructor);
SET_HANDLER_CLASS("monster", CreatureInstanceConstructor);
SET_HANDLER_CLASS("resource", ResourceInstanceConstructor);
SET_HANDLER_CLASS("static", CObstacleConstructor);
SET_HANDLER_CLASS("", CObstacleConstructor);
@ -73,7 +75,6 @@ CObjectClassesHandler::CObjectClassesHandler()
SET_HANDLER("artifact", CGArtifact);
SET_HANDLER("borderGate", CGBorderGate);
SET_HANDLER("borderGuard", CGBorderGuard);
SET_HANDLER("monster", CGCreature);
SET_HANDLER("denOfThieves", CGDenOfthieves);
SET_HANDLER("event", CGEvent);
SET_HANDLER("garrison", CGGarrison);
@ -87,7 +88,6 @@ CObjectClassesHandler::CObjectClassesHandler()
SET_HANDLER("pandora", CGPandoraBox);
SET_HANDLER("prison", CGHeroInstance);
SET_HANDLER("questGuard", CGQuestGuard);
SET_HANDLER("resource", CGResource);
SET_HANDLER("scholar", CGScholar);
SET_HANDLER("seerHut", CGSeerHut);
SET_HANDLER("sign", CGSignBottle);

View File

@ -35,6 +35,26 @@ bool CObstacleConstructor::isStaticObject()
return true;
}
bool CreatureInstanceConstructor::hasNameTextID() const
{
return true;
}
std::string CreatureInstanceConstructor::getNameTextID() const
{
return VLC->creatures()->getByIndex(getSubIndex())->getNamePluralTextID();
}
bool ResourceInstanceConstructor::hasNameTextID() const
{
return true;
}
std::string ResourceInstanceConstructor::getNameTextID() const
{
return TextIdentifier("core", "restypes", getSubIndex()).get();
}
void CTownInstanceConstructor::initTypeData(const JsonNode & input)
{
VLC->modh->identifiers.requestIdentifier("faction", input["faction"], [&](si32 index)
@ -86,6 +106,16 @@ void CTownInstanceConstructor::randomizeObject(CGTownInstance * object, CRandomG
object->appearance = templ;
}
bool CTownInstanceConstructor::hasNameTextID() const
{
return true;
}
std::string CTownInstanceConstructor::getNameTextID() const
{
return faction->getNameTextID();
}
void CHeroInstanceConstructor::initTypeData(const JsonNode & input)
{
VLC->modh->identifiers.requestIdentifier(
@ -133,6 +163,16 @@ void CHeroInstanceConstructor::randomizeObject(CGHeroInstance * object, CRandomG
}
bool CHeroInstanceConstructor::hasNameTextID() const
{
return true;
}
std::string CHeroInstanceConstructor::getNameTextID() const
{
return heroClass->getNameTextID();
}
void BoatInstanceConstructor::initTypeData(const JsonNode & input)
{
layer = EPathfindingLayer::SAIL;

View File

@ -13,6 +13,7 @@
#include "../LogicalExpression.h"
#include "../mapObjects/MiscObjects.h"
#include "../mapObjects/CGCreature.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -22,6 +23,7 @@ class CGTownInstance;
class CGHeroInstance;
class CGMarket;
class CHeroClass;
class CGCreature;
class CBank;
class CGBoat;
class CFaction;
@ -33,6 +35,20 @@ public:
bool isStaticObject() override;
};
class CreatureInstanceConstructor : public CDefaultObjectTypeHandler<CGCreature>
{
public:
bool hasNameTextID() const override;
std::string getNameTextID() const override;
};
class ResourceInstanceConstructor : public CDefaultObjectTypeHandler<CGResource>
{
public:
bool hasNameTextID() const override;
std::string getNameTextID() const override;
};
class CTownInstanceConstructor : public CDefaultObjectTypeHandler<CGTownInstance>
{
JsonNode filtersJson;
@ -48,6 +64,9 @@ public:
void randomizeObject(CGTownInstance * object, CRandomGenerator & rng) const override;
void afterLoadFinalization() override;
bool hasNameTextID() const override;
std::string getNameTextID() const override;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & filtersJson;
@ -72,6 +91,9 @@ public:
void randomizeObject(CGHeroInstance * object, CRandomGenerator & rng) const override;
void afterLoadFinalization() override;
bool hasNameTextID() const override;
std::string getNameTextID() const override;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & filtersJson;

View File

@ -324,6 +324,21 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h) const
{
if(count) //there are available creatures
{
if (VLC->settings()->getBoolean(EGameSettings::DWELLINGS_ACCUMULATE_WHEN_OWNED))
{
SlotID testSlot = h->getSlotFor(crid);
if(!testSlot.validSlot()) //no available slot - try merging army of visiting hero
{
std::pair<SlotID, SlotID> toMerge;
if (h->mergableStacks(toMerge))
{
cb->moveStack(StackLocation(h, toMerge.first), StackLocation(h, toMerge.second), -1); //merge toMerge.first into toMerge.second
assert(!h->hasStackAtSlot(toMerge.first)); //we have now a new free slot
}
}
}
SlotID slot = h->getSlotFor(crid);
if(!slot.validSlot()) //no available slot
{

View File

@ -107,6 +107,8 @@ void registerTypesMapObjectTypes(Serializer &s)
s.template registerType<AObjectTypeHandler, ShrineInstanceConstructor>();
s.template registerType<AObjectTypeHandler, ShipyardInstanceConstructor>();
s.template registerType<AObjectTypeHandler, HillFortInstanceConstructor>();
s.template registerType<AObjectTypeHandler, CreatureInstanceConstructor>();
s.template registerType<AObjectTypeHandler, ResourceInstanceConstructor>();
#define REGISTER_GENERIC_HANDLER(TYPENAME) s.template registerType<AObjectTypeHandler, CDefaultObjectTypeHandler<TYPENAME> >()

View File

@ -541,7 +541,7 @@ void TargetCondition::loadConditions(const JsonNode & source, bool exclusive, bo
CModHandler::parseIdentifier(keyValue.first, scope, type, identifier);
item = itemFactory->createConfigurable(scope, type, identifier);
item = itemFactory->createConfigurable(keyValue.second.meta, type, identifier);
}
if(item)

View File

@ -250,7 +250,10 @@ void Timed::serializeJsonUnitEffect(JsonSerializeFormat & handler)
auto guard = handler.enterStruct(p.first);
const JsonNode & bonusNode = handler.getCurrent();
auto b = JsonUtils::parseBonus(bonusNode);
bonus.push_back(b);
if (b)
bonus.push_back(b);
else
logMod->error("Failed to parse bonus '%s'!", p.first);
}
}
}