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;
}
Esempio n. 3
0
    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;
    }
Esempio n. 4
0
    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");
    }
Esempio n. 5
0
    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;
    }
Esempio n. 6
0
    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();
    }
Esempio n. 7
0
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;
        }
Esempio n. 8
0
    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{