88 *
99 * Dice! QQ Dice Robot for TRPG
1010 * Copyright (C) 2018-2021 w4123溯洄
11- * Copyright (C) 2019-2024 String.Empty
11+ * Copyright (C) 2019-2025 String.Empty
1212 *
1313 * This program is free software: you can redistribute it and/or modify it under the terms
1414 * of the GNU Affero General Public License as published by the Free Software Foundation,
@@ -540,11 +540,9 @@ std::string RD::FormStringCombined() const
540540 {
541541 strReturnString.append (
542542 vboolNegative[distance (vintRes.begin (), i)] ? " -" : (i == vintRes.begin () ? " " : " +" ));
543- if (*i < 0 && i != vintRes.begin ())
544- strReturnString.append (" (" );
543+ // if (*i < 0 && i != vintRes.begin()) strReturnString.append("(");
545544 strReturnString.append (std::to_string (*i));
546- if (*i < 0 && i != vintRes.begin ())
547- strReturnString.append (" )" );
545+ // if (*i < 0 && i != vintRes.begin()) strReturnString.append(")");
548546 }
549547 return strReturnString;
550548}
@@ -620,30 +618,40 @@ DicePool::DicePool(const std::string& expr, const int target) :RD(expr, 10), nTa
620618 }
621619 if (const int intRDRes = cntDice (strDice.substr (intReadDiceLoc)))
622620 err = intRDRes;
621+ vboolNegative.clear ();
623622}
624623int_errno DicePool::cntDice (std::string& dice) {
625- std::string strDiceCnt = dice.substr (0 , dice.find ( ' a ' ));
624+ std::string strDiceCnt = dice.substr (0 , dice.find_first_not_of ( " 0123456789 " ));
626625 for (auto i : strDiceCnt)
627626 if (!isdigit (static_cast <unsigned char >(i)))
628627 return DiceCnt_Err;
629628 if (strDiceCnt.length () > 4 )
630629 return DiceTooBig_Err;
631630 int intDiceCnt = stoi (strDiceCnt);
632- if (intDiceCnt == 0 )
633- return ZeroDice_Err;
634- if (*(vboolNegative.end () - 1 ))nDiceCnt -= intDiceCnt;
635- else nDiceCnt += intDiceCnt;
636- // AddVal
637- std::string strAddVal = dice.substr (dice.find (' a' ) + 1 );
638- if (strAddVal.length () > 2 )
639- return AddDiceVal_Err;
640- for (auto i : strAddVal)
641- if (!isdigit (static_cast <unsigned char >(i)))
642- return Input_Err;
643- if (!strAddVal.empty ()) {
644- nDiceAdd = stoi (strAddVal);
645- if (nDiceAdd < 5 || nDiceAdd > 11 )
631+ if (dice.length () == strDiceCnt.length ()) {
632+ if (*(vboolNegative.end () - 1 ))nExtraVal -= intDiceCnt;
633+ else nExtraVal += intDiceCnt;
634+ }
635+ else {
636+ if (intDiceCnt == 0 )
637+ return ZeroDice_Err;
638+ if (*(vboolNegative.end () - 1 ))nDiceCnt -= intDiceCnt;
639+ else nDiceCnt += intDiceCnt;
640+ // AddVal
641+ if (std::string strAddVal = dice.substr (strDiceCnt.size () + 1 );
642+ strAddVal.length () > 2 ) {
646643 return AddDiceVal_Err;
644+ }
645+ else {
646+ for (auto i : strAddVal)
647+ if (!isdigit (static_cast <unsigned char >(i)))
648+ return Input_Err;
649+ if (!strAddVal.empty ()) {
650+ nDiceAdd = stoi (strAddVal);
651+ if (nDiceAdd < 5 || nDiceAdd > 11 )
652+ return AddDiceVal_Err;
653+ }
654+ }
647655 }
648656 vboolNegative.erase (vboolNegative.end () - 1 );
649657 return 0 ;
@@ -652,13 +660,14 @@ int_errno DicePool::roll(ptr<DiceSession> game) const
652660{
653661 if (err) return err;
654662 if (!nDiceCnt)return ZeroDice_Err;
655- intTotal = 0 ;
663+ intTotal = nExtraVal ;
656664 while (nDiceCnt != 0 ){
657665 std::vector<int > vintTmpRes;
658666 int intTmpRes = 0 ;
659667 vintTmpRes.push_back (nDiceCnt);
660668 int AddNum = 0 ;
661- int intCnt = nDiceCnt;
669+ bool isPos{ nDiceCnt > 0 };
670+ int intCnt = isPos ? nDiceCnt : -nDiceCnt;
662671 while (intCnt--)
663672 {
664673 int intTmpResOnce = RandomGenerator::Randint (1 , 10 );
@@ -669,17 +678,18 @@ int_errno DicePool::roll(ptr<DiceSession> game) const
669678 AddNum++;
670679 }
671680 if (nDiceCnt > 10 )sort (vintTmpRes.end () - nDiceCnt, vintTmpRes.end ());
672- nDiceCnt = AddNum;
673- vvintRes.emplace_back (vintTmpRes);
674- vintRes.emplace_back (intTmpRes);
681+ if (intTmpRes || vintRes.empty ()) {
682+ vboolNegative.emplace_back (!isPos);
683+ vvintRes.emplace_back (vintTmpRes);
684+ vintRes.emplace_back (intTmpRes);
685+ }
686+ nDiceCnt = isPos ? AddNum : -AddNum;
675687 intTotal += intTmpRes;
676688 }
677- // if (boolNegative)
678- // nSuccess -= intTmpRes;
679- // else
680- // nSuccess += intTmpRes;
681- // vBnP.insert(vBnP.begin(), WW_Dice);
682- // vboolNegative.insert(vboolNegative.begin(), boolNegative);
689+ if (nExtraVal) {
690+ vintRes.emplace_back (nExtraVal > 0 ? nExtraVal : -nExtraVal);
691+ vboolNegative.emplace_back (nExtraVal < 0 );
692+ }
683693 return 0 ;
684694}
685695std::string DicePool::FormStringSeparate () const
@@ -737,6 +747,10 @@ std::string DicePool::FormStringSeparate() const
737747 strReturnString.append (" }" );
738748 ++idx;
739749 }
750+ if (nExtraVal > 0 ) {
751+ strReturnString += " +" + std::to_string (nExtraVal);
752+ }
753+ else if (nExtraVal < 0 )strReturnString += std::to_string (nExtraVal);
740754 return strReturnString;
741755}
742756void init (string& msg)
0 commit comments