mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Object picker for victory/loss conditions
This commit is contained in:
		| @@ -279,10 +279,53 @@ void LoseConditions::on_loseComboBox_currentIndexChanged(int index) | ||||
|  | ||||
| void LoseConditions::onObjectSelect() | ||||
| { | ||||
| 	int loseCondition = ui->loseComboBox->currentIndex() - 1; | ||||
| 	for(int lvl : {0, 1}) | ||||
| 	{ | ||||
| 		auto & l = controller->scene(lvl)->objectPickerView; | ||||
| 		switch(loseCondition) | ||||
| 		{ | ||||
| 			case 0: {  //EventCondition::CONTROL (Obj::TOWN) | ||||
| 				l.highlight<const CGTownInstance>(); | ||||
| 				break; | ||||
| 			} | ||||
| 				 | ||||
| 			case 1: { //EventCondition::CONTROL (Obj::HERO) | ||||
| 				l.highlight<const CGHeroInstance>(); | ||||
| 				break; | ||||
| 			} | ||||
| 			default: | ||||
| 				return; | ||||
| 		} | ||||
| 		l.update(); | ||||
| 		QObject::connect(&l, &ObjectPickerLayer::selectionMade, this, &LoseConditions::onObjectPicked); | ||||
| 	} | ||||
| 	 | ||||
| 	dynamic_cast<QWidget*>(parent()->parent()->parent()->parent()->parent()->parent()->parent())->hide(); | ||||
| } | ||||
|  | ||||
| void LoseConditions::onObjectPicked(const CGObjectInstance * obj) | ||||
| { | ||||
| 	dynamic_cast<QWidget*>(parent()->parent()->parent()->parent()->parent()->parent()->parent())->show(); | ||||
| 	 | ||||
| 	for(int lvl : {0, 1}) | ||||
| 	{ | ||||
| 		auto & l = controller->scene(lvl)->objectPickerView; | ||||
| 		l.clear(); | ||||
| 		l.update(); | ||||
| 		QObject::disconnect(&l, &ObjectPickerLayer::selectionMade, this, &LoseConditions::onObjectPicked); | ||||
| 	} | ||||
| 	 | ||||
| 	if(!obj) //discarded | ||||
| 		return; | ||||
| 	 | ||||
| 	for(int i = 0; i < loseTypeWidget->count(); ++i) | ||||
| 	{ | ||||
| 		auto data = controller->map()->objects.at(loseTypeWidget->itemData(i).toInt()); | ||||
| 		if(data == obj) | ||||
| 		{ | ||||
| 			loseTypeWidget->setCurrentIndex(i); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -13,6 +13,7 @@ | ||||
| #include "../mapcontroller.h" | ||||
| #include "../lib/CGeneralTextHandler.h" | ||||
| #include "../lib/constants/StringConstants.h" | ||||
| #include "../../lib/mapObjects/CGCreature.h" | ||||
|  | ||||
| #include "../inspector/townbulidingswidget.h" //to convert BuildingID to string | ||||
|  | ||||
| @@ -31,7 +32,7 @@ void VictoryConditions::initialize(MapController & c) | ||||
| 	ui->victoryMessageEdit->setText(QString::fromStdString(controller->map()->victoryMessage.toString())); | ||||
|  | ||||
| 	//victory conditions | ||||
| 	const std::array<std::string, 8> conditionStringsWin = { | ||||
| 	const std::array<std::string, 9> conditionStringsWin = { | ||||
| 		QT_TR_NOOP("No special victory"), | ||||
| 		QT_TR_NOOP("Capture artifact"), | ||||
| 		QT_TR_NOOP("Hire creatures"), | ||||
| @@ -39,7 +40,8 @@ void VictoryConditions::initialize(MapController & c) | ||||
| 		QT_TR_NOOP("Construct building"), | ||||
| 		QT_TR_NOOP("Capture town"), | ||||
| 		QT_TR_NOOP("Defeat hero"), | ||||
| 		QT_TR_NOOP("Transport artifact") | ||||
| 		QT_TR_NOOP("Transport artifact"), | ||||
| 		QT_TR_NOOP("Kill monster") | ||||
| 	}; | ||||
|  | ||||
| 	for(auto & s : conditionStringsWin) | ||||
| @@ -124,10 +126,10 @@ void VictoryConditions::initialize(MapController & c) | ||||
| 						} | ||||
|  | ||||
| 						case EventCondition::DESTROY: { | ||||
| 							ui->victoryComboBox->setCurrentIndex(6); | ||||
| 							assert(victoryTypeWidget); | ||||
| 							if(json["objectType"].Integer() == Obj::HERO) | ||||
| 							{ | ||||
| 								ui->victoryComboBox->setCurrentIndex(6); | ||||
| 								assert(victoryTypeWidget); | ||||
| 								int heroIdx = getObjectByPos<const CGHeroInstance>(*controller->map(), posFromJson(json["position"])); | ||||
| 								if(heroIdx >= 0) | ||||
| 								{ | ||||
| @@ -135,7 +137,17 @@ void VictoryConditions::initialize(MapController & c) | ||||
| 									victoryTypeWidget->setCurrentIndex(idx); | ||||
| 								} | ||||
| 							} | ||||
| 							//TODO: support control other objects (monsters) | ||||
| 							if(json["objectType"].Integer() == Obj::MONSTER) | ||||
| 							{ | ||||
| 								ui->victoryComboBox->setCurrentIndex(8); | ||||
| 								assert(victoryTypeWidget); | ||||
| 								int monsterIdx = getObjectByPos<const CGCreature>(*controller->map(), posFromJson(json["position"])); | ||||
| 								if(monsterIdx >= 0) | ||||
| 								{ | ||||
| 									auto idx = victoryTypeWidget->findData(monsterIdx); | ||||
| 									victoryTypeWidget->setCurrentIndex(idx); | ||||
| 								} | ||||
| 							} | ||||
| 							break; | ||||
| 						} | ||||
|  | ||||
| @@ -283,6 +295,18 @@ void VictoryConditions::update() | ||||
| 				specialVictory.trigger = EventExpression(cond); | ||||
| 				break; | ||||
| 			} | ||||
| 				 | ||||
| 			case 7: { | ||||
| 				EventCondition cond(EventCondition::DESTROY); | ||||
| 				assert(victoryTypeWidget); | ||||
| 				cond.objectType = Obj::MONSTER; | ||||
| 				int monsterIdx = victoryTypeWidget->currentData().toInt(); | ||||
| 				cond.position = controller->map()->objects[monsterIdx]->pos; | ||||
| 				specialVictory.effect.toOtherMessage.appendTextID("core.genrltxt.287"); | ||||
| 				specialVictory.onFulfill.appendTextID("core.genrltxt.286"); | ||||
| 				specialVictory.trigger = EventExpression(cond); | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
|  | ||||
| @@ -318,9 +342,11 @@ void VictoryConditions::on_victoryComboBox_currentIndexChanged(int index) | ||||
| 	delete victoryTypeWidget; | ||||
| 	delete victoryValueWidget; | ||||
| 	delete victorySelectWidget; | ||||
| 	delete pickObjectButton; | ||||
| 	victoryTypeWidget = nullptr; | ||||
| 	victoryValueWidget = nullptr; | ||||
| 	victorySelectWidget = nullptr; | ||||
| 	pickObjectButton = nullptr; | ||||
|  | ||||
| 	if(index == 0) | ||||
| 	{ | ||||
| @@ -385,6 +411,10 @@ void VictoryConditions::on_victoryComboBox_currentIndexChanged(int index) | ||||
| 			victorySelectWidget->addItem("Any town", QVariant::fromValue(-1)); | ||||
| 			for(int i : getObjectIndexes<const CGTownInstance>(*controller->map())) | ||||
| 				victorySelectWidget->addItem(getTownName(*controller->map(), i).c_str(), QVariant::fromValue(i)); | ||||
| 			 | ||||
| 			pickObjectButton = new QToolButton; | ||||
| 			connect(pickObjectButton, &QToolButton::clicked, this, &VictoryConditions::onObjectSelect); | ||||
| 			ui->victoryParamsLayout->addWidget(pickObjectButton); | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| @@ -393,6 +423,9 @@ void VictoryConditions::on_victoryComboBox_currentIndexChanged(int index) | ||||
| 			ui->victoryParamsLayout->addWidget(victoryTypeWidget); | ||||
| 			for(int i : getObjectIndexes<const CGTownInstance>(*controller->map())) | ||||
| 				victoryTypeWidget->addItem(tr(getTownName(*controller->map(), i).c_str()), QVariant::fromValue(i)); | ||||
| 			pickObjectButton = new QToolButton; | ||||
| 			connect(pickObjectButton, &QToolButton::clicked, this, &VictoryConditions::onObjectSelect); | ||||
| 			ui->victoryParamsLayout->addWidget(pickObjectButton); | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| @@ -401,6 +434,9 @@ void VictoryConditions::on_victoryComboBox_currentIndexChanged(int index) | ||||
| 			ui->victoryParamsLayout->addWidget(victoryTypeWidget); | ||||
| 			for(int i : getObjectIndexes<const CGHeroInstance>(*controller->map())) | ||||
| 				victoryTypeWidget->addItem(tr(getHeroName(*controller->map(), i).c_str()), QVariant::fromValue(i)); | ||||
| 			pickObjectButton = new QToolButton; | ||||
| 			connect(pickObjectButton, &QToolButton::clicked, this, &VictoryConditions::onObjectSelect); | ||||
| 			ui->victoryParamsLayout->addWidget(pickObjectButton); | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| @@ -409,37 +445,103 @@ void VictoryConditions::on_victoryComboBox_currentIndexChanged(int index) | ||||
| 			ui->victoryParamsLayout->addWidget(victoryTypeWidget); | ||||
| 			for(int i = 0; i < controller->map()->allowedArtifact.size(); ++i) | ||||
| 				victoryTypeWidget->addItem(QString::fromStdString(VLC->arth->objects[i]->getNameTranslated()), QVariant::fromValue(i)); | ||||
|  | ||||
| 			 | ||||
| 			victorySelectWidget = new QComboBox; | ||||
| 			ui->victoryParamsLayout->addWidget(victorySelectWidget); | ||||
| 			for(int i : getObjectIndexes<const CGTownInstance>(*controller->map())) | ||||
| 				victorySelectWidget->addItem(tr(getTownName(*controller->map(), i).c_str()), QVariant::fromValue(i)); | ||||
| 			pickObjectButton = new QToolButton; | ||||
| 			connect(pickObjectButton, &QToolButton::clicked, this, &VictoryConditions::onObjectSelect); | ||||
| 			ui->victoryParamsLayout->addWidget(pickObjectButton); | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		//TODO: support this vectory type | ||||
| 		// in order to do that, need to implement finding creature by position | ||||
| 		// selecting from map would be the best user experience | ||||
| 		/*case 7: { //EventCondition::DESTROY (Obj::MONSTER) | ||||
| 			 | ||||
| 		case 7: { //EventCondition::DESTROY (Obj::MONSTER) | ||||
| 			victoryTypeWidget = new QComboBox; | ||||
| 			ui->loseParamsLayout->addWidget(victoryTypeWidget); | ||||
| 			for(int i : getObjectIndexes<const CGCreature>(*mapPointer)) | ||||
| 				victoryTypeWidget->addItem(tr(getMonsterName(i).c_str()), QVariant::fromValue(i)); | ||||
| 			ui->victoryParamsLayout->addWidget(victoryTypeWidget); | ||||
| 			for(int i : getObjectIndexes<const CGCreature>(*controller->map())) | ||||
| 				victoryTypeWidget->addItem(tr(getMonsterName(*controller->map(), i).c_str()), QVariant::fromValue(i)); | ||||
| 			pickObjectButton = new QToolButton; | ||||
| 			connect(pickObjectButton, &QToolButton::clicked, this, &VictoryConditions::onObjectSelect); | ||||
| 			ui->victoryParamsLayout->addWidget(pickObjectButton); | ||||
| 			break; | ||||
| 		}*/ | ||||
|  | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| void VictoryConditions::onObjectSelect() | ||||
| { | ||||
| 	int vicConditions = ui->victoryComboBox->currentIndex() - 1; | ||||
| 	for(int lvl : {0, 1}) | ||||
| 	{ | ||||
| 		auto & l = controller->scene(lvl)->objectPickerView; | ||||
| 		switch(vicConditions) | ||||
| 		{ | ||||
| 			case 3: { //EventCondition::HAVE_BUILDING | ||||
| 				l.highlight<const CGTownInstance>(); | ||||
| 				break; | ||||
| 			} | ||||
| 				 | ||||
| 			case 4: { //EventCondition::CONTROL (Obj::TOWN) | ||||
| 				l.highlight<const CGTownInstance>(); | ||||
| 				break; | ||||
| 			} | ||||
| 				 | ||||
| 			case 5: { //EventCondition::DESTROY (Obj::HERO) | ||||
| 				l.highlight<const CGHeroInstance>(); | ||||
| 				break; | ||||
| 			} | ||||
| 				 | ||||
| 			case 6: { //EventCondition::TRANSPORT (Obj::ARTEFACT) | ||||
| 				l.highlight<const CGTownInstance>(); | ||||
| 				break; | ||||
| 			} | ||||
| 				 | ||||
| 			case 7: { //EventCondition::DESTROY (Obj::MONSTER) | ||||
| 				l.highlight<const CGCreature>(); | ||||
| 				break; | ||||
| 			} | ||||
| 			default: | ||||
| 				return; | ||||
| 		} | ||||
| 		l.update(); | ||||
| 		QObject::connect(&l, &ObjectPickerLayer::selectionMade, this, &VictoryConditions::onObjectPicked); | ||||
| 	} | ||||
| 	 | ||||
| 	dynamic_cast<QWidget*>(parent()->parent()->parent()->parent()->parent()->parent()->parent())->hide(); | ||||
| } | ||||
|  | ||||
| void VictoryConditions::onObjectPicked(const CGObjectInstance * obj) | ||||
| { | ||||
| 	dynamic_cast<QWidget*>(parent()->parent()->parent()->parent()->parent()->parent()->parent())->show(); | ||||
| 	 | ||||
| 	for(int lvl : {0, 1}) | ||||
| 	{ | ||||
| 		auto & l = controller->scene(lvl)->objectPickerView; | ||||
| 		l.clear(); | ||||
| 		l.update(); | ||||
| 		QObject::disconnect(&l, &ObjectPickerLayer::selectionMade, this, &VictoryConditions::onObjectPicked); | ||||
| 	} | ||||
| 	 | ||||
| 	if(!obj) //discarded | ||||
| 		return; | ||||
| 	 | ||||
| 	int vicConditions = ui->victoryComboBox->currentIndex() - 1; | ||||
| 	QComboBox * w = victoryTypeWidget; | ||||
| 	if(vicConditions == 3 || vicConditions == 6) | ||||
| 		w = victorySelectWidget; | ||||
| 	 | ||||
| 	for(int i = 0; i < w->count(); ++i) | ||||
| 	{ | ||||
| 		if(w->itemData(i).toInt() < 0) | ||||
| 			continue; | ||||
| 		 | ||||
| 		auto data = controller->map()->objects.at(w->itemData(i).toInt()); | ||||
| 		if(data == obj) | ||||
| 		{ | ||||
| 			w->setCurrentIndex(i); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user