int MoQiang::AnZhiZhangBi(CONTEXT_TIMELINE_3 *con)
{   
	int ret;
    CommandRequest cmd_req;
	Coder::askForSkill(id,AN_ZHI_ZHANG_BI, cmd_req);
	//有限等待,由UserTask调用tryNotify唤醒
	if(engine->waitForOne(id, network::MSG_CMD_REQ, cmd_req))
	{
		void* reply;
		if (GE_SUCCESS == (ret = engine->getReply(id, reply)))
		{
			Respond* respond = (Respond*) reply;
			//发动
			if(respond->args(0)==1)     
			{	
				network::SkillMsg skill;
				Coder::skillNotice(id, id,AN_ZHI_ZHANG_BI, skill);
				engine->sendMessage(-1, MSG_SKILL, skill);
				//弃牌
				vector<int> cardIDs;
				int cardNum= respond->card_ids_size();
				int card_id;

			for(int i = 0; i < cardNum; i ++)
				{   
					card_id=respond->card_ids(i);
     if((getCardByID(card_id)->getElement() == ELEMENT_THUNDER||getCardByID(card_id)->getType()==TYPE_MAGIC )&& checkOneHandCard(card_id) == GE_SUCCESS)
					cardIDs.push_back(card_id);
				}
			if(cardNum>0)
			{
				CardMsg show_card;
				Coder::showCardNotice(id, cardIDs.size(), cardIDs, show_card);
				engine->sendMessage(-1, MSG_CARD, show_card);

		        engine->setStateMoveCardsNotToHand(id, DECK_HAND, -1, DECK_DISCARD, cardNum, cardIDs, id,AN_ZHI_ZHANG_BI, true);
				return GE_URGENT;
			}
			else
			{
				return GE_SUCCESS;
			}
				
			}
			//没发动技能
			return GE_SUCCESS;
		}
		return ret;
	}

	else{
		//超时啥都不用做
		return GE_TIMEOUT;
	}
}
void BackgroundEngine::useMagicCard(int cardID, int srcID, int dstID)
{
    CardEntity *magicCard = getCardByID(cardID);
    PlayerEntity *srcPlayer = this->getPlayerByID(srcID);
    PlayerEntity *dstPlayer = this->getPlayerByID(dstID);
    QList<CardEntity*> cards;
    cards << magicCard;


    if(magicCard->getMagicName() == POISONCARD)
    {   
        this->useCard(cards,srcPlayer,dstPlayer,true);

    }
    else if(magicCard->getMagicName() == SHIELDCARD)
    {
        this->useCard(cards,srcPlayer,dstPlayer,true);

    }
    else if(magicCard->getMagicName() == WEAKCARD)
    {
        this->useCard(cards,srcPlayer,dstPlayer,true);

    }
    else if(magicCard->getMagicName() == MISSILECARD)
    {
        this->useCard(cards,srcPlayer,dstPlayer);
        this->missileProcess(magicCard,srcID,dstID);
    }
}
int LingFu::v_magic_skill(Action *action)
{
	int actionID = action->action_id();
	int cardID;
	int playerID = action->src_id();
	CardEntity* card;

	if(playerID != id){
		return GE_INVALID_PLAYERID;
	}

	switch(actionID)
	{
	case FENG_XING:
		cardID = action->card_ids(0);
		card = getCardByID(cardID);
		//不是自己的手牌                          || 不是风系               
		if(GE_SUCCESS != checkOneHandCard(cardID) || ELEMENT_WIND != card->getElement()){
			return GE_INVALID_CARDID;
		}
		if(2 != action->dst_ids_size()){
			return GE_INVALID_PLAYERID;
		}
		break;
	case LEI_MING:
		cardID = action->card_ids(0);
		card = getCardByID(cardID);
		//不是自己的手牌                          || 不是雷系               
		if(GE_SUCCESS != checkOneHandCard(cardID) || ELEMENT_THUNDER != card->getElement()){
			return GE_INVALID_CARDID;
		}
		if(2 != action->dst_ids_size()){
			return GE_INVALID_PLAYERID;
		}
		break;

	default:
		return GE_INVALID_ACTION;
	}
	return GE_SUCCESS;
}
Exemplo n.º 4
0
QList<CardEntity*> messageBuffer::readCardID(int sum)
{
    QList<CardEntity*> cards;
    messageBuffer::cardBufferUsed.acquire(sum);
    for(int i = 0;i < sum;i++)
    {
        cards << getCardByID(messageBuffer::cardBuffer[messageBuffer::cardBufferBottom++]);
        if(messageBuffer::cardBufferBottom >= BUFFERSIZE)
            messageBuffer::cardBufferBottom = 0;
    }
    messageBuffer::cardBufferFree.release(sum);
    return cards;
}
int ShengNv::v_magic_skill(Action *action)
{
	int actionID = action->action_id();
	int cardID;
	int playerID = action->src_id();
	CardEntity* card;

	if(playerID != id){
		return GE_INVALID_PLAYERID;
	}
	switch(actionID)
	{
	case ZHI_LIAO_SHU:
		cardID = action->card_ids(0);
		card = getCardByID(cardID);
		//不是自己的手牌                          || 不是对应的法术牌                
		if(GE_SUCCESS != checkOneHandCard(cardID) || !card->checkSpeciality(actionID)){
			return GE_INVALID_ACTION;
		}
		break;
	case ZHI_YU_ZHI_GUANG:
		cardID = action->card_ids(0);
		card = getCardByID(cardID);
		if(GE_SUCCESS != checkOneHandCard(cardID) || !card->checkSpeciality(actionID) || action->dst_ids_size() < 1 || action->dst_ids_size() > 3){
			return GE_INVALID_ACTION;
		}
		break;
	case SHENG_LIAO:
		if(getEnergy() < 1 || used_ShengLiao){
			return GE_INVALID_ACTION;
		}
		break;
	default:
		return GE_INVALID_ACTION;
	}
	return GE_SUCCESS;
}
//【充盈】
int MoQiang::ChongYing(Action* action)
{

   //检查客户端返回的是否为魔法牌&&雷系牌
	  int cardID = action->card_ids(0);
	  CardEntity* card = getCardByID(cardID);
		if( card->getType() != TYPE_MAGIC&&card->getElement()!=ELEMENT_THUNDER ){
			return GE_SUCCESS;
		}
		cardCount=0;
		used_ChongYing=true;
		SkillMsg skill_msg;
	   //丢弃魔法牌&&雷系牌
		Coder::skillNotice(id, id, CHONG_YING, skill_msg);
		engine->sendMessage(-1, MSG_SKILL, skill_msg);
		CardMsg show_card;
		Coder::showCardNotice(id, 1, cardID, show_card);
		engine->sendMessage(-1, MSG_CARD, show_card);

		//所有移牌操作都要用setStateMoveXXXX,ToHand的话要填好HARM,就算不是伤害
	PlayerEntity* it = this->getPre();
	HARM chongying;
	chongying.cause =CHONG_YING;
	chongying.point = 1;
	chongying.srcID = id;
	chongying.type = HARM_NONE;

	HARM chongying_discard;
	chongying_discard.cause =CHONG_YING_DISCARD;
	chongying_discard.point = 1;
	chongying_discard.srcID = id;
	chongying_discard.type = HARM_NONE;
	
	//先进后出,所以逆出牌顺序压,最后才是魔枪自己明弃法牌
	while(it != this){
		//bool isShown = false, bool canGiveUp = false
		if(it->getColor()!=color)
		engine->pushGameState(new StateRequestHand(it->getID(),chongying, -1, DECK_DISCARD, true, false)); //不能不弃牌
		else
         engine->pushGameState(new StateRequestHand(it->getID(),chongying_discard, -1, DECK_DISCARD, true, true));

		it = it->getPre();
	}
	engine->pushGameState(new StateRequestHand(this->getID(),chongying_discard, -1, DECK_DISCARD, true, true));
	engine->setStateMoveOneCardNotToHand(id, DECK_HAND, -1, DECK_DISCARD, cardID, id, CHONG_YING, true);

	addAction(ACTION_ATTACK,CHONG_YING);
	return GE_URGENT;
}
int MoQiang::ChongYing_Effect(int playerID, int howMany, vector<int> cards, HARM & harm)
{
	if(0 != howMany)
	{
		int cardID = cards[0];
		PlayerEntity* player =engine->getPlayerEntity(playerID);
		CardEntity* card = getCardByID(cardID);
		if((TYPE_MAGIC == card->getType() || ELEMENT_THUNDER == player->getCardElement(cardID)) && playerID != id)
		{
			//harm.point++;
			cardCount++;
		}
	}
	return GE_SUCCESS;
}
int ShenGuan::ShenShengQiYue()
{
	if(this->getHandCardNum() == 0 && this->getEnergy() == 1)
		return GE_SUCCESS;
	if(this->getEnergy() == 1 && this->getHandCardNum() == 1 && getCardByID(*this->getHandCards().begin())->getElement() == ELEMENT_LIGHT)
		return GE_SUCCESS;
	CommandRequest cmd_req;
	Coder::askForSkill(id, SHEN_SHENG_QI_YUE, cmd_req);
	//有限等待,由UserTask调用tryNotify唤醒
	if(engine->waitForOne(id, network::MSG_CMD_REQ, cmd_req))
	{
		void* reply;
		int ret;
		if (GE_SUCCESS == (ret = engine->getReply(id, reply)))
		{
			Respond* respond = (Respond*) reply;
			//发动			
			int crossNum = respond->args(0);			
			if (crossNum > 0)
			{
				int dstID = respond->dst_ids(0);
				PlayerEntity *dstPlayer = engine->getPlayerEntity(dstID);
				network::SkillMsg skill_msg;
				Coder::skillNotice(id, dstID, SHEN_SHENG_QI_YUE, skill_msg);
				engine->sendMessage(-1, MSG_SKILL, skill_msg);
				if(crystal>0){
					setCrystal(--crystal);
				}
				else{
					setGem(--gem);
				}
				subCrossNum(crossNum);
				dstPlayer->addCrossNum(crossNum, 4);
				GameInfo game_info;
				Coder::energyNotice(id, gem, crystal, game_info);
				Coder::crossNotice(id, getCrossNum(), game_info);
				Coder::crossNotice(dstID, dstPlayer->getCrossNum(), game_info);
				engine->sendMessage(-1, MSG_GAME, game_info);
				return GE_SUCCESS;
			}
		}
		return ret;
	}
	else{
		//超时啥都不用做
		return GE_TIMEOUT;
	}
}
int ShengNv::BingShuangDaoYan(CONTEXT_TIMELINE_1 *con)
{
	int srcID = con->attack.srcID;
	int cardID = con->attack.cardID;
	CardEntity* card = getCardByID(cardID);
	if (srcID != id || card->getElement() != ELEMENT_WATER){
		return GE_SUCCESS;
	}
	CommandRequest cmd_req;
	int ret;
	Coder::askForSkill(id, BING_SHUANG_DAO_YAN, cmd_req);
	//有限等待,由UserTask调用tryNotify唤醒
	if(engine->waitForOne(id, network::MSG_CMD_REQ, cmd_req))
	{
		void* reply;
		if (GE_SUCCESS == (ret = engine->getReply(id, reply)))
		{
			Respond* respond = (Respond*) reply;
			int dstID = respond->dst_ids(0);
			PlayerEntity * dstPlayer = engine->getPlayerEntity(dstID);
			SkillMsg skill_msg;
			Coder::skillNotice(id, id, BING_SHUANG_DAO_YAN, skill_msg);
			engine->sendMessage(-1, MSG_SKILL, skill_msg);
			dstPlayer->addCrossNum(1);
			GameInfo update_info;
			Coder::crossNotice(dstID, dstPlayer->getCrossNum(), update_info);
			engine->sendMessage(-1, MSG_GAME, update_info);
		}
		return ret;
	}
	else{
		//超时为自己加治疗
		int dstID = id;
		PlayerEntity * dstPlayer = engine->getPlayerEntity(dstID);
		SkillMsg skill_msg;
		Coder::skillNotice(id, id, BING_SHUANG_DAO_YAN, skill_msg);
		engine->sendMessage(-1, MSG_SKILL, skill_msg);
		dstPlayer->addCrossNum(1);
		GameInfo update_info;
		Coder::crossNotice(dstID, dstPlayer->getCrossNum(), update_info);
		engine->sendMessage(-1, MSG_GAME, update_info);
		return GE_TIMEOUT;
	}
}
int HongLian::v_magic_skill(Action *action)
{
	int actionID = action->action_id();
	int cardID;
	int playerID = action->src_id();
	//int dstID;
	CardEntity* card;
	//PlayerEntity* dst;
	

	if(playerID != id){
		return GE_INVALID_PLAYERID;
	}
	switch(actionID)
	{
	case XING_HONG_SHI_ZI:
		//未选中两张||没能量||没血印
		if(action->card_ids_size() != 2 || getEnergy() < 1 || 0 == token[0])
		{
			return GE_INVALID_ACTION;
		}
		//非法术牌
		for(int i = 0;i<action->card_ids_size();i++)
		{
			cardID = action->card_ids(i);
			card = getCardByID(cardID);
			if(TYPE_MAGIC != card->getType() || GE_SUCCESS != checkOneHandCard(cardID))
			{
				return GE_INVALID_ACTION;
			}
		}
		break;
	default:
		return GE_INVALID_ACTION;
	}
	return GE_SUCCESS;
}
Exemplo n.º 11
0
void BackgroundEngine::timeLine2(CardEntity* harmCard,PlayerEntity* src,PlayerEntity* dst,bool isActiveAttack,int attackType,Harm harm)
{
    coder.askForReBat(attackType,harmCard->getID(),dst->getID(),src->getID());
    //当攻击是必中时,不接受客户端回应
    //emit askForReply(dst->getHandCards(),element,dst->getID());
    BatInfor temp;
    bool checkShield=true;
    if(attackType != NOMISS)
    {
        //战斗信息存储在temp中。若应战,则保存着应战的牌;若抵挡,则保存着圣光或圣盾
        temp = messageBuffer::readBatInfor();
    }
    else
    {
        temp.reply = HIT;
        checkShield=false;
    }

    if(temp.reply == REPLYBATTLE)
    {
        //应战
        //似乎发射信号的时机还要商榷
        CardEntity* usedCard = getCardByID(temp.CardID);
        QList<CardEntity*> use;
        use<<usedCard;
        this->useCard(use,getPlayerByID(temp.srcID),getPlayerByID(temp.dstID));

        coder.hitNotice(BLOCKED,isActiveAttack,dst->getID(),src->getID());
        QList<void*> args;
        args << src;
        args << dst;
        args << &harm;
        args << harmCard;
        args << &isActiveAttack;
        emit timeLine2missedSIG(args);
        this->timeLine1(getCardByID(temp.CardID),getPlayerByID(temp.srcID),getPlayerByID(temp.dstID),false);
    }
    else if(temp.reply == BLOCKED)
    {
        //抵挡
        CardEntity* usedCard = getCardByID(temp.CardID);

        if(usedCard->getPlace() == HAND)
        {
            //圣光
            QList<CardEntity*> use;
            use<<usedCard;
            this->useCard(use,getPlayerByID(temp.srcID));
        }
        coder.hitNotice(BLOCKED,isActiveAttack,dst->getID(),src->getID());
        QList<void*> args;
        args << src;
        args << dst;
        args << &harm;
        args << harmCard;
        args << &isActiveAttack;
        emit timeLine2missedSIG(args);

    }
    else if(temp.reply == HIT)
    {    
        //命中的情况

        QList<void*> args;
        args << src;
        args << dst;
        args << &checkShield;
        emit shieldSIG(args);
        for(int i = 0;i < dst->getBasicEffect().size()&& checkShield;i++)
        {
            //检查是否有圣盾                        
            if(dst->getBasicEffect().at(i)->getMagicName() == SHIELDCARD || dst->getBasicEffect().at(i)->getSpecialityList().contains(tr("天使之墙")))
            {
                coder.shieldNotic(dst->getID());
                dst->removeBasicEffect(dst->getBasicEffect()[i]);

                coder.hitNotice(BLOCKED,isActiveAttack,dst->getID(),src->getID());
                args.clear();
                args << src;
                args << dst;
                args << &harm;
                args << harmCard;
                args << &isActiveAttack;
                emit timeLine2missedSIG(args);
                return;
            }
        }
        //emit timeLine2hitSIG();

        coder.hitNotice(HIT,isActiveAttack,dst->getID(),src->getID());
        args.clear();
        args << src;
        args << dst;
        args << &harm;
        args << harmCard;
        args << &isActiveAttack;
        emit timeLine2hitSIG(args);

        int color = src->getColor();
        //增加星石
        if((teamArea.getCrystal(color) + teamArea.getGem(color)) < 5)
        {
            if(isActiveAttack)
                teamArea.setGem(color,teamArea.getGem(color) + 1);
            else
                teamArea.setCrystal(color,teamArea.getCrystal(color) + 1);
            coder.stoneNotice(color,teamArea.getGem(color),teamArea.getCrystal(color));

        }

        this->timeLine3(harm,src,dst);
    }
}
Exemplo n.º 12
0
//行动阶段函数
void BackgroundEngine::actionPhase()
{    
    //这个标记表明是否行动过,如果已经行动过,那么追加的各种行动机会可以放弃
    bool acted = false;
    bool firstTime=true;
    int canGiveUp=0;


    this->checkEffect(this->currentPlayer);
    QList<void*> args;
    args<<currentPlayer;

    while((this->allowAttack()||this->allowMagic()||this->allowSpecial())&&playing)
    {        
        //根据允许的行动类别询问client
        if(firstTime){
            emit actionPhaseSIG(args);
            emit tiaoXinPhaseSIG(currentPlayer,&canGiveUp);
            firstTime=false;
        }
        if(!acted){
            coder.askForAction(currentPlayer->getID(),canGiveUp,acted);
        }
        else
            coder.askForAdditionalAction(currentPlayer->getID());

        //读取client的回复
        BatInfor bat = messageBuffer::readBatInfor();

        //放弃额外行动
        if(bat.reply == FINISH)
            break;
        //无法行动
        if(bat.reply == UNACTIONAL)
        {                        
            //弃牌重摸
            this->reDraw();
            continue;
        }

        if(bat.reply == ATTACK || bat.reply==ATTACKSKILL)
        {
            //使用攻击牌
            CardEntity* usingCard = getCardByID(bat.CardID);
            PlayerEntity* dst = getPlayerByID(bat.dstID);
            PlayerEntity* src = getPlayerByID(bat.srcID);
            QList<CardEntity*> use;
            int realCard=1;
            use << usingCard;
            args.clear();
            args<<&bat;
            args<<&realCard;
            if(bat.reply==ATTACKSKILL)
                emit skillAttack(args);
            this->useCard(use,src,dst,false,realCard);
            this->timeLine1(usingCard,src,dst,true);

            acted = true;
            this->acted(ATTACK);
            args.clear();
            args<< src;
            args << dst;
            emit attackFinishSIG(args);

        }

        else if(bat.reply == MAGIC)
        {
            //使用法术牌
            if(bat.infor1 == COMMONMAGIC)
                this->useMagicCard(bat.CardID,bat.srcID,bat.dstID);
            else
            {
                QList<void*> args;
                args << &bat;
                emit this->skillMagic(args);
            }
            acted = true;
            this->acted(MAGIC);
            PlayerEntity* src = getPlayerByID(bat.srcID);
            args.clear();
            args<< src;
            emit magicFinishSIG(args);
        }
        else if(bat.reply == SPECIAL)
        {
            //特殊行动
            if(bat.CardID == BUY)
            {
                coder.notice("执行【购买】");
                this->drawCards(3,0,this->getCurrentPlayer());
                int color = this->currentPlayer->getColor();
                teamArea.setGem(color,teamArea.getGem(color) + bat.infor1);
                teamArea.setCrystal(color,teamArea.getCrystal(color) + bat.infor2);                
                coder.stoneNotice(color,teamArea.getGem(color),teamArea.getCrystal(color));
            }
            else if(bat.CardID == SYNTHESIZE)
            {
                coder.notice("执行【合成】");
                this->drawCards(3,0,currentPlayer);
                int color = this->currentPlayer->getColor();
                teamArea.setGem(color,teamArea.getGem(color) - bat.infor1);
                teamArea.setCrystal(color,teamArea.getCrystal(color) - bat.infor2);
                teamArea.setCup(color,teamArea.getCup(color) + 1);
                teamArea.setMorale(!color,teamArea.getMorale(!color) - 1);                
                coder.stoneNotice(color,teamArea.getGem(color),teamArea.getCrystal(color));
                coder.cupNotice(color,teamArea.getCup(color));
                coder.moraleNotice(!color,teamArea.getMorale(!color));
                this->checkEnd();
            }
            else if(bat.CardID == EXTRACT)
            {
                coder.notice("执行【提炼】");
                int color = this->currentPlayer->getColor();
                teamArea.setGem(color,teamArea.getGem(color) - bat.infor1);
                teamArea.setCrystal(color,teamArea.getCrystal(color) - bat.infor2);
                currentPlayer->setGem(currentPlayer->getGem()+bat.infor1);
                currentPlayer->setCrystal(currentPlayer->getCrystal()+bat.infor2);                
                coder.stoneNotice(color,teamArea.getGem(color),teamArea.getCrystal(color));
                coder.energyNotice(currentPlayer->getID(),currentPlayer->getGem(),currentPlayer->getCrystal());
            }
            else {
                QList<void*> args;
                args << &bat;
                emit skillSpecial(args);
            }
            acted = true;
            this->acted(SPECIAL);
        }
    }
    emit turnEndPhaseSIG(currentPlayer);
}
Exemplo n.º 13
0
//魔弹处理
void BackgroundEngine::missileProcess(CardEntity* card,int src,int dst)
{
    bool rightOrder;
    BatInfor reply;
    PlayerEntity* nextOpponent;

    //确定传递方向
    nextOpponent = this->getCurrentPlayer()->getNext();
    while(nextOpponent->getColor() == this->currentPlayer->getColor())
        nextOpponent = nextOpponent->getNext();
    if(nextOpponent->getID() == dst)
        rightOrder = true;
    else
        rightOrder = false;

    bool passed[6];
    for(int i = 0;i < this->playerList.size();i++)
    {
        passed[i] = false;
    }
    int missilePoint = 2;

    QList<CardEntity*> cards;


    do
    {
        cards.clear();
        //魔弹传递到下家
        missilePass(rightOrder,dst,src,passed,missilePoint);

        //读取用户回复
        reply = messageBuffer::readBatInfor();

        if(reply.reply == 0)
        {
            //继续传递
            src = dst;
            dst = reply.dstID;
            missilePoint++;
            cards << getCardByID(reply.CardID);
            this->useCard(cards,getPlayerByID(src),getPlayerByID(dst),false);
            continue;
        }
        else if(reply.reply == 1)
        {
            //圣光
            cards << getCardByID(reply.CardID);
            this->useCard(cards,getPlayerByID(dst));
            break;
        }
        else if(reply.reply == 2)
        {
            //无应对
            PlayerEntity* dstPlayer = getPlayerByID(dst);
            bool shieldBlocked = false;
            //检查圣盾
            for(int i = 0;i < dstPlayer->getBasicEffect().size();i++)
            {
                if(dstPlayer->getBasicEffect()[i]->getMagicName() == SHIELDCARD||dstPlayer->getBasicEffect().at(i)->getSpecialityList().contains(tr("天使之墙")))
                {
                    coder.shieldNotic(dst);
                    dstPlayer->removeBasicEffect(dstPlayer->getBasicEffect()[i]);
                    shieldBlocked = true;
                    break;
                }
            }
            if(shieldBlocked)
                break;
            Harm missileHurt;
            missileHurt.harmPoint = missilePoint;
            missileHurt.type = MAGIC;
            //无圣盾,造成伤害
            this->timeLine3(missileHurt,getPlayerByID(src),dstPlayer,"魔弹");
            break;
        }
        else if(reply.reply == 802)
        {
            //继续传递
            src = dst;
            dst = reply.dstID;
            missilePoint++;
            cards << getCardByID(reply.CardID);
            useCard(cards,getPlayerByID(src),getPlayerByID(dst));
            coder.notice("魔导师发动【魔弹融合】");
            continue;
        }

    }while(1);

}
int NvWuShen::YingLingZhaoHuan(CONTEXT_TIMELINE_2_HIT *con)
{
	int ret;
	if(con->attack.srcID != id || getEnergy() == 0) {
		return GE_SUCCESS;
	}
	CommandRequest cmd_req;
	Coder::askForSkill(id, YING_LING_ZHAO_HUAN, cmd_req);

	if(engine->waitForOne(id, network::MSG_CMD_REQ, cmd_req))
	{
		void* reply;
		if (GE_SUCCESS == (ret = engine->getReply(id, reply)))
		{
			Respond* respond = (Respond*) reply;
			if(respond->args(0) == 1){
				network::SkillMsg skill;
				GameInfo game_info;
				Coder::skillNotice(id, con->attack.dstID, YING_LING_ZHAO_HUAN, skill);
				engine->sendMessage(-1, MSG_SKILL, skill);
				if(crystal >0) {
					setCrystal(--crystal);
				}
				else {
					setGem(--gem);
				}
				Coder::energyNotice(id, gem, crystal, game_info);
				tap = true;
				engine->sendMessage(-1, MSG_GAME, game_info);
				con->harm.point += 1;
				if(respond->args(1)==1){
					int cardID = respond->card_ids(0);
					CardEntity* card = getCardByID(cardID);
					if( card->getType() == TYPE_MAGIC ){
						con->harm.point += 1;
						CardMsg show_card;
						Coder::showCardNotice(id, 1, cardID, show_card);
						engine->sendMessage(-1, MSG_CARD, show_card);
						engine->setStateMoveOneCardNotToHand(id, DECK_HAND, -1, DECK_DISCARD, cardID, id, YING_LING_ZHAO_HUAN, true);
					}
					else {
						return GE_INVALID_CARDID;
					}
				}
				skill.Clear();
				Coder::skillNotice(id, id, HE_PING_XING_ZHE, skill);
				engine->sendMessage(-1, MSG_SKILL, skill);
				game_info.Clear();
				Coder::tapNotice(id, tap, game_info);
				engine->sendMessage(-1, MSG_GAME, game_info);
				if(respond->args(1)==1)
					return GE_URGENT;
				else
					return GE_SUCCESS;
			}
			//取消直接返回
			return GE_SUCCESS;
		}
		return GE_SUCCESS;
	}
	else {
		return GE_TIMEOUT;
	}
}
int LingFu::BaiGuiYeXing_Expose(int cardID)
{
	int ret;
	CommandRequest cmd_req;
	Coder::askForSkill(id, BAI_GUI_YE_XING, cmd_req);
	bool isFire = getCardByID(cardID)->getElement() == ELEMENT_FIRE;
	Command *cmd = (Command*)(&cmd_req.commands(cmd_req.commands_size()-1));
	cmd->add_args(isFire? 1 : 0);
	//有限等待,由UserTask调用tryNotify唤醒
	if(engine->waitForOne(id, network::MSG_CMD_REQ, cmd_req))
	{
		void* reply;
		if (GE_SUCCESS == (ret = engine->getReply(id, reply)))
		{
			Respond* respond = (Respond*) reply;
			ret = GE_INVALID_ACTION;
			//展示
			if(respond->args(0) == 1){
				if(!isFire){
					return GE_INVALID_CARDID;
				}
				if(respond->dst_ids_size() != 2){
					return GE_INVALID_PLAYERID;
				}
				isExposed = true;
				dstIDs[0] = respond->dst_ids(0);
				dstIDs[1] = respond->dst_ids(1);
				list<int> dsts;
				dsts.push_back(dstIDs[0]);
				dsts.push_back(dstIDs[1]);
				network::SkillMsg skill;
				Coder::skillNotice(id, dsts, BAI_GUI_YE_XING, skill);
				engine->sendMessage(-1, MSG_SKILL, skill);
				CardMsg show_card;
				Coder::showCardNotice(id, 1, cardID, show_card);
				engine->sendMessage(-1, MSG_CARD, show_card);
				return GE_SUCCESS;				
			}
			else if(respond->args(0) == 0){
				if(respond->dst_ids_size() != 1){
					return GE_INVALID_PLAYERID;
				}
				isExposed = false;
				dstIDs[0] = respond->dst_ids(0);
				network::SkillMsg skill;
				Coder::skillNotice(id, dstIDs[0], BAI_GUI_YE_XING, skill);
				engine->sendMessage(-1, MSG_SKILL, skill);
				return GE_SUCCESS;
			}
		}
		return ret;
	}
	else{
		isExposed = false;
		dstIDs[0] = 0;
		network::SkillMsg skill;
		Coder::skillNotice(id, dstIDs[0], BAI_GUI_YE_XING, skill);
		engine->sendMessage(-1, MSG_SKILL, skill);
		return GE_TIMEOUT;
	}
}
int ShenGuan::v_magic_skill(Action *action)
{
	int actionID = action->action_id();
	int cardID;
	int playerID = action->src_id();
	CardEntity* card;
	PlayerEntity* dst;

	if(playerID != id){
		return GE_INVALID_PLAYERID;
	}
	switch(actionID)
	{
	case SHEN_SHENG_QI_FU:
		if(action->card_ids_size() != 2)
		{
			return GE_INVALID_ACTION;
		}
		for(int i =0;i<action->card_ids_size();i++)
		{
			cardID = action->card_ids(i);
			card = getCardByID(cardID);
			if(TYPE_MAGIC != card->getType() || GE_SUCCESS != checkOneHandCard(cardID))
			{
				return GE_INVALID_ACTION;
			}
		}
		break;
	case SHUI_ZHI_SHEN_LI:
		
		cardID = action->card_ids(0);
		card = getCardByID(cardID);
		dst = engine->getPlayerEntity(action->dst_ids(0));
		if(GE_SUCCESS != checkOneHandCard(cardID) || card->getElement() != ELEMENT_WATER || color != dst->getColor() || action->dst_ids_size() != 1){
			return GE_INVALID_ACTION;
		}
		break;
	case SHEN_SHENG_LING_YU:
		dst = engine->getPlayerEntity(action->dst_ids(0));
		if(this->getHandCardNum()>2){
			if (action->card_ids_size()!=2){
				return GE_INVALID_ACTION;
			}
		}
		else if( getHandCardNum() != action->card_ids_size()){
			return GE_INVALID_ACTION;
		}
		if(action->args(0) == 1){
			if (getEnergy() < 1 || crossNum < 1){
				return GE_INVALID_ACTION;
			}
		}
		else if(getEnergy() < 1 || dst->getColor() != color){
			return GE_INVALID_ACTION;
		}
		break;
	default:
		return GE_INVALID_ACTION;
	}
	return GE_SUCCESS;
}