File indexing completed on 2024-04-28 05:37:00
0001 /*************************************************************************** 0002 * Copyright (C) 2015 by Renaud Guezennec * 0003 * https://rolisteam.org/contact * 0004 * * 0005 * rolisteam 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 0021 #include "operationcondition.h" 0022 0023 OperationCondition::OperationCondition() 0024 : m_operator(Dice::ConditionOperator::Modulo), m_boolean(nullptr), m_value(nullptr) 0025 { 0026 } 0027 OperationCondition::~OperationCondition() 0028 { 0029 if(m_value != nullptr) 0030 { 0031 delete m_value; 0032 m_value= nullptr; 0033 } 0034 } 0035 BooleanCondition* OperationCondition::getBoolean() const 0036 { 0037 return m_boolean; 0038 } 0039 0040 void OperationCondition::setBoolean(BooleanCondition* boolean) 0041 { 0042 m_boolean= boolean; 0043 } 0044 0045 qint64 OperationCondition::hasValid(Die* b, bool recursive, bool unhighlight) const 0046 { 0047 if(nullptr == m_boolean) 0048 { 0049 return 0; 0050 } 0051 QList<qint64> listValues; 0052 if(recursive) 0053 { 0054 listValues= b->getListValue(); 0055 } 0056 else 0057 { 0058 listValues.append(b->getLastRolledValue()); 0059 } 0060 0061 qint64 sum= 0; 0062 for(qint64& value : listValues) 0063 { 0064 switch(m_operator) 0065 { 0066 case Dice::ConditionOperator::Modulo: 0067 { 0068 Die die; 0069 die.setMaxValue(b->getMaxValue()); 0070 auto valueScalar= valueToScalar(); 0071 if(valueScalar == 0) 0072 valueScalar= 1; 0073 die.insertRollValue(value % valueScalar); 0074 sum+= m_boolean->hasValid(&die, recursive, false) ? 1 : 0; 0075 } 0076 break; 0077 } 0078 } 0079 if((unhighlight) && (sum == 0)) 0080 { 0081 b->setHighlighted(false); 0082 } 0083 else 0084 { 0085 b->setHighlighted(true); 0086 } 0087 0088 return sum; 0089 } 0090 0091 void OperationCondition::setOperator(Dice::ConditionOperator m) 0092 { 0093 m_operator= m; 0094 } 0095 0096 void OperationCondition::setValueNode(ExecutionNode* node) 0097 { 0098 m_value= node; 0099 } 0100 0101 QString OperationCondition::toString() 0102 { 0103 QString str(""); 0104 switch(m_operator) 0105 { 0106 case Dice::ConditionOperator::Modulo: 0107 str.append(QStringLiteral("\\%")); 0108 break; 0109 } 0110 return QStringLiteral("[%1%2%3]").arg(str).arg(valueToScalar()).arg(m_boolean->toString()); 0111 } 0112 Dice::CONDITION_STATE OperationCondition::isValidRangeSize(const std::pair<qint64, qint64>& range) const 0113 { 0114 Dice::CONDITION_STATE valid= Dice::CONDITION_STATE::REACHABLE; 0115 0116 auto rangeIsClose= (range.first == range.second); 0117 0118 Die die; 0119 die.insertRollValue(range.first); 0120 0121 if(nullptr == m_boolean) 0122 return Dice::CONDITION_STATE::ERROR_STATE; 0123 0124 if(rangeIsClose && m_boolean->hasValid(&die, false, false)) 0125 valid= Dice::CONDITION_STATE::ALWAYSTRUE; 0126 else if(rangeIsClose && !m_boolean->hasValid(&die, false, false)) 0127 valid= Dice::CONDITION_STATE::UNREACHABLE; 0128 0129 return valid; 0130 } 0131 0132 Validator* OperationCondition::getCopy() const 0133 { 0134 OperationCondition* val= new OperationCondition(); 0135 val->setOperator(m_operator); 0136 val->setValueNode(m_value->getCopy()); 0137 BooleanCondition* boolean= dynamic_cast<BooleanCondition*>(m_boolean->getCopy()); 0138 val->setBoolean(boolean); 0139 return val; 0140 } 0141 0142 qint64 OperationCondition::valueToScalar() const 0143 { 0144 if(m_value == nullptr) 0145 return 0; 0146 0147 m_value->run(nullptr); 0148 auto result= m_value->getResult(); 0149 return result->getResult(Dice::RESULT_TYPE::SCALAR).toInt(); 0150 } 0151 0152 const std::set<qint64>& OperationCondition::getPossibleValues(const std::pair<qint64, qint64>& range) 0153 { 0154 if(nullptr == m_boolean) 0155 return m_values; 0156 0157 for(qint64 i= std::min(range.first, range.second); i <= std::max(range.first, range.second); ++i) 0158 { 0159 auto valueScalar= valueToScalar(); 0160 auto val= i % valueScalar; 0161 Die die; 0162 die.insertRollValue(val); 0163 if(m_boolean->hasValid(&die, false, false)) 0164 m_values.insert(i); 0165 } 0166 return m_values; 0167 }