bool trigger(TriggerEvent triggerEvent, Room *room, ServerPlayer *player, QVariant &data) const
    {
        if (triggerEvent == TurnStart) {
            room->setPlayerMark(player, "@hengjiang", 0);
        } else if (triggerEvent == CardsMoveOneTime) {
            CardsMoveOneTimeStruct move = data.value<CardsMoveOneTimeStruct>();
            if (move.from && player == move.from && player->getPhase() == Player::Discard
                && (move.reason.m_reason & CardMoveReason::S_MASK_BASIC_REASON) == CardMoveReason::S_REASON_DISCARD)
                player->setFlags("HengjiangDiscarded");
        } else if (triggerEvent == EventPhaseChanging) {
            PhaseChangeStruct change = data.value<PhaseChangeStruct>();
            if (change.to != Player::NotActive) return false;
            ServerPlayer *zangba = room->findPlayerBySkillName("hengjiang");
            if (!zangba) return false;
            if (player->getMark("@hengjiang") > 0) {
                bool invoke = false;
                if (!player->hasFlag("HengjiangDiscarded")) {
                    LogMessage log;
                    log.type = "#HengjiangDraw";
                    log.from = player;
                    log.to << zangba;
                    log.arg = "hengjiang";
                    room->sendLog(log);

                    invoke = true;
                }
                player->setFlags("-HengjiangDiscarded");
                room->setPlayerMark(player, "@hengjiang", 0);
                if (invoke) zangba->drawCards(1, objectName());
            }
        }
        return false;
    }
 virtual bool trigger(TriggerEvent , Room *room, ServerPlayer *player, QVariant &data) const{
     RecoverStruct recover_struct = data.value<RecoverStruct>();
     int recover = recover_struct.recover;
     for (int i = 0; i < recover; i++) {
         ServerPlayer *target = room->askForPlayerChosen(player, room->getOtherPlayers(player), objectName(), "shushen-invoke", true, true);
         if (target) {
             room->broadcastSkillInvoke(objectName(), target->getGeneralName().contains("liubei") ? 2 : 1);
             target->drawCards(1);
         } else {
             break;
         }
     }
     return false;
 }
 bool trigger(TriggerEvent, Room *room, ServerPlayer *player, QVariant &data) const
 {
     RecoverStruct recover_struct = data.value<RecoverStruct>();
     int recover = recover_struct.recover;
     for (int i = 0; i < recover; i++) {
         ServerPlayer *target = room->askForPlayerChosen(player, room->getOtherPlayers(player), objectName(), "shushen-invoke", true, true);
         if (target) {
             room->broadcastSkillInvoke(objectName(), target->getGeneralName().contains("liubei") ? 2 : 1);
             if (target->isWounded() && room->askForChoice(player, objectName(), "recover+draw", QVariant::fromValue(target)) == "recover")
                 room->recover(target, RecoverStruct(player));
             else
                 target->drawCards(2, objectName());
         } else {
             break;
         }
     }
     return false;
 }
    virtual void onDamaged(ServerPlayer *huaxiong, const DamageStruct &damage) const{
        ServerPlayer *from = damage.from;
        Room *room = huaxiong->getRoom();

        if(from && from->isAlive() && damage.card && damage.card->isKindOf("Slash") && damage.card->isRed()){
            room->playSkillEffect(objectName());
            LogMessage log;
            log.from = huaxiong;
            log.arg = objectName();
            log.type = "#TriggerSkill";
            room->sendLog(log);

            if(from->isWounded())
                room->recover(from, RecoverStruct(), true);
            else
                from->drawCards(1);
        }
    }
    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 bool trigger(TriggerEvent, Room *room, ServerPlayer *player, QVariant &) const{
     if (player->getPhase() != Player::Finish)
         return false;
     ServerPlayer *yuejin = room->findPlayerBySkillName(objectName());
     if (!yuejin || yuejin == player)
         return false;
     if (yuejin->canDiscard(yuejin, "h") && room->askForCard(yuejin, ".Basic", "@xiaoguo", QVariant(), objectName())) {
         room->broadcastSkillInvoke(objectName(), 1);
         if (!room->askForCard(player, ".Equip", "@xiaoguo-discard", QVariant())) {
             room->broadcastSkillInvoke(objectName(), 2);
             room->damage(DamageStruct("xiaoguo", yuejin, player));
         } else {
             room->broadcastSkillInvoke(objectName(), 3);
             if (yuejin->isAlive())
                 yuejin->drawCards(1, objectName());
         }
     }
     return false;
 }