Complete city production queue implementation

This commit is contained in:
bart
2026-11-08 22:30:13 +01:00
parent 4eda595861
commit 980e777199
14 changed files with 222 additions and 20 deletions
+87 -14
View File
@@ -455,41 +455,106 @@ bool GameManager::buyTileForCity(int cityId, int tx, int ty)
return true;
}
void GameManager::setCityProject(int cityId, CityProjectType type, const QString &id)
void GameManager::queueCityProject(int cityId, CityProjectType type, const QString &id)
{
City *city = getCityById(cityId);
if (!city) return;
const CityConfig &cCfg = TerrainYieldManager::instance().getCityConfig();
int maxQueue = cCfg.maxProductionQueueSize;
if (type == CityProjectType::Unit) {
const UnitConfig *uCfg = m_unitConfigManager.getConfig(id);
if (!uCfg) return;
city->startProject(CityProjectType::Unit, id, uCfg->name, uCfg->laborCost);
QString msg = Localization::instance().get("ui.city.project_started", "%1: Started %2")
.arg(city->name).arg(uCfg->name);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(255, 230, 80), 2.5f);
if (!city->hasActiveProject()) {
city->startProject(CityProjectType::Unit, id, uCfg->name, uCfg->laborCost);
QString msg = Localization::instance().get("ui.city.project_started", "%1: Started %2")
.arg(city->name).arg(uCfg->name);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(255, 230, 80), 2.5f);
} else {
if ((int)city->projectQueue.size() >= maxQueue) {
QString msg = Localization::instance().get("ui.city.queue_full_float", "Production queue is full! (Max %1)").arg(maxQueue);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(255, 100, 100), 2.0f);
return;
}
city->queueProject(CityProjectType::Unit, id, uCfg->name, uCfg->laborCost, "center", maxQueue);
int pos = (int)city->projectQueue.size();
QString msg = Localization::instance().get("ui.city.project_queued", "%1: Added %2 to queue (#%3)")
.arg(city->name).arg(uCfg->name).arg(pos);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(100, 200, 255), 2.2f);
}
} else if (type == CityProjectType::Building) {
const BuildingConfig *bCfg = m_buildingConfigManager.getBuilding(id);
if (!bCfg) return;
if (city->hasBuilding(id)) {
QString msg = Localization::instance().get("ui.city.already_built", "%1 already built!").arg(bCfg->name);
QString msg = Localization::instance().get("ui.city.already_built", "%1 already built in this city!").arg(bCfg->name);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(255, 100, 100), 2.2f);
return;
}
city->startProject(CityProjectType::Building, id, bCfg->name, bCfg->laborCost, bCfg->district);
QString msg = Localization::instance().get("ui.city.project_started", "%1: Started %2")
.arg(city->name).arg(bCfg->name);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(255, 230, 80), 2.5f);
if (city->isBuildingQueuedOrBuilt(id)) {
QString msg = Localization::instance().get("ui.city.already_queued", "%1 is already in the production queue!").arg(bCfg->name);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(255, 160, 60), 2.2f);
return;
}
if (!city->hasActiveProject()) {
city->startProject(CityProjectType::Building, id, bCfg->name, bCfg->laborCost, bCfg->district);
QString msg = Localization::instance().get("ui.city.project_started", "%1: Started %2")
.arg(city->name).arg(bCfg->name);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(255, 230, 80), 2.5f);
} else {
if ((int)city->projectQueue.size() >= maxQueue) {
QString msg = Localization::instance().get("ui.city.queue_full_float", "Production queue is full! (Max %1)").arg(maxQueue);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(255, 100, 100), 2.0f);
return;
}
city->queueProject(CityProjectType::Building, id, bCfg->name, bCfg->laborCost, bCfg->district, maxQueue);
int pos = (int)city->projectQueue.size();
QString msg = Localization::instance().get("ui.city.project_queued", "%1: Added %2 to queue (#%3)")
.arg(city->name).arg(bCfg->name).arg(pos);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(100, 200, 255), 2.2f);
}
}
}
void GameManager::setCityProject(int cityId, CityProjectType type, const QString &id)
{
queueCityProject(cityId, type, id);
}
void GameManager::cancelCityProject(int cityId)
{
City *city = getCityById(cityId);
if (!city || !city->hasActiveProject()) return;
QString msg = Localization::instance().get("ui.city.project_cancelled", "%1: Project cancelled").arg(city->name);
QString cancelledName = city->currentProject.name;
city->cancelActiveProject();
QString msg = Localization::instance().get("ui.city.project_cancelled", "%1: Cancelled %2").arg(city->name).arg(cancelledName);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(255, 180, 80), 2.0f);
city->cancelProject();
if (city->hasActiveProject()) {
QString nextMsg = Localization::instance().get("ui.city.project_started", "%1: Started %2")
.arg(city->name).arg(city->currentProject.name);
addFloatingText(nextMsg, city->worldPos + QVector3D(0.0f, 0.0f, 1.4f), QColor(255, 230, 80), 2.5f);
}
}
void GameManager::removeQueuedCityProject(int cityId, int queueIndex)
{
City *city = getCityById(cityId);
if (!city) return;
if (queueIndex >= 0 && queueIndex < (int)city->projectQueue.size()) {
QString itemName = city->projectQueue[queueIndex].name;
city->removeQueuedProject(queueIndex);
QString msg = Localization::instance().get("ui.city.queued_item_removed", "%1: Removed %2 from queue")
.arg(city->name).arg(itemName);
addFloatingText(msg, city->worldPos + QVector3D(0.0f, 0.0f, 1.2f), QColor(255, 170, 80), 2.0f);
}
}
void GameManager::completeCityProject(City &city, Matrix2D<TerrainPoint> *mapPoints, int numPoints05)
@@ -540,8 +605,16 @@ void GameManager::completeCityProject(City &city, Matrix2D<TerrainPoint> *mapPoi
}
int excess = city.currentProject.currentLabor - city.currentProject.laborCost;
city.accumulatedLabor += std::max(0, excess);
city.cancelProject();
city.advanceQueue();
if (city.hasActiveProject() && excess > 0) {
city.currentProject.currentLabor += excess;
if (city.currentProject.currentLabor >= city.currentProject.laborCost) {
completeCityProject(city, mapPoints, numPoints05);
}
} else {
city.accumulatedLabor += std::max(0, excess);
}
}
void GameManager::commandMoveSelected(int targetX, int targetY, Matrix2D<TerrainPoint> *mapPoints, int numPoints05)