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:
commit
d9a598ad9c
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -176,7 +176,7 @@
|
||||
"bonuses" : {
|
||||
"damage" : {
|
||||
"type" : "CREATURE_DAMAGE",
|
||||
"subtype" : "creatureDamageMin",
|
||||
"subtype" : "creatureDamageBoth",
|
||||
"val" : 5
|
||||
},
|
||||
"attack" : {
|
||||
|
@ -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"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -128,6 +128,8 @@ public:
|
||||
void resetStaticData();
|
||||
void resolveQuestIdentifiers();
|
||||
|
||||
void reindexObjects();
|
||||
|
||||
ui32 checksum;
|
||||
std::vector<Rumor> rumors;
|
||||
std::vector<DisposedHero> disposedHeroes;
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
||||
|
@ -288,7 +288,7 @@ void LobbyDatabase::prepareStatements()
|
||||
isAccountNameExistsStatement = database->prepare(R"(
|
||||
SELECT COUNT(displayName)
|
||||
FROM accounts
|
||||
WHERE displayName = ?
|
||||
WHERE displayName = ? COLLATE NOCASE
|
||||
)");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user