void Manager::handleDiscardRequest(ValueEvent<DiscardRequestMsg>* e) { Seat* s = seat(e->value().seat()); std::vector<Card> cards; for (auto c : e->value().card()) { cards.push_back(c); } if (mStatus != DiscardWait) { notifyDiscardFail(s, cards, ErrorCode::StatusError); return; } if (mPerformer != s) { notifyDiscardFail(s, cards, ErrorCode::PerformerError); return; } CardContainer res; bool isMax = false; try { isMax = mChecker->discard(mRes, s, cards, res); } catch (Exception& excp) { if (excp.code() == ErrorCode::ThrowFail) { mStatus = ThrowFail; mRes.putThrowFail(s->id(), res); } notifyDiscardFail(s, cards, excp.code()); return; } DiscardActionMsg m; m.set_seat(s->seat()); m.set_max(isMax); m.set_reason(DiscardActionMsg::Normal); m.set_order(mRes.resNumber()); m.set_score(0); mRes.put(s->seat(), res, isMax); if (mRes.resNumber() == 0) { mPerformer = seat(mRes.lastCircle().max()->seat); if ((mPerformer->id() & 1) != (mDealer & 1)) { int score = mRes.lastCircle().score(); if (score > 0) { mRes.addScore(score); m.set_score(score); } } } else { mPerformer = mPerformer->next(); } m << cards; notifyDiscardAction(m); if (mRes.resCnt() == 100) { mStatus = DiscardFinish; std::vector<Card> b; mGen.getBottom(b); Seat* s = seat(mRes.lastCircle().max()->seat); int score = 0; int factor = 0; if ((s->id() & 1) != (mDealer & 1)) { const CardContainer& cc = mRes.lastCircle().max()->cards; if (mOpt.slaveCanCatchBottom || cc.mask().hasOnlySuit() == CardMask::Master) { for (auto& i : b) { score += i.score(); } factor = cc.factor(); if (mOpt.doubleBottomScore) { factor <<= 1; } mRes.addScore(score * factor); } } mPerformer = NULL; notifyDiscardFinish(mRes, score, factor); } else { mStatus = DiscardNotify; } }