File indexing completed on 2024-05-05 05:40:23
0001 /*************************************************************************** 0002 * Copyright (C) 2021 by Renaud Guezennec * 0003 * http://www.rolisteam.org/contact * 0004 * * 0005 * This software is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "controller/antagonistboardcontroller.h" 0021 0022 #include <data/campaign.h> 0023 #include <data/campaigneditor.h> 0024 #include <data/character.h> 0025 #include <worker/iohelper.h> 0026 0027 namespace campaign 0028 { 0029 0030 template <typename T> 0031 QList<CharacterField*> convertToGeneric(QList<T> list) 0032 { 0033 QList<CharacterField*> res; 0034 0035 std::transform(std::begin(list), std::end(list), std::back_inserter(res), 0036 [](T type) 0037 { 0038 CharacterField* tmp= type; 0039 return tmp; 0040 }); 0041 0042 return res; 0043 } 0044 0045 template <typename T> 0046 QList<T> convertToSpecific(QList<CharacterField*> list) 0047 { 0048 QList<T> res; 0049 0050 std::transform(std::begin(list), std::end(list), std::back_inserter(res), 0051 [](CharacterField* type) { return dynamic_cast<T>(type); }); 0052 0053 return res; 0054 } 0055 /* 0056 template <typename T> 0057 bool isNull(const T& value); 0058 0059 template <> 0060 bool isNull(const QPixmap& value) 0061 { 0062 return value.isNull(); 0063 } 0064 template <> 0065 bool isNull(const QString& value) 0066 { 0067 return value.isEmpty(); 0068 } 0069 0070 template <> 0071 bool isNull(const int& value) 0072 { 0073 return value == 0; 0074 } 0075 0076 template <> 0077 bool isNull(const bool& value) 0078 { 0079 return !value; 0080 } 0081 0082 template <typename T> 0083 bool isAccepted(FilteredCharacterModel::Definition def, T value) 0084 { 0085 if(def == FilteredCharacterModel::All) 0086 { 0087 return true; 0088 } 0089 else if(def == FilteredCharacterModel::With) 0090 { 0091 return !isNull(value); 0092 } 0093 else 0094 { 0095 return isNull(value); 0096 } 0097 } 0098 */ 0099 AntagonistBoardController::AntagonistBoardController(campaign::CampaignEditor* editor, QObject* parent) 0100 : QObject(parent) 0101 , m_editor(editor) 0102 , m_models{{new GenericModel({QStringLiteral("Name"), QStringLiteral("Command")}, {}, this), 0103 new GenericModel({QStringLiteral("Name"), QStringLiteral("Uri")}, {1}, this), 0104 new GenericModel({QStringLiteral("Name"), QStringLiteral("Value")}, {}, this)}} 0105 , m_filteredModel(new FilteredCharacterModel) 0106 , m_colorModel(new ColorModel) 0107 , m_stateModel(new StateModel) 0108 { 0109 if(m_editor) 0110 { 0111 auto campaign= m_editor->campaign(); 0112 m_filteredModel->setSourceModel(campaign->npcModel()); 0113 m_colorModel->setSourceModel(campaign->npcModel()); 0114 m_stateModel->setSourceModel(campaign->npcModel()); 0115 connect( 0116 campaign->npcModel(), &campaign::NonPlayableCharacterModel::modelReset, m_colorModel.get(), 0117 [this]() 0118 { 0119 auto campaign= m_editor->campaign(); 0120 if(!campaign) 0121 return; 0122 0123 m_colorModel->setSourceModel(campaign->npcModel()); 0124 m_stateModel->setSourceModel(campaign->npcModel()); 0125 }, 0126 Qt::QueuedConnection); 0127 0128 connect(m_filteredModel.get(), &FilteredCharacterModel::searchChanged, this, 0129 &AntagonistBoardController::searchTextChanged); 0130 connect(campaign, &campaign::Campaign::stateModelChanged, this, 0131 &AntagonistBoardController::characterStateModelChanged); 0132 connect(campaign, &campaign::Campaign::stateModelChanged, this, &AntagonistBoardController::stateModelChanged); 0133 } 0134 } 0135 0136 QString AntagonistBoardController::searchText() const 0137 { 0138 return m_filteredModel->search(); 0139 } 0140 0141 FilteredCharacterModel* AntagonistBoardController::filteredModel() const 0142 { 0143 return m_filteredModel.get(); 0144 } 0145 0146 GenericModel* AntagonistBoardController::actionModel() const 0147 { 0148 return m_models[static_cast<int>(ModelType::Model_Action)]; 0149 } 0150 0151 GenericModel* AntagonistBoardController::shapeModel() const 0152 { 0153 return m_models[static_cast<int>(ModelType::Model_Shape)]; 0154 } 0155 0156 GenericModel* AntagonistBoardController::propertyModel() const 0157 { 0158 return m_models[static_cast<int>(ModelType::Model_Properties)]; 0159 } 0160 0161 bool AntagonistBoardController::editingCharacter() const 0162 { 0163 return !m_character.isNull(); 0164 } 0165 NonPlayableCharacter* AntagonistBoardController::character() const 0166 { 0167 return m_character; 0168 } 0169 0170 void AntagonistBoardController::removeData(const QModelIndex& index, campaign::ModelType type) 0171 { 0172 if(!index.isValid()) 0173 return; 0174 0175 m_models[static_cast<int>(type)]->removeData(index); 0176 } 0177 0178 void AntagonistBoardController::appendData(ModelType type) 0179 { 0180 switch(type) 0181 { 0182 case ModelType::Model_Action: 0183 m_models[static_cast<int>(type)]->addData(new CharacterAction); 0184 break; 0185 case ModelType::Model_Properties: 0186 m_models[static_cast<int>(type)]->addData(new CharacterProperty); 0187 break; 0188 case ModelType::Model_Shape: 0189 m_models[static_cast<int>(type)]->addData(new CharacterShape); 0190 break; 0191 } 0192 } 0193 0194 void AntagonistBoardController::editCharacter(const QString& id) 0195 { 0196 auto campaign= m_editor->campaign(); 0197 auto const& list= campaign->npcModel()->npcList(); 0198 auto it= std::find_if(std::begin(list), std::end(list), 0199 [id](const std::unique_ptr<NonPlayableCharacter>& npc) { return npc->uuid() == id; }); 0200 0201 if(it == std::end(list)) 0202 return; 0203 0204 setCharacter((*it).get()); 0205 } 0206 0207 void AntagonistBoardController::setCharacter(NonPlayableCharacter* character) 0208 { 0209 if(character == m_character) 0210 return; 0211 m_character= character; 0212 0213 if(m_character) 0214 { 0215 auto actMo= actionModel(); 0216 actMo->resetData(convertToGeneric<CharacterAction*>(character->actionList())); 0217 0218 auto pros= propertyModel(); 0219 pros->resetData(convertToGeneric<CharacterProperty*>(character->propertiesList())); 0220 0221 auto shapes= shapeModel(); 0222 shapes->resetData(convertToGeneric<CharacterShape*>(character->shapeList())); 0223 } 0224 0225 emit characterChanged(); 0226 } 0227 0228 void AntagonistBoardController::saveToken() 0229 { 0230 if(!m_character) 0231 return; 0232 0233 m_character->defineActionList(convertToSpecific<CharacterAction*>(actionModel()->fields())); 0234 m_character->definePropertiesList(convertToSpecific<CharacterProperty*>(propertyModel()->fields())); 0235 m_character->defineShapeList(convertToSpecific<CharacterShape*>(shapeModel()->fields())); 0236 0237 auto model= m_editor->campaign()->npcModel(); 0238 model->refresh(m_character->uuid()); 0239 0240 setCharacter(nullptr); 0241 } 0242 0243 void AntagonistBoardController::addCharacter() 0244 { 0245 m_editor->campaign()->addCharacter(); 0246 } 0247 0248 void AntagonistBoardController::changeImage(const QString& id, const QByteArray& data) 0249 { 0250 auto campaign= m_editor->campaign(); 0251 auto const& model= campaign->npcModel(); 0252 auto index= model->indexFromUuid(id); 0253 auto path= m_editor->saveAvatar(id, data); 0254 model->setData(index, data, NonPlayableCharacterModel::RoleAvatar); 0255 model->setData(index, path, NonPlayableCharacterModel::RoleAvatarPath); 0256 } 0257 0258 QString AntagonistBoardController::imageFolder() const 0259 { 0260 return m_editor->campaign()->directory(campaign::Campaign::Place::MEDIA_ROOT); 0261 } 0262 0263 void AntagonistBoardController::removeCharacter(const QString& id) 0264 { 0265 m_editor->campaign()->removeCharacter(id); 0266 } 0267 0268 void AntagonistBoardController::setSearchText(const QString& text) 0269 { 0270 m_filteredModel->setSearch(text); 0271 } 0272 0273 FilteredCharacterModel::Definition FilteredCharacterModel::gmdetailsDef() const 0274 { 0275 return m_gmdetailsDef; 0276 } 0277 0278 void FilteredCharacterModel::setGmdetailsDef(FilteredCharacterModel::Definition newGmdetailsDef) 0279 { 0280 if(m_gmdetailsDef == newGmdetailsDef) 0281 return; 0282 m_gmdetailsDef= newGmdetailsDef; 0283 emit gmdetailsDefChanged(); 0284 } 0285 0286 const QString& FilteredCharacterModel::gmdetails() const 0287 { 0288 return m_gmdetails; 0289 } 0290 0291 void FilteredCharacterModel::setGmdetails(const QString& newGmdetails) 0292 { 0293 if(m_gmdetails == newGmdetails) 0294 return; 0295 m_gmdetails= newGmdetails; 0296 emit gmdetailsChanged(); 0297 } 0298 0299 FilteredCharacterModel::HealthState FilteredCharacterModel::hlState() const 0300 { 0301 return m_hlState; 0302 } 0303 0304 void FilteredCharacterModel::setHlState(FilteredCharacterModel::HealthState newHlState) 0305 { 0306 if(m_hlState == newHlState) 0307 return; 0308 m_hlState= newHlState; 0309 emit hlStateChanged(); 0310 } 0311 0312 ColorModel* AntagonistBoardController::colorModel() const 0313 { 0314 return m_colorModel.get(); 0315 } 0316 0317 StateModel* AntagonistBoardController::stateModel() const 0318 { 0319 return m_stateModel.get(); 0320 } 0321 0322 CharacterStateModel* AntagonistBoardController::characterStateModel() const 0323 { 0324 if(!m_editor) 0325 return nullptr; 0326 0327 auto camp= m_editor->campaign(); 0328 if(!camp) 0329 return nullptr; 0330 0331 return camp->stateModel(); 0332 } 0333 0334 } // namespace campaign