virtual bool onPhaseChange(ServerPlayer *zhangliang) const{ Room *room = zhangliang->getRoom(); if(zhangliang->getPhase() != Player::Draw) return false; QList<ServerPlayer *> players = room->getOtherPlayers(zhangliang); foreach(ServerPlayer *p, players){ if(p->isKongcheng()) players.removeOne(p); } if(players.isEmpty() || !zhangliang->askForSkillInvoke(objectName())) return false; room->playSkillEffect(objectName()); ServerPlayer *rengonger = room->askForPlayerChosen(zhangliang, players, objectName()); QList<int> handcards = rengonger->handCards(); room->fillAG(handcards, zhangliang); int card_id = room->askForAG(zhangliang, handcards, false, objectName()); room->moveCardTo(Sanguosha->getCard(card_id), zhangliang, Player::Hand, false); room->broadcastInvoke("clearAG"); return true; }
const Card *WuxinCard::validate(CardUseStruct &cardUse) const{ QList<int> skysoldier = cardUse.from->getPile("skysoldier"); QList<int> black_skysoldier, disabled_skysoldier; foreach(int id, skysoldier){ if (Sanguosha->getCard(id)->isBlack()){ Slash *theslash = new Slash(Card::SuitToBeDecided, -1); theslash->setSkillName("wuxin"); theslash->addSubcard(id); theslash->deleteLater(); bool can_slash = theslash->isAvailable(cardUse.from) && theslash->targetsFeasible(ServerPlayerList2PlayerList(cardUse.to), cardUse.from); if (can_slash) black_skysoldier << id; else disabled_skysoldier << id; } else disabled_skysoldier << id; } if (black_skysoldier.isEmpty()) return NULL; Room *room = cardUse.from->getRoom(); room->fillAG(skysoldier, cardUse.from, disabled_skysoldier); int slash_id = room->askForAG(cardUse.from, black_skysoldier, false, "wuxin"); room->clearAG(cardUse.from); Slash *slash = new Slash(Card::SuitToBeDecided, -1); slash->addSubcard(slash_id); slash->setSkillName("wuxin"); return slash; }
static void Exchange(ServerPlayer *shenzhuge){ QList<int> &stars = shenzhuge->getPile("stars"); if(stars.isEmpty()) return; Room *room = shenzhuge->getRoom(); room->fillAG(stars, shenzhuge); int ai_delay = Config.AIDelay; Config.AIDelay = 0; QList<int> to_exchange; while(!stars.isEmpty()){ int card_id = room->askForAG(shenzhuge, stars, true, "qixing"); if(card_id == -1) break; stars.removeOne(card_id); to_exchange << card_id; const Card *card = Sanguosha->getCard(card_id); shenzhuge->addCard(card, Player::Hand); room->setCardMapping(card_id, shenzhuge, Player::Hand); QString take_str = QString("%1:%2").arg(shenzhuge->objectName()).arg(card_id); shenzhuge->invoke("takeAG", take_str); shenzhuge->invoke("pile", QString("%1:stars-%2").arg(shenzhuge->objectName()).arg(card_id)); } Config.AIDelay = ai_delay; shenzhuge->invoke("clearAG"); if(to_exchange.isEmpty()) return; int n = to_exchange.length(); const Card *exchange_card = room->askForExchange(shenzhuge, "qixing", n); foreach(int card_id, exchange_card->getSubcards()){ shenzhuge->invoke("pile", QString("%1:stars+%2").arg(shenzhuge->objectName()).arg(card_id)); } LogMessage log; log.type = "#QixingExchange"; log.from = shenzhuge; log.arg = QString::number(n); room->sendLog(log); room->moveCardTo(exchange_card, shenzhuge, Player::Special, false); stars.append(exchange_card->getSubcards()); delete exchange_card; }
static void DiscardStar(ServerPlayer *shenzhuge, int n){ Room *room = shenzhuge->getRoom(); QList<int> &stars = shenzhuge->getPile("stars"); room->fillAG(stars, shenzhuge); int i; for(i=0; i<n; i++){ int card_id = room->askForAG(shenzhuge, stars, false, "qixing-discard"); stars.removeOne(card_id); room->throwCard(card_id); shenzhuge->invoke("pile", QString("%1:stars-%2").arg(shenzhuge->objectName()).arg(card_id)); } shenzhuge->invoke("clearAG"); }
virtual bool onPhaseChange(ServerPlayer *wangyi) const{ if(!wangyi->isWounded()) return false; if(wangyi->getPhase() == Player::Start || wangyi->getPhase() == Player::Finish){ if(!wangyi->askForSkillInvoke(objectName())) return false; Room *room = wangyi->getRoom(); JudgeStruct judge; judge.pattern = QRegExp("(.*):(club|spade):(.*)"); judge.good = true; judge.reason = objectName(); judge.who = wangyi; room->judge(judge); if(judge.isGood()){ int x = wangyi->getLostHp(); LogMessage log; log.type = "#WatchNCards"; log.from = wangyi; log.arg = QString::number(x); room->sendLog(log); room->playSkillEffect(objectName()); QList<int> miji_cards = room->getNCards(x, false); room->fillAG(miji_cards, wangyi); room->askForAG(wangyi, miji_cards, true, objectName()); room->broadcastInvoke("clearAG"); room->addToDrawPile(miji_cards); ServerPlayer *target = room->askForPlayerChosen(wangyi, room->getAllPlayers(), objectName()); log.type = "#Miji"; log.arg = objectName(); log.to << target; room->sendLog(log); target->drawCards(x, false); } } return false; }
virtual void onDamaged(ServerPlayer *target, const DamageStruct &damage) const{ Room *room = target->getRoom(); if (!target->askForSkillInvoke(objectName(), QVariant::fromValue(damage))) return; room->broadcastSkillInvoke(objectName()); QList<int> card_ids = room->getNCards(4); room->fillAG(card_ids); QList<int> to_get, to_throw; while (true) { int sum = 0; foreach (int id, to_get) sum += Sanguosha->getCard(id)->getNumber(); foreach (int id, card_ids) { if (sum + Sanguosha->getCard(id)->getNumber() >= 13) { room->takeAG(NULL, id, false); card_ids.removeOne(id); to_throw << id; } } if (card_ids.isEmpty()) break; int card_id = room->askForAG(target, card_ids, card_ids.length() < 4, objectName()); if (card_id == -1) break; card_ids.removeOne(card_id); to_get << card_id; room->takeAG(target, card_id, false); if (card_ids.isEmpty()) break; } DummyCard *dummy = new DummyCard; if (!to_get.isEmpty()) { dummy->addSubcards(to_get); target->obtainCard(dummy); } dummy->clearSubcards(); if (!to_throw.isEmpty() || !card_ids.isEmpty()) { dummy->addSubcards(to_throw + card_ids); CardMoveReason reason(CardMoveReason::S_REASON_NATURAL_ENTER, target->objectName(), objectName(), QString()); room->throwCard(dummy, reason, NULL); } delete dummy; room->clearAG(); }
void GameRule::onPhaseChange(ServerPlayer *player) const{ Room *room = player->getRoom(); switch(player->getPhase()){ case Player::RoundStart:{ break; } case Player::Start: { player->setMark("SlashCount", 0); if(room->getMode() == "05_2v3") if(player->isLord() || player->getRole() == "loyalist"){ int card_id = room->drawCard(); room->showCard(player, card_id); room->getThread()->delay(); player->addToPile("Angers", card_id); LogMessage log; log.type = "$Juqi"; log.from = player; log.card_str = QString::number(card_id); room->sendLog(log); if(player->getPile("Angers").length() > 4){ const QList<int> angs = player->getPile("Angers"); room->fillAG(angs, player); int card_id = room->askForAG(player, angs, false, "cbangercollect"); if(card_id < 0) card_id = player->getPile("Angers").first(); room->throwCard(card_id); player->invoke("clearAG"); } } break; } case Player::Judge: { QList<const DelayedTrick *> tricks = player->delayedTricks(); while(!tricks.isEmpty() && player->isAlive()){ const DelayedTrick *trick = tricks.takeLast(); bool on_effect = room->cardEffect(trick, NULL, player); if(!on_effect) trick->onNullified(player); } break; } case Player::Draw: { QVariant num = 2; if(room->getTag("FirstRound").toBool()){ room->setTag("FirstRound", false); if(room->getMode() == "02_1v1") num = 1; } room->getThread()->trigger(DrawNCards, player, num); int n = num.toInt(); if(n > 0) player->drawCards(n, false); room->getThread()->trigger(DrawNCardsDone, player, num); break; } case Player::Play: { player->clearHistory(); while(player->isAlive()){ CardUseStruct card_use; room->activate(player, card_use); if(card_use.isValid()){ room->useCard(card_use); }else break; } break; } case Player::Discard:{ int discard_num = player->getHandcardNum() - player->getMaxCards(); if(player->hasFlag("jilei")){ QSet<const Card *> jilei_cards; QList<const Card *> handcards = player->getHandcards(); foreach(const Card *card, handcards){ if(player->isJilei(card)) jilei_cards << card; } if(jilei_cards.size() > player->getMaxCards()){ // show all his cards room->showAllCards(player); DummyCard *dummy_card = new DummyCard; foreach(const Card *card, handcards.toSet() - jilei_cards){ dummy_card->addSubcard(card); } room->throwCard(dummy_card, player); return; } } if(discard_num > 0) room->askForDiscard(player, "gamerule", discard_num); break; }
virtual bool trigger(TriggerEvent event, ServerPlayer *jim, QVariant &data) const{ Room *room = jim->getRoom(); if(event == Dying){ if(jim && jim->askForSkillInvoke(objectName(), data)){ room->playSkillEffect("juesi"); int x = jim->getMaxHP(); if(x > 4) x = 4; bool has_duplicate = false; bool maxhp_increased = false; bool has_second_duplicate = false; bool survived = false; QList<int> card_ids = room->getNCards(x); int i, j; for(i=0; i < card_ids.length(); i++){ for(j=i+1; j < card_ids.length(); j++){ const Card *card = Sanguosha->getCard(card_ids.at(i)); if(card->sameColorWith( Sanguosha->getCard(card_ids.at(j)) )){ has_duplicate = true; } } } qSort(card_ids.begin(), card_ids.end(), CompareBySuit); room->fillAG(card_ids); if(has_duplicate) if(room->askForChoice(jim, "juesi", "maxhp+cancel") == "maxhp"){ int card_id = room->askForAG(jim, card_ids, false, "juesi"); card_ids.removeOne(card_id); room->takeAG(NULL, card_id); int card_id2 = room->askForAG(jim, card_ids, false, "juesi"); card_ids.removeOne(card_id2); room->takeAG(NULL, card_id2); if(Sanguosha->getCard(card_id)->sameColorWith(Sanguosha->getCard(card_id2))){ room->setPlayerProperty(jim, "maxhp", jim->getMaxHP() + 1); maxhp_increased = true; } } for(i=0; i < card_ids.length(); i++){ for(j=i+1; j < card_ids.length(); j++){ const Card *card = Sanguosha->getCard(card_ids.at(i)); if(card->sameColorWith( Sanguosha->getCard(card_ids.at(j)) )){ has_second_duplicate = true; } } } if(maxhp_increased && has_second_duplicate) if(room->askForChoice(jim, "juesi", "hp+cancel") == "hp"){ int card_id = room->askForAG(jim, card_ids, false, "juesi"); card_ids.removeOne(card_id); room->takeAG(NULL, card_id); int card_id2 = room->askForAG(jim, card_ids, false, "juesi"); card_ids.removeOne(card_id2); room->takeAG(NULL, card_id2); if(Sanguosha->getCard(card_id)->sameColorWith(Sanguosha->getCard(card_id2))){ RecoverStruct recover; recover.who = jim; room->recover(jim, recover); if(jim->getHp()>0) survived = true; } } if(survived){ foreach(int card_id, card_ids){ room->takeAG(jim, card_id); } }else{