1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

Merge branch 'develop' into battleonly

This commit is contained in:
Laserlicht
2025-11-02 20:31:28 +01:00
committed by GitHub
11 changed files with 150 additions and 60 deletions

View File

@@ -1678,7 +1678,7 @@ void CObjectListWindow::trimTextIfTooWide(std::string & text, bool preserveCount
{ {
auto posBrace = text.find_last_of("("); auto posBrace = text.find_last_of("(");
auto posClosing = text.find_last_of(")"); auto posClosing = text.find_last_of(")");
if (posBrace != std::string::npos && posClosing != std::string::npos && posBrace < posClosing) if (posBrace != std::string::npos && posClosing != std::string::npos && posClosing > posBrace)
{ {
std::string objCount = text.substr(posBrace, posClosing - posBrace) + ')'; std::string objCount = text.substr(posBrace, posClosing - posBrace) + ')';
suffix += " "; suffix += " ";

View File

@@ -1110,8 +1110,10 @@ void CModListView::installMaps(QStringList maps)
} }
else else
{ {
QString fileName = map.section('/', -1, -1); QString srcPath = Helper::getRealPath(map);
if (QFile::exists(destDir + fileName)) QString fileName = QFileInfo(srcPath).fileName();
QString destFile = destDir + fileName;
if (QFile::exists(destFile))
conflictCount++; conflictCount++;
} }
} }
@@ -1198,9 +1200,11 @@ void CModListView::installMaps(QStringList maps)
else else
{ {
// Single map file // Single map file
QString fileName = map.section('/', -1, -1); QString srcPath = Helper::getRealPath(map);
QString fileName = QFileInfo(srcPath).fileName();
QString destFile = destDir + fileName; QString destFile = destDir + fileName;
logGlobal->info("Importing map '%s'", map.toStdString());
logGlobal->info("Importing map '%s'", srcPath.toStdString());
if (QFile::exists(destFile)) if (QFile::exists(destFile))
{ {

View File

@@ -276,7 +276,7 @@ bool CModFilterModel::filterMatchesCategory(const QModelIndex & source) const
return !mod.isInstalled(); return !mod.isInstalled();
case ModFilterMask::INSTALLED: case ModFilterMask::INSTALLED:
return mod.isInstalled(); return mod.isInstalled();
case ModFilterMask::UPDATEABLE: case ModFilterMask::UPDATABLE:
return mod.isUpdateAvailable(); return mod.isUpdateAvailable();
case ModFilterMask::ENABLED: case ModFilterMask::ENABLED:
return mod.isInstalled() && base->model->isModEnabled(modID); return mod.isInstalled() && base->model->isModEnabled(modID);
@@ -320,6 +320,31 @@ bool CModFilterModel::filterAcceptsRow(int source_row, const QModelIndex & sourc
return false; return false;
} }
bool CModFilterModel::lessThan(const QModelIndex & source_left, const QModelIndex & source_right) const
{
if(source_left.column() != ModFields::STATUS_ENABLED)
return QSortFilterProxyModel::lessThan(source_left, source_right);
const auto leftMod = base->model->getMod(base->modIndexToName(source_left));
const auto rightMod = base->model->getMod(base->modIndexToName(source_right));
const auto isLeftEnabled = base->model->isModEnabled(leftMod.getID());
const auto isRightEnabled = base->model->isModEnabled(rightMod.getID());
if(!isLeftEnabled && isRightEnabled)
return true;
if(isLeftEnabled && !isRightEnabled)
return false;
const auto isLeftInstalled = leftMod.isInstalled();
const auto isRightInstalled = rightMod.isInstalled();
if(!isLeftInstalled && isRightInstalled)
return true;
if(isLeftInstalled && !isRightInstalled)
return false;
return QSortFilterProxyModel::lessThan(source_left.siblingAtColumn(ModFields::NAME), source_right.siblingAtColumn(ModFields::NAME));
}
CModFilterModel::CModFilterModel(ModStateItemModel * model, QObject * parent) CModFilterModel::CModFilterModel(ModStateItemModel * model, QObject * parent)
: QSortFilterProxyModel(parent), base(model), filterMask(ModFilterMask::ALL) : QSortFilterProxyModel(parent), base(model), filterMask(ModFilterMask::ALL)
{ {

View File

@@ -32,7 +32,7 @@ enum class ModFilterMask : uint8_t
ALL, ALL,
AVAILABLE, AVAILABLE,
INSTALLED, INSTALLED,
UPDATEABLE, UPDATABLE,
ENABLED, ENABLED,
DISABLED DISABLED
}; };
@@ -97,6 +97,8 @@ class CModFilterModel final : public QSortFilterProxyModel
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const override; bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const override;
bool lessThan(const QModelIndex & source_left, const QModelIndex & source_right) const override;
public: public:
void setTypeFilter(ModFilterMask filterMask); void setTypeFilter(ModFilterMask filterMask);

View File

@@ -20,7 +20,8 @@
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
const std::vector<CDrawLinesOperation::LinePattern> CDrawLinesOperation::patterns = template <typename T>
const std::vector<typename CDrawLinesOperation<T>::LinePattern> CDrawLinesOperation<T>::patterns =
{ {
//single tile. fall-back pattern //single tile. fall-back pattern
{ {
@@ -156,34 +157,47 @@ static bool ruleIsAny(const std::string & rule)
#endif #endif
///CDrawLinesOperation ///CDrawLinesOperation
CDrawLinesOperation::CDrawLinesOperation(CMap * map, CTerrainSelection terrainSel, vstd::RNG * gen): template <typename T>
CDrawLinesOperation<T>::CDrawLinesOperation(CMap * map, CTerrainSelection terrainSel, T lineType, vstd::RNG * gen):
CMapOperation(map), CMapOperation(map),
terrainSel(std::move(terrainSel)), terrainSel(std::move(terrainSel)),
lineType(lineType),
gen(gen) gen(gen)
{ {
} }
///CDrawRoadsOperation ///CDrawRoadsOperation
CDrawRoadsOperation::CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, RoadId roadType, vstd::RNG * gen): CDrawRoadsOperation::CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, RoadId roadType, vstd::RNG * gen):
CDrawLinesOperation(map, terrainSel,gen), CDrawLinesOperation(map, terrainSel,roadType, gen)
roadType(roadType) {}
{
}
///CDrawRiversOperation ///CDrawRiversOperation
CDrawRiversOperation::CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, RiverId riverType, vstd::RNG * gen): CDrawRiversOperation::CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, RiverId riverType, vstd::RNG * gen):
CDrawLinesOperation(map, terrainSel, gen), CDrawLinesOperation(map, terrainSel, riverType, gen)
riverType(riverType) {}
template <typename T>
void CDrawLinesOperation<T>::execute()
{ {
for(const auto & pos : terrainSel.getSelectedItems())
{
auto identifier = getIdentifier(map->getTile(pos));
if (formerState.find(identifier) == formerState.end())
formerState.insert({identifier, CTerrainSelection(terrainSel.getMap())});
formerState.at(identifier).select(pos);
}
drawLines(terrainSel, lineType);
} }
void CDrawLinesOperation::execute() template <typename T>
void CDrawLinesOperation<T>::drawLines(CTerrainSelection selection, T type)
{ {
std::set<int3> invalidated; std::set<int3> invalidated;
for(const auto & pos : terrainSel.getSelectedItems()) for(const auto & pos : selection.getSelectedItems())
{ {
executeTile(map->getTile(pos)); executeTile(map->getTile(pos), type);
auto rect = extendTileAroundSafely(pos); auto rect = extendTileAroundSafely(pos);
rect.forEach([&invalidated](const int3 & pos) rect.forEach([&invalidated](const int3 & pos)
@@ -195,17 +209,23 @@ void CDrawLinesOperation::execute()
updateTiles(invalidated); updateTiles(invalidated);
} }
void CDrawLinesOperation::undo() template <typename T>
void CDrawLinesOperation<T>::undo()
{ {
//TODO for (auto const& typeToSelection : formerState)
{
drawLines(typeToSelection.second, typeToSelection.first);
}
} }
void CDrawLinesOperation::redo() template <typename T>
void CDrawLinesOperation<T>::redo()
{ {
//TODO drawLines(terrainSel, lineType);
} }
void CDrawLinesOperation::flipPattern(LinePattern& pattern, int flip) const template <typename T>
void CDrawLinesOperation<T>::flipPattern(LinePattern& pattern, int flip) const
{ {
//todo: use cashing here and also in terrain patterns //todo: use cashing here and also in terrain patterns
@@ -233,7 +253,8 @@ void CDrawLinesOperation::flipPattern(LinePattern& pattern, int flip) const
} }
} }
void CDrawLinesOperation::updateTiles(std::set<int3> & invalidated) template <typename T>
void CDrawLinesOperation<T>::updateTiles(std::set<int3> & invalidated)
{ {
for(const int3 & coord : invalidated) for(const int3 & coord : invalidated)
{ {
@@ -264,7 +285,8 @@ void CDrawLinesOperation::updateTiles(std::set<int3> & invalidated)
} }
} }
CDrawLinesOperation::ValidationResult CDrawLinesOperation::validateTile(const LinePattern & pattern, const int3 & pos) template <typename T>
typename CDrawLinesOperation<T>::ValidationResult CDrawLinesOperation<T>::validateTile(const LinePattern & pattern, const int3 & pos)
{ {
ValidationResult result(false); ValidationResult result(false);
@@ -342,14 +364,14 @@ std::string CDrawRiversOperation::getLabel() const
return "Draw Rivers"; return "Draw Rivers";
} }
void CDrawRoadsOperation::executeTile(TerrainTile & tile) void CDrawRoadsOperation::executeTile(TerrainTile & tile, RoadId type)
{ {
tile.roadType = roadType; tile.roadType = type;
} }
void CDrawRiversOperation::executeTile(TerrainTile & tile) void CDrawRiversOperation::executeTile(TerrainTile & tile, RiverId type)
{ {
tile.riverType = riverType; tile.riverType = type;
} }
bool CDrawRoadsOperation::canApplyPattern(const LinePattern & pattern) const bool CDrawRoadsOperation::canApplyPattern(const LinePattern & pattern) const
@@ -398,4 +420,14 @@ void CDrawRiversOperation::updateTile(TerrainTile & tile, const LinePattern & pa
tile.extTileFlags = (tile.extTileFlags & 0b00111111) | (flip << 2); tile.extTileFlags = (tile.extTileFlags & 0b00111111) | (flip << 2);
} }
RiverId CDrawRiversOperation::getIdentifier(TerrainTile & tile) const
{
return tile.riverType;
}
RoadId CDrawRoadsOperation::getIdentifier(TerrainTile & tile) const
{
return tile.roadType;
}
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@@ -16,7 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
struct TerrainTile; struct TerrainTile;
class CDrawLinesOperation : public CMapOperation template <typename T> class CDrawLinesOperation : public CMapOperation
{ {
public: public:
void execute() override; void execute() override;
@@ -41,14 +41,15 @@ protected:
int flip; int flip;
}; };
CDrawLinesOperation(CMap * map, CTerrainSelection terrainSel, vstd::RNG * gen); CDrawLinesOperation(CMap * map, CTerrainSelection terrainSel, T lineType, vstd::RNG * gen);
virtual void executeTile(TerrainTile & tile) = 0; virtual void executeTile(TerrainTile & tile, T type) = 0;
virtual bool canApplyPattern(const CDrawLinesOperation::LinePattern & pattern) const = 0; virtual bool canApplyPattern(const LinePattern & pattern) const = 0;
virtual bool needUpdateTile(const TerrainTile & tile) const = 0; virtual bool needUpdateTile(const TerrainTile & tile) const = 0;
virtual bool tileHasSomething(const int3 & pos) const = 0; virtual bool tileHasSomething(const int3 & pos) const = 0;
virtual void updateTile(TerrainTile & tile, const CDrawLinesOperation::LinePattern & pattern, const int flip) = 0; virtual void updateTile(TerrainTile & tile, const LinePattern & pattern, const int flip) = 0;
virtual T getIdentifier(TerrainTile & tile) const = 0;
static const std::vector<LinePattern> patterns; static const std::vector<LinePattern> patterns;
void flipPattern(LinePattern & pattern, int flip) const; void flipPattern(LinePattern & pattern, int flip) const;
@@ -58,38 +59,45 @@ protected:
ValidationResult validateTile(const LinePattern & pattern, const int3 & pos); ValidationResult validateTile(const LinePattern & pattern, const int3 & pos);
CTerrainSelection terrainSel; CTerrainSelection terrainSel;
T lineType;
vstd::RNG * gen; vstd::RNG * gen;
std::map<T, CTerrainSelection> formerState;
private:
void drawLines(CTerrainSelection selection, T type);
}; };
class CDrawRoadsOperation : public CDrawLinesOperation class CDrawRoadsOperation : public CDrawLinesOperation<RoadId>
{ {
public: public:
CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, RoadId roadType, vstd::RNG * gen); CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, RoadId roadType, vstd::RNG * gen);
std::string getLabel() const override; std::string getLabel() const override;
protected: protected:
void executeTile(TerrainTile & tile) override; void executeTile(TerrainTile & tile, RoadId type) override;
bool canApplyPattern(const CDrawLinesOperation::LinePattern & pattern) const override; bool canApplyPattern(const LinePattern & pattern) const override;
bool needUpdateTile(const TerrainTile & tile) const override; bool needUpdateTile(const TerrainTile & tile) const override;
bool tileHasSomething(const int3 & pos) const override; bool tileHasSomething(const int3 & pos) const override;
void updateTile(TerrainTile & tile, const CDrawLinesOperation::LinePattern & pattern, const int flip) override; void updateTile(TerrainTile & tile, const LinePattern & pattern, const int flip) override;
RoadId getIdentifier(TerrainTile & tile) const override;
private: private:
RoadId roadType; RoadId roadType;
}; };
class CDrawRiversOperation : public CDrawLinesOperation class CDrawRiversOperation : public CDrawLinesOperation<RiverId>
{ {
public: public:
CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, RiverId roadType, vstd::RNG * gen); CDrawRiversOperation(CMap * map, const CTerrainSelection & terrainSel, RiverId roadType, vstd::RNG * gen);
std::string getLabel() const override; std::string getLabel() const override;
protected: protected:
void executeTile(TerrainTile & tile) override; void executeTile(TerrainTile & tile, RiverId type) override;
bool canApplyPattern(const CDrawLinesOperation::LinePattern & pattern) const override; bool canApplyPattern(const LinePattern & pattern) const override;
bool needUpdateTile(const TerrainTile & tile) const override; bool needUpdateTile(const TerrainTile & tile) const override;
bool tileHasSomething(const int3 & pos) const override; bool tileHasSomething(const int3 & pos) const override;
void updateTile(TerrainTile & tile, const CDrawLinesOperation::LinePattern & pattern, const int flip) override; void updateTile(TerrainTile & tile, const LinePattern & pattern, const int flip) override;
RiverId getIdentifier(TerrainTile & tile) const override;
private: private:
RiverId riverType; RiverId riverType;

View File

@@ -103,22 +103,38 @@ void CDrawTerrainOperation::execute()
for(const auto & pos : terrainSel.getSelectedItems()) for(const auto & pos : terrainSel.getSelectedItems())
{ {
auto & tile = map->getTile(pos); auto & tile = map->getTile(pos);
tile.terrainType = terType; if (formerState.find(tile.terrainType) == formerState.end())
formerState.insert({tile.terrainType, CTerrainSelection(terrainSel.getMap())});
formerState.at(tile.terrainType).select(pos);
}
drawTerrain(terType, terrainSel);
}
void CDrawTerrainOperation::drawTerrain(TerrainId terrainType, CTerrainSelection selection)
{
for(const auto & pos : selection.getSelectedItems())
{
auto & tile = map->getTile(pos);
tile.terrainType = terrainType;
invalidateTerrainViews(pos); invalidateTerrainViews(pos);
} }
updateTerrainTypes(); updateTerrainTypes(selection);
updateTerrainViews(); updateTerrainViews();
invalidatedTerViews.clear();
} }
void CDrawTerrainOperation::undo() void CDrawTerrainOperation::undo()
{ {
//TODO for (auto const& typeToSelection : formerState)
{
drawTerrain(typeToSelection.first, typeToSelection.second);
}
} }
void CDrawTerrainOperation::redo() void CDrawTerrainOperation::redo()
{ {
//TODO drawTerrain(terType, terrainSel);
} }
std::string CDrawTerrainOperation::getLabel() const std::string CDrawTerrainOperation::getLabel() const
@@ -126,9 +142,9 @@ std::string CDrawTerrainOperation::getLabel() const
return "Draw Terrain"; return "Draw Terrain";
} }
void CDrawTerrainOperation::updateTerrainTypes() void CDrawTerrainOperation::updateTerrainTypes(CTerrainSelection selection)
{ {
auto positions = terrainSel.getSelectedItems(); auto positions = selection.getSelectedItems();
while(!positions.empty()) while(!positions.empty())
{ {
const auto & centerPos = *(positions.begin()); const auto & centerPos = *(positions.begin());

View File

@@ -94,7 +94,8 @@ private:
InvalidTiles() : centerPosValid(false) { } InvalidTiles() : centerPosValid(false) { }
}; };
void updateTerrainTypes(); void drawTerrain(TerrainId terrain, CTerrainSelection selection);
void updateTerrainTypes(CTerrainSelection selection);
void invalidateTerrainViews(const int3 & centerPos); void invalidateTerrainViews(const int3 & centerPos);
InvalidTiles getInvalidTiles(const int3 & centerPos) const; InvalidTiles getInvalidTiles(const int3 & centerPos) const;
@@ -106,6 +107,7 @@ private:
CTerrainSelection terrainSel; CTerrainSelection terrainSel;
TerrainId terType; TerrainId terType;
std::map<TerrainId, CTerrainSelection> formerState;
int decorationsPercentage; int decorationsPercentage;
vstd::RNG* gen; vstd::RNG* gen;
std::set<int3> invalidatedTerViews; std::set<int3> invalidatedTerViews;

View File

@@ -77,7 +77,7 @@ namespace ERMConverter
} }
else if(isMacro()) else if(isMacro())
{ {
return boost::to_string(boost::format("M['%s']") % macro); return (boost::format("M['%s']") % macro).str();
} }
else if(isSpecial() && (name.size() == 1)) else if(isSpecial() && (name.size() == 1))
{ {
@@ -206,7 +206,7 @@ namespace ERMConverter
} }
std::string operator()(const int & flag) const std::string operator()(const int & flag) const
{ {
return boost::to_string(boost::format("F['%d']") % flag); return (boost::format("F['%d']") % flag).str();
} }
}; };
@@ -801,14 +801,14 @@ namespace ERMConverter
fmt % target % v.str() % opt; fmt % target % v.str() % opt;
put(fmt.str()); put(fmt.str());
} }
for(int i = paramIndex; i < trig.params->size(); i++) for(int i = paramIndex; i < trig.params->size(); i++)
{ {
opt = std::visit(VR_X(), (*trig.params)[i]); opt = std::visit(VR_X(), (*trig.params)[i]);
if(i > paramIndex) put(","); if(i > paramIndex) put(",");
put(opt); put(opt);
} }
putLine(")"); putLine(")");
} }
break; break;
@@ -1183,7 +1183,7 @@ namespace ERMConverter
} }
void operator()(const boost::recursive_wrapper<VNode> & opt) const; void operator()(const boost::recursive_wrapper<VNode> & opt) const;
void operator()(const VSymbol & opt) const void operator()(const VSymbol & opt) const
{ {
(*out) << "\"" << opt.text << "\""; (*out) << "\"" << opt.text << "\"";
} }
@@ -1589,7 +1589,7 @@ namespace VERMInterpreter
struct OptionConverterVisitor struct OptionConverterVisitor
{ {
VOption operator()(const boost::recursive_wrapper<ERM::TVExp>& cmd) const VOption operator()(const boost::recursive_wrapper<ERM::TVExp>& cmd) const
{ {
return boost::recursive_wrapper<VNode>(VNode(cmd.get())); return boost::recursive_wrapper<VNode>(VNode(cmd.get()));
} }
VOption operator()(const ERM::TSymbol & cmd) const VOption operator()(const ERM::TSymbol & cmd) const
@@ -1599,7 +1599,7 @@ namespace VERMInterpreter
else else
return boost::recursive_wrapper<VNode>(VNode(cmd)); return boost::recursive_wrapper<VNode>(VNode(cmd));
} }
VOption operator()(const char & cmd) const VOption operator()(const char & cmd) const
{ {
return TLiteral(cmd); return TLiteral(cmd);
} }
@@ -1732,6 +1732,7 @@ namespace VERMInterpreter
} }
VermTreeIterator & VermTreeIterator::operator=( const VOptionList & opt ) VermTreeIterator & VermTreeIterator::operator=( const VOptionList & opt )
{ {
// TODO: warning: all paths through this function will call itself [-Winfinite-recursion]
return *this = opt; return *this = opt;
} }
VOption & VermTreeIterator::getAsItem() VOption & VermTreeIterator::getAsItem()

View File

@@ -36,14 +36,14 @@ class GlobalLobbyProcessor;
class CVCMIServer : public LobbyInfo, public INetworkServerListener, public INetworkTimerListener, public IGameServer class CVCMIServer : public LobbyInfo, public INetworkServerListener, public INetworkTimerListener, public IGameServer
{ {
/// Network server instance that receives and processes incoming connections on active socket
std::unique_ptr<INetworkServer> networkServer;
std::unique_ptr<GlobalLobbyProcessor> lobbyProcessor; std::unique_ptr<GlobalLobbyProcessor> lobbyProcessor;
std::chrono::steady_clock::time_point gameplayStartTime; std::chrono::steady_clock::time_point gameplayStartTime;
std::chrono::steady_clock::time_point lastTimerUpdateTime; std::chrono::steady_clock::time_point lastTimerUpdateTime;
std::unique_ptr<INetworkHandler> networkHandler; std::unique_ptr<INetworkHandler> networkHandler;
/// Network server instance that receives and processes incoming connections on active socket
std::unique_ptr<INetworkServer> networkServer;
EServerState state = EServerState::LOBBY; EServerState state = EServerState::LOBBY;