File indexing completed on 2024-05-12 05:39:27

0001 #include "explodedicenode.h"
0002 #include "diceparser/parsingtoolbox.h"
0003 #include "validatorlist.h"
0004 
0005 ExplodeDiceNode::ExplodeDiceNode() : m_diceResult(new DiceResult())
0006 {
0007     m_result= m_diceResult;
0008 }
0009 void ExplodeDiceNode::run(ExecutionNode* previous)
0010 {
0011     m_previousNode= previous;
0012     if(!previous)
0013         return;
0014 
0015     if(!previous->getResult())
0016         return;
0017 
0018     DiceResult* previous_result= dynamic_cast<DiceResult*>(previous->getResult());
0019     m_result->setPrevious(previous_result);
0020 
0021     if(!previous_result)
0022         return;
0023 
0024     for(auto& die : previous_result->getResultList())
0025     {
0026         Die* tmpdie= new Die(*die);
0027         m_diceResult->insertResult(tmpdie);
0028         die->displayed();
0029     }
0030 
0031     qint64 limit= -1;
0032     if(m_limit)
0033     {
0034         m_limit->run(this);
0035         auto limitNode= ParsingToolBox::getLeafNode(m_limit);
0036         auto result= limitNode->getResult();
0037         if(result->hasResultOfType(Dice::RESULT_TYPE::SCALAR))
0038             limit= static_cast<quint64>(result->getResult(Dice::RESULT_TYPE::SCALAR).toInt());
0039     }
0040 
0041     bool hasExploded= false;
0042     std::function<void(Die*, qint64)> f= [&hasExploded, this, limit](Die* die, qint64)
0043     {
0044         static QHash<Die*, qint64> explodePerDice;
0045         if(Dice::CONDITION_STATE::ALWAYSTRUE
0046            == m_validatorList->isValidRangeSize(std::make_pair<qint64, qint64>(die->getBase(), die->getMaxValue())))
0047         {
0048             m_errors.insert(Dice::ERROR_CODE::ENDLESS_LOOP_ERROR,
0049                             QObject::tr("Condition (%1) cause an endless loop with this dice: %2")
0050                                 .arg(toString(true))
0051                                 .arg(QStringLiteral("d[%1,%2]")
0052                                          .arg(static_cast<int>(die->getBase()))
0053                                          .arg(static_cast<int>(die->getMaxValue()))));
0054         }
0055         hasExploded= true;
0056         if(limit >= 0)
0057         {
0058             auto& d= explodePerDice[die];
0059             if(d == limit)
0060             {
0061                 hasExploded= false;
0062                 return;
0063             }
0064             ++d;
0065         }
0066         die->roll(true);
0067     };
0068     do
0069     {
0070         hasExploded= false;
0071         m_validatorList->validResult(m_diceResult, false, false, f);
0072     } while(hasExploded);
0073 
0074     if(nullptr != m_nextNode)
0075     {
0076         m_nextNode->run(this);
0077     }
0078 }
0079 ExplodeDiceNode::~ExplodeDiceNode()
0080 {
0081     if(nullptr != m_validatorList)
0082     {
0083         delete m_validatorList;
0084     }
0085 }
0086 void ExplodeDiceNode::setValidatorList(ValidatorList* val)
0087 {
0088     m_validatorList= val;
0089 }
0090 QString ExplodeDiceNode::toString(bool withlabel) const
0091 {
0092     if(withlabel)
0093     {
0094         return QString("%1 [label=\"ExplodeDiceNode %2\"]").arg(m_id, m_validatorList->toString());
0095     }
0096     else
0097     {
0098         return m_id;
0099     }
0100 }
0101 qint64 ExplodeDiceNode::getPriority() const
0102 {
0103     qint64 priority= 0;
0104     if(nullptr != m_previousNode)
0105     {
0106         priority= m_previousNode->getPriority();
0107     }
0108     return priority;
0109 }
0110 
0111 ExecutionNode* ExplodeDiceNode::getCopy() const
0112 {
0113     ExplodeDiceNode* node= new ExplodeDiceNode();
0114     if(nullptr != m_validatorList)
0115     {
0116         node->setValidatorList(m_validatorList->getCopy());
0117     }
0118     if(nullptr != m_nextNode)
0119     {
0120         node->setNextNode(m_nextNode->getCopy());
0121     }
0122     return node;
0123 }
0124 
0125 void ExplodeDiceNode::setLimitNode(ExecutionNode* limitNode)
0126 {
0127     m_limit= limitNode;
0128 }