1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-13 11:40:38 +02:00

Merge remote-tracking branch 'origin/develop' into biome_system

This commit is contained in:
Tomasz Zieliński 2024-04-08 15:01:17 +02:00
commit d9a598ad9c
16 changed files with 63 additions and 10 deletions

View File

@ -2031,6 +2031,9 @@ void VCAI::tryRealize(Goals::Explore & g)
void VCAI::tryRealize(Goals::RecruitHero & g)
{
if(cb->getResourceAmount(EGameResID::GOLD) < GameConstants::HERO_GOLD_COST)
throw cannotFulfillGoalException("Not enough gold to recruit hero!");
if(const CGTownInstance * t = findTownWithTavern())
{
recruitHero(t, true);

View File

@ -194,6 +194,11 @@ void CPlayerInterface::playerEndsTurn(PlayerColor player)
GH.windows().popWindows(1);
}
if(castleInt)
castleInt->close();
castleInt = nullptr;
// remove all pending dialogs that do not expect query answer
vstd::erase_if(dialogs, [](const std::shared_ptr<CInfoWindow> & window){
return window->ID == QueryID::NONE;

View File

@ -141,7 +141,7 @@ void GlobalLobbyClient::receiveChatHistory(const JsonNode & json)
chatHistory[channelKey].push_back(message);
if(lobbyWindowPtr)
if(lobbyWindowPtr && lobbyWindowPtr->isChannelOpen(channelType, channelName))
lobbyWindowPtr->onGameChatMessage(message.displayName, message.messageText, message.timeFormatted, channelType, channelName);
}
}

View File

@ -38,7 +38,7 @@ GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
MetaString loginAs;
loginAs.appendTextID("vcmi.lobby.login.as");
loginAs.replaceTextID(CSH->getGlobalLobby().getAccountDisplayName());
loginAs.replaceRawString(CSH->getGlobalLobby().getAccountDisplayName());
filledBackground = std::make_shared<FilledTexturePlayerColored>(ImagePath::builtin("DiBoxBck"), Rect(0, 0, pos.w, pos.h));
labelTitle = std::make_shared<CLabel>( pos.w / 2, 20, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.login.title"));
@ -65,6 +65,7 @@ GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
{
buttonLogin->block(true);
toggleMode->setSelected(0);
onLoginModeChanged(0); // call it manually to disable widgets - toggleMode will not emit this call if this is currenly selected option
}
else
toggleMode->setSelected(1);

View File

@ -64,6 +64,7 @@ void GlobalLobbyWindow::doOpenChannel(const std::string & channelType, const std
widget->getGameChatHeader()->setText(text.toString());
// Update currently selected item in UI
// WARNING: this invalidates function parameters since some of them are members of objects that will be destroyed by reset
widget->getAccountList()->reset();
widget->getChannelList()->reset();
widget->getMatchList()->reset();

View File

@ -119,7 +119,7 @@ CBonusSelection::CBonusSelection()
if (!getCampaign()->getMusic().empty())
CCS->musich->playMusic( getCampaign()->getMusic(), true, false);
if(settings["general"]["enableUiEnhancements"].Bool())
if(CSH->getState() != EClientState::GAMEPLAY && settings["general"]["enableUiEnhancements"].Bool())
{
tabExtraOptions = std::make_shared<ExtraOptionsTab>();
tabExtraOptions->recActions = UPDATE | SHOWALL | LCLICK | RCLICK_POPUP;

View File

@ -176,7 +176,7 @@
"bonuses" : {
"damage" : {
"type" : "CREATURE_DAMAGE",
"subtype" : "creatureDamageMin",
"subtype" : "creatureDamageBoth",
"val" : 5
},
"attack" : {

View File

@ -31,7 +31,10 @@ Minimalistic version of this file:
``` javascript
{
"name" : "My test mod",
"description" : "My test mod that add a lot of useless stuff into the game"
"description" : "My test mod that add a lot of useless stuff into the game",
"version" : "1.00",
"modType" : "Graphical",
"contact" : "http://www.contact.example.com"
}
```

View File

@ -742,7 +742,7 @@ DamageEstimation CBattleInfoCallback::battleEstimateDamage(const battle::Unit *
{
RETURN_IF_NOT_BATTLE({});
auto reachability = battleGetDistances(attacker, attacker->getPosition());
int getMovementRange = reachability[attackerPosition];
int getMovementRange = attackerPosition.isValid() ? reachability[attackerPosition] : 0;
return battleEstimateDamage(attacker, defender, getMovementRange, retaliationDmg);
}

View File

@ -369,7 +369,7 @@ JsonNode CampaignState::crossoverSerialize(CGHeroInstance * hero) const
CGHeroInstance * CampaignState::crossoverDeserialize(const JsonNode & node, CMap * map) const
{
JsonDeserializer handler(nullptr, const_cast<JsonNode&>(node));
auto * hero = new CGHeroInstance(map->cb);
auto * hero = new CGHeroInstance(map ? map->cb : nullptr);
hero->ID = Obj::HERO;
hero->serializeJsonOptions(handler);
if (map)

View File

@ -642,7 +642,6 @@ void CGameState::initHeroes()
boat->id = ObjectInstanceID(static_cast<si32>(gs->map->objects.size()));
map->objects.emplace_back(boat);
map->addBlockVisTiles(boat);
hero->attachToBoat(boat);
}

View File

@ -572,16 +572,18 @@ void CMap::removeObject(CGObjectInstance * obj)
instanceNames.erase(obj->instanceName);
//update indeces
auto iter = std::next(objects.begin(), obj->id.getNum());
iter = objects.erase(iter);
for(int i = obj->id.getNum(); iter != objects.end(); ++i, ++iter)
{
(*iter)->id = ObjectInstanceID(i);
}
obj->afterRemoveFromMap(this);
//TOOD: Clean artifact instances (mostly worn by hero?) and quests related to this object
//This causes crash with undo/redo in editor
}
bool CMap::isWaterMap() const
@ -704,4 +706,38 @@ void CMap::resolveQuestIdentifiers()
questIdentifierToId.clear();
}
void CMap::reindexObjects()
{
// Only reindex at editor / RMG operations
std::sort(objects.begin(), objects.end(), [](const CGObjectInstance * lhs, const CGObjectInstance * rhs)
{
// Obstacles first, then visitable, at the end - removable
if (!lhs->isVisitable() && rhs->isVisitable())
return true;
if (lhs->isVisitable() && !rhs->isVisitable())
return false;
// Special case for Windomill - draw on top of other objects
if (lhs->ID != Obj::WINDMILL && rhs->ID == Obj::WINDMILL)
return true;
if (lhs->ID == Obj::WINDMILL && rhs->ID != Obj::WINDMILL)
return false;
if (!lhs->isRemovable() && rhs->isRemovable())
return true;
if (lhs->isRemovable() && !rhs->isRemovable())
return false;
return lhs->pos.y < rhs->pos.y;
});
// instanceNames don't change
for (size_t i = 0; i < objects.size(); ++i)
{
objects[i]->id = ObjectInstanceID(i);
}
}
VCMI_LIB_NAMESPACE_END

View File

@ -128,6 +128,8 @@ public:
void resetStaticData();
void resolveQuestIdentifiers();
void reindexObjects();
ui32 checksum;
std::vector<Rumor> rumors;
std::vector<DisposedHero> disposedHeroes;

View File

@ -47,6 +47,8 @@ CComposedOperation::CComposedOperation(CMap* map) : CMapOperation(map)
void CComposedOperation::execute()
{
// FIXME: Only reindex objects at the end of composite operation
for(auto & operation : operations)
{
operation->execute();

View File

@ -419,6 +419,7 @@ void CMapGenerator::fillZones()
auto grailZone = *RandomGeneratorUtil::nextItem(treasureZones, rand);
map->getMap(this).grailPos = *RandomGeneratorUtil::nextItem(grailZone->freePaths()->getTiles(), rand);
map->getMap(this).reindexObjects();
logGlobal->info("Zones filled successfully");

View File

@ -288,7 +288,7 @@ void LobbyDatabase::prepareStatements()
isAccountNameExistsStatement = database->prepare(R"(
SELECT COUNT(displayName)
FROM accounts
WHERE displayName = ?
WHERE displayName = ? COLLATE NOCASE
)");
}