예제 #1
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();
            room->broadcastSkillInvoke(objectName(), 1);
            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();
                wangyi->drawCards(x); //It should be preview, not draw
                ServerPlayer *target = room->askForPlayerChosen(wangyi, room->getAllPlayers(), objectName());

                if (target == wangyi)
                    room->broadcastSkillInvoke(objectName(), 2);
                else if (target->getGeneralName().contains("machao"))
                    room->broadcastSkillInvoke(objectName(), 4);
                else
                    room->broadcastSkillInvoke(objectName(), 3);

                QList<const Card *> miji_cards = wangyi->getHandcards().mid(wangyi->getHandcardNum() - x);
                foreach(const Card *card, miji_cards){
                    CardMoveReason reason(CardMoveReason::S_REASON_GIVE, wangyi->objectName());
                    reason.m_playerId == target->objectName();
                    room->obtainCard(target, card, reason, false);
                }
            }
예제 #2
0
void NosJujianCard::onEffect(const CardEffectStruct &effect) const{
    int n = subcardsLength();
    effect.to->drawCards(n);
    Room *room = effect.from->getRoom();
    room->broadcastSkillInvoke("jujian");

    if(n == 3){
        QSet<Card::CardType> types;

        foreach(int card_id, effect.card->getSubcards()){
            const Card *card = Sanguosha->getCard(card_id);
            types << card->getTypeId();
        }

        if(types.size() == 1){

            LogMessage log;
            log.type = "#JujianRecover";
            log.from = effect.from;
            const Card *card = Sanguosha->getCard(subcards.first());
            log.arg = card->getType();
            room->sendLog(log);

            RecoverStruct recover;
            recover.card = this;
            recover.who = effect.from;
            room->recover(effect.from, recover);
        }
    }
    void onDamaged(ServerPlayer *xiahou, const DamageStruct &damage) const
    {
        ServerPlayer *from = damage.from;
        Room *room = xiahou->getRoom();
        QVariant data = QVariant::fromValue(damage);

        if (room->askForSkillInvoke(xiahou, "neoganglie", data)) {
            room->broadcastSkillInvoke("ganglie");

            JudgeStruct judge;
            judge.pattern = ".|heart";
            judge.good = false;
            judge.reason = objectName();
            judge.who = xiahou;

            room->judge(judge);
            if (!from || from->isDead()) return;
            if (judge.isGood()) {
                QStringList choicelist;
                choicelist << "damage";
                if (from->getHandcardNum() > 1)
                    choicelist << "throw";
                QString choice = room->askForChoice(xiahou, objectName(), choicelist.join("+"));
                if (choice == "damage")
                    room->damage(DamageStruct(objectName(), xiahou, from));
                else
                    room->askForDiscard(from, objectName(), 2, 2);
            }
        }
    }
예제 #4
0
void DelayedTrick::onNullified(ServerPlayer *target) const{
    Room *room = target->getRoom();
    if(movable){
        QList<ServerPlayer *> players = room->getOtherPlayers(target);
        players << target;

        foreach(ServerPlayer *player, players){
            if(player->containsTrick(objectName()))
                continue;

            const ProhibitSkill *skill = room->isProhibited(target, player, this);
            if(skill){
                LogMessage log;
                log.type = "#SkillAvoid";
                log.from = player;
                log.arg = skill->objectName();
                log.arg2 = objectName();
                room->sendLog(log);

                room->broadcastSkillInvoke(skill->objectName());
                continue;
            }

            CardMoveReason reason(CardMoveReason::S_REASON_TRANSFER, target->objectName(), QString(), this->getSkillName(), QString());
            room->moveCardTo(this, target, player, Player::PlaceDelayedTrick, reason, true);
            break;
        }
    }
    else{
예제 #5
0
void NeoFanjianCard::onEffect(const CardEffectStruct &effect) const{
    ServerPlayer *zhouyu = effect.from;
    ServerPlayer *target = effect.to;
    Room *room = zhouyu->getRoom();

    room->broadcastSkillInvoke("fanjian");
    const Card *card = Sanguosha->getCard(getSubcards().first());
    int card_id = card->getEffectiveId();
    Card::Suit suit = room->askForSuit(target, "neofanjian");

    LogMessage log;
    log.type = "#ChooseSuit";
    log.from = target;
    log.arg = Card::Suit2String(suit);
    room->sendLog(log);

    room->getThread()->delay();
    target->obtainCard(this);
    room->showCard(target, card_id);

    if(card->getSuit() != suit){
        DamageStruct damage;
        damage.card = NULL;
        damage.from = zhouyu;
        damage.to = target;

        room->damage(damage);
    }
}
예제 #6
0
const Card *HuanhuoCard::validate(CardUseStruct &card_use) const
{
	ServerPlayer *yuji = card_use.from;
	Room *room = yuji->getRoom();

	QString to_guhuo = user_string;
	if (user_string == "slash"
		&& Sanguosha->currentRoomState()->getCurrentCardUseReason() == CardUseStruct::CARD_USE_REASON_RESPONSE_USE) {
		QStringList guhuo_list;
		guhuo_list << "slash";
		if (!Config.BanPackages.contains("maneuvering"))
			guhuo_list << "normal_slash" << "thunder_slash" << "fire_slash";
		to_guhuo = room->askForChoice(yuji, "guhuo_slash", guhuo_list.join("+"));
	}
	room->broadcastSkillInvoke("crhuanhuo");

	LogMessage log;
	log.type = card_use.to.isEmpty() ? "#HuanhuoNoTarget" : "#Huanhuo";
	log.from = yuji;
	log.to = card_use.to;
	log.arg = to_guhuo;
	log.arg2 = "crhuanhuo";
	room->sendLog(log);

	QString user_str;
	if (to_guhuo == "normal_slash")
		user_str = "slash";
	else
		user_str = to_guhuo;
	Card *use_card = Sanguosha->cloneCard(user_str, Card::NoSuit, 0);
	use_card->setSkillName("crhuanhuo");
	use_card->deleteLater();
	return use_card;
}
예제 #7
0
void DelayedTrick::onNullified(ServerPlayer *target) const
{
    Room *room = target->getRoom();
    RoomThread *thread = room->getThread();

    if (movable) {
        QList<ServerPlayer *> players = room->getOtherPlayers(target);
        players << target;
        ServerPlayer *next = NULL; //next meaning this next one
        bool next2next = false; //it's meaning another next(a second next) is necessary
        foreach (ServerPlayer *player, players) {
            if (player->containsTrick(objectName()))
                continue;

            const ProhibitSkill *skill = room->isProhibited(target, player, this);
            if (skill) {
                LogMessage log;
                log.type = "#SkillAvoid";
                log.from = player;
                log.arg = skill->objectName();
                log.arg2 = objectName();
                room->sendLog(log);

                room->broadcastSkillInvoke(skill->objectName());
                continue;
            }

            next = player;
            CardMoveReason reason(CardMoveReason::S_REASON_TRANSFER, target->objectName(), QString(), getSkillName(), QString());
            room->moveCardTo(this, target, player, Player::PlaceDelayedTrick, reason, true);
            if (target == player)
                break;

            CardUseStruct use;
            use.from = NULL;
            use.to << player;
            use.card = this;
            QVariant data = QVariant::fromValue(use);
            thread->trigger(TargetConfirming, room, data);
            CardUseStruct new_use = data.value<CardUseStruct>();
            if (new_use.to.isEmpty()) {
                next2next = true;
                break;
            }

            thread->trigger(TargetConfirmed, room, data);
            break;
        }
        //case:stop.
        if (!next) {
            CardMoveReason reason(CardMoveReason::S_REASON_TRANSFER, target->objectName(), QString(), getSkillName(), QString());
            room->moveCardTo(this, target, target, Player::PlaceDelayedTrick, reason, true);
        }
        //case: next2next
        if (next && next2next)
            onNullified(next);
    } else {
예제 #8
0
 virtual bool onPhaseChange(ServerPlayer *gongsun) const{
     Room *room = gongsun->getRoom();
     if(gongsun->getPhase() == Player::Finish && gongsun->askForSkillInvoke(objectName())){
         gongsun->drawCards(2);
         room->broadcastSkillInvoke("zhulou", qrand() % 2 + 1);
         if(!room->askForCard(gongsun, ".Weapon", "@zhulou-discard", QVariant(), CardDiscarded))
             room->loseHp(gongsun);
     }
     return false;
 }
예제 #9
0
    virtual bool trigger(TriggerEvent, Room* room, ServerPlayer *player, QVariant &data) const{
        CardEffectStruct effect = data.value<CardEffectStruct>();

        if(effect.to == effect.from)
            return false;

        if(effect.card->getTypeId() == Card::Trick){
            Room *room = player->getRoom();

            if((effect.from && effect.from->hasSkill(objectName()))){
                LogMessage log;
                log.type = "#WuyanBaD";
                log.from = effect.from;
                log.to << effect.to;
                log.arg = effect.card->objectName();
                log.arg2 = objectName();

                room->sendLog(log);

                room->broadcastSkillInvoke("wuyan");

                return true;
            }

            if(effect.to->hasSkill(objectName()) && effect.from){
                LogMessage log;
                log.type = "#WuyanGooD";
                log.from = effect.to;
                log.to << effect.from;
                log.arg = effect.card->objectName();
                log.arg2 = objectName();

                room->sendLog(log);

                room->broadcastSkillInvoke("wuyan");

                return true;
            }
        }

        return false;
    }
예제 #10
0
    virtual void onDamaged(ServerPlayer *guojia, const DamageStruct &damage) const{
        Room *room = guojia->getRoom();

        room->broadcastSkillInvoke(objectName());
        int n = damage.damage * 3;
        guojia->drawCards(n);
        QList<int> yiji_cards = guojia->handCards().mid(guojia->getHandcardNum() - n);

        while(room->askForYiji(guojia, yiji_cards))
            ; // empty loop
    }
 bool onPhaseChange(ServerPlayer *gongsun) const
 {
     Room *room = gongsun->getRoom();
     if (gongsun->getPhase() == Player::Finish && gongsun->askForSkillInvoke(this)) {
         gongsun->drawCards(2);
         room->broadcastSkillInvoke("zhulou");
         if (!room->askForCard(gongsun, ".Weapon", "@zhulou-discard"))
             room->loseHp(gongsun);
     }
     return false;
 }
예제 #12
0
    virtual void onDamaged(ServerPlayer *caocao, const DamageStruct &damage) const{
        Room *room = caocao->getRoom();
        const Card *card = damage.card;
        if(card && room->getCardPlace(card->getEffectiveId()) == Player::PlaceTable){

            QVariant data = QVariant::fromValue(card);
            if(room->askForSkillInvoke(caocao, "jianxiong", data)){
            room->broadcastSkillInvoke(objectName());
                caocao->obtainCard(card);
            }
        }
    }
예제 #13
0
void DelayedTrick::onNullified(ServerPlayer *target) const
{
    Room *room = target->getRoom();
    RoomThread *thread = room->getThread();
    if (movable) {
        QList<ServerPlayer *> players = room->getOtherPlayers(target);
        players << target;
        ServerPlayer *p = NULL;

        foreach (ServerPlayer *player, players) {
            if (player->containsTrick(objectName()))
                continue;

            const ProhibitSkill *skill = room->isProhibited(target, player, this);
            if (skill) {
                if (skill->isVisible()) {
                    LogMessage log;
                    log.type = "#SkillAvoid";
                    log.from = player;
                    log.arg = skill->objectName();
                    log.arg2 = objectName();
                    room->sendLog(log);

                    room->broadcastSkillInvoke(skill->objectName());
                }
                continue;
            }

            CardMoveReason reason(CardMoveReason::S_REASON_TRANSFER, target->objectName(), QString(), this->getSkillName(), QString());
            room->moveCardTo(this, target, player, Player::PlaceDelayedTrick, reason, true);

            if (target == player) break;

            CardUseStruct use;
            use.from = NULL;
            use.to << player;
            use.card = this;
            QVariant data = QVariant::fromValue(use);
            thread->trigger(TargetConfirming, room, player, data);
            CardUseStruct new_use = data.value<CardUseStruct>();
            if (new_use.to.isEmpty()) {
                p = player;
                break;
            }

            foreach(ServerPlayer *p, room->getAllPlayers())
                thread->trigger(TargetConfirmed, room, p, data);
            break;
        }
        if (p)
            onNullified(p);
    } else {
예제 #14
0
    virtual bool onPhaseChange(ServerPlayer *target) const{
        if(target->getPhase() == Player::Finish){
            Room *room = target->getRoom();
            if(room->askForSkillInvoke(target, objectName())){
                target->drawCards(2 + target->getLostHp());
                target->turnOver();

                room->broadcastSkillInvoke("jushou");
            }
        }

        return false;
    }
 void onDamaged(ServerPlayer *target, const DamageStruct &damage) const
 {
     Room *room = target->getRoom();
     for (int i = 1; i <= damage.damage; i++) {
         ServerPlayer *current = room->getCurrent();
         if (!current || current->isDead() || current->getPhase() == Player::NotActive)
             break;
         if (room->askForSkillInvoke(target, objectName(), QVariant::fromValue(current))) {
             room->broadcastSkillInvoke(objectName());
             room->addPlayerMark(current, "@hengjiang");
         }
     }
 }
예제 #16
0
 virtual bool onPhaseChange(ServerPlayer *ganfuren) const{
     Room *room = ganfuren->getRoom();
     if (ganfuren->getPhase() != Player::Start || ganfuren->isKongcheng())
         return false;
     if (room->askForSkillInvoke(ganfuren, objectName())) {
         // As the cost, if one of her handcards cannot be throwed, the skill is unable to invoke
         foreach (const Card *card, ganfuren->getHandcards()) {
             if (ganfuren->isJilei(card))
                 return false;
         }
         //==================================
         int handcard_num = ganfuren->getHandcardNum();
         room->broadcastSkillInvoke(objectName());
         ganfuren->throwAllHandCards();
         if (handcard_num >= ganfuren->getHp())
             room->recover(ganfuren, RecoverStruct(ganfuren));
     }
    bool onPhaseChange(ServerPlayer *player) const
    {
        if (player->getPhase() != Player::Draw)  return false;
        Room *room = player->getRoom();
        QList<ServerPlayer *> players = room->getOtherPlayers(player);
        bool has_frantic = player->getMark("@frantic") > 0;
        room->broadcastSkillInvoke(objectName());

        if (has_frantic) {
            foreach (ServerPlayer *target, players) {
                if (target->getCards("he").length() == 0)
                    continue;
                int card_id = room->askForCardChosen(player, target, "he", objectName());
                room->obtainCard(player, card_id, room->getCardPlace(card_id) != Player::PlaceHand);
            }
            return true;
        } else {
예제 #18
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();
    }
예제 #19
0
    const Card *onRetrial(ServerPlayer *player, JudgeStruct *judge) const
    {
        QStringList prompt_list;
        prompt_list << "@guidao-card" << judge->who->objectName()
            << objectName() << judge->reason << QString::number(judge->card->getEffectiveId());
        QString prompt = prompt_list.join(":");

        Room *room = player->getRoom();

        const Card *card = room->askForCard(player, ".|black", prompt, QVariant::fromValue(judge), Card::MethodResponse, judge->who, true);

        if (card != NULL) {
            int index = qrand() % 2 + 1;
            if (Player::isNostalGeneral(player, "zhangjiao"))
                index += 2;
            room->broadcastSkillInvoke(objectName(), index);
        }

        return card;
    }
예제 #20
0
    virtual bool onPhaseChange(ServerPlayer *target) const{
        Room *room = target->getRoom();
        if (target->getPhase() == Player::Finish && target->isWounded() && target->askForSkillInvoke(objectName())) {
            room->broadcastSkillInvoke(objectName(), 1);
            QStringList draw_num;
            for (int i = 1; i <= target->getLostHp(); draw_num << QString::number(i++)) {}
            int num = room->askForChoice(target, "miji_draw", draw_num.join("+")).toInt();
            target->drawCards(num, objectName());

            if (!target->isKongcheng()) {
                int n = 0;
                forever {
                    int original_handcardnum = target->getHandcardNum();
                    if (n < num && !target->isKongcheng()) {
                        QList<int> handcards = target->handCards();
                        if (!room->askForYiji(target, handcards, objectName(), false, false, false, num - n))
                            break;
                        n += original_handcardnum - target->getHandcardNum();
                    } else {
                        break;
                    }
                }
                // give the rest cards randomly
                if (n < num && !target->isKongcheng()) {
                    int rest_num = num - n;
                    forever {
                        QList<int> handcard_list = target->handCards();
                        qShuffle(handcard_list);
                        int give = qrand() % rest_num + 1;
                        rest_num -= give;
                        QList<int> to_give = handcard_list.length() < give ? handcard_list : handcard_list.mid(0, give);
                        ServerPlayer *receiver = room->getOtherPlayers(target).at(qrand() % (target->aliveCount() - 1));
                        DummyCard *dummy = new DummyCard;
                        foreach (int id, to_give)
                            dummy->addSubcard(id);
                        room->obtainCard(receiver, dummy, false);
                        delete dummy;
                        if (rest_num == 0 || target->isKongcheng())
                            break;
                    }
                }
예제 #21
0
const Card *HuanhuoCard::validateInResponse(ServerPlayer *yuji) const
{
	Room *room = yuji->getRoom();
	room->broadcastSkillInvoke("crhuanhuo");

	QString to_guhuo;
	if (user_string == "peach+analeptic") {
		QStringList guhuo_list;
		guhuo_list << "peach";
		if (!Config.BanPackages.contains("maneuvering"))
			guhuo_list << "analeptic";
		to_guhuo = room->askForChoice(yuji, "crhuanhuo_saveself", guhuo_list.join("+"));
	}
	else if (user_string == "slash") {
		QStringList guhuo_list;
		guhuo_list << "slash";
		if (!Config.BanPackages.contains("maneuvering"))
			guhuo_list << "normal_slash" << "thunder_slash" << "fire_slash";
		to_guhuo = room->askForChoice(yuji, "crhuanhuo_slash", guhuo_list.join("+"));
	}
	else
		to_guhuo = user_string;

	LogMessage log;
	log.type = "#crhuanhuoNoTarget";
	log.from = yuji;
	log.arg = to_guhuo;
	log.arg2 = "crhuanhuo";
	room->sendLog(log);

	QString user_str;
	if (to_guhuo == "normal_slash")
		user_str = "slash";
	else
		user_str = to_guhuo;
	Card *use_card = Sanguosha->cloneCard(user_str, Card::NoSuit, 0);
	use_card->setSkillName("crhuanhuo");
	use_card->deleteLater();
	return use_card;
}
예제 #22
0
    virtual void onDamaged(ServerPlayer *xiahou, const DamageStruct &damage) const{
        ServerPlayer *from = damage.from;
        Room *room = xiahou->getRoom();
        QVariant source = QVariant::fromValue(from);

        if(from && from->isAlive() && room->askForSkillInvoke(xiahou, "neoganglie", source)){
            room->broadcastSkillInvoke("ganglie");

            JudgeStruct judge;
            judge.pattern = QRegExp("(.*):(heart):(.*)");
            judge.good = false;
            judge.reason = objectName();
            judge.who = xiahou;

            room->judge(judge);
            if(judge.isGood()){
                QStringList choicelist;
                choicelist << "damage";
                if (from->getHandcardNum() > 1)
                    choicelist << "throw";
                QString choice;
                if (choicelist.length() == 1)
                    choice = choicelist.first();
                else
                    choice = room->askForChoice(xiahou, "neoganglie", choicelist.join("+"));
                if(choice == "damage"){
                    DamageStruct damage;
                    damage.from = xiahou;
                    damage.to = from;

                    room->setEmotion(xiahou, "good");
                    room->damage(damage);
                }
                else
                     room->askForDiscard(from, objectName(), 2, 2);
            }else
                room->setEmotion(xiahou, "bad");
        }
    }
예제 #23
0
void ShushenCard::onEffect(const CardEffectStruct &effect) const{
    Room *room = effect.to->getRoom();
    room->broadcastSkillInvoke("shushen", effect.to->getGeneralName().contains("liubei") ? 2 : 1);
    effect.to->drawCards(1);
}