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); } }
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); } } }
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{
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); } }
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; }
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 {
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; }
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; }
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; }
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); } } }
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 {
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"); } } }
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 {
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(); }
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; }
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; } }
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; }
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"); } }
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); }