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, "ganglie", source)){ room->playSkillEffect(objectName()); JudgeStruct judge; judge.pattern = QRegExp("(.*):(club):(.*)"); judge.good = false; judge.reason = objectName(); judge.who = xiahou; room->judge(judge); if(judge.isGood()){ if(!room->askForDiscard(from, objectName(), 2, true)){ DamageStruct damage; damage.from = xiahou; damage.to = from; room->setEmotion(xiahou, "good"); room->damage(damage); } }else room->setEmotion(xiahou, "bad"); } }
void Shit::doDamage(ServerPlayer *victim) const{ if(victim->isDead()) return; LogMessage log; log.card_str = getEffectIdString(); log.from = victim; Room *room = victim->getRoom(); if(getSuit() == Spade){ log.type = "$ShitLostHp"; room->sendLog(log); room->loseHp(victim); return; } DamageStruct damage; damage.from = damage.to = victim; damage.card = this; switch(getSuit()){ case Club: damage.nature = DamageStruct::Thunder; break; case Heart: damage.nature = DamageStruct::Fire; break; default: damage.nature = DamageStruct::Normal; } log.type = "$ShitDamage"; room->sendLog(log); room->damage(damage); }
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 QuhuCard::onEffect(const CardEffectStruct &effect) const{ ServerPlayer *xunyu = effect.from; ServerPlayer *tiger = effect.to; Room *room = xunyu->getRoom(); bool success = room->pindian(xunyu, tiger); if(success){ QList<ServerPlayer *> players = room->getOtherPlayers(tiger), wolves; foreach(ServerPlayer *player, players){ if(tiger->inMyAttackRange(player)) wolves << player; } if(wolves.isEmpty()) return; ServerPlayer *wolf = room->askForPlayerChosen(xunyu, wolves); DamageStruct damage; damage.from = tiger; damage.to = wolf; room->damage(damage); }else{
void FloodCard::onEffect(const CardEffectStruct &effect) const{ effect.to->throwAllEquips(); Room *room = effect.to->getRoom(); if (!room->askForDiscard(effect.to, "flood", 2, 2, true)) room->damage(DamageStruct("flood", effect.from, effect.to)); }
void LeijiCard::onEffect(const CardEffectStruct &effect) const{ ServerPlayer *zhangjiao = effect.from; ServerPlayer *target = effect.to; Room *room = zhangjiao->getRoom(); room->setEmotion(target, "bad"); JudgeStruct judge; judge.pattern = QRegExp("(.*):(spade):(.*)"); judge.good = false; judge.reason = "leiji"; judge.who = target; room->judge(judge); if(judge.isBad()){ DamageStruct damage; damage.card = NULL; damage.damage = 2; damage.from = zhangjiao; damage.to = target; damage.nature = DamageStruct::Thunder; room->damage(damage); }else room->setEmotion(zhangjiao, "bad"); }
void FurongCard::onEffect(const CardEffectStruct &effect) const { Room *room = effect.from->getRoom(); // copy Room::askForCard twice!! // anti-programming skill!! // wait for the final version. const Card *card1 = NULL; const Card *card2 = NULL; if (card1 == NULL || card2 == NULL) return; //for future use if (card1->isKindOf("Slash") && !card2->isKindOf("Jink")) room->damage(DamageStruct(objectName(), effect.from, effect.to)); else if (!card1->isKindOf("Slash") && card2->isKindOf("Jink")) { if (!effect.to->isNude()) { int id = room->askForCardChosen(effect.from, effect.to, "he", objectName()); room->obtainCard(effect.from, id, false); } } }
void FanjianCard::onEffect(const CardEffectStruct &effect) const{ ServerPlayer *zhouyu = effect.from; ServerPlayer *target = effect.to; Room *room = zhouyu->getRoom(); int card_id = zhouyu->getRandomHandCardId(); const Card *card = Sanguosha->getCard(card_id); Card::Suit suit = room->askForSuit(target); LogMessage log; log.type = "#ChooseSuit"; log.from = target; log.arg = Card::Suit2String(suit); room->sendLog(log); room->showCard(zhouyu, card_id); room->getThread()->delay(); if(card->getSuit() != suit){ DamageStruct damage; damage.card = NULL; damage.from = zhouyu; damage.to = target; room->damage(damage); } if(target->isAlive()){ target->obtainCard(card); } }
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); } }
void FireAttack::onEffect(const CardEffectStruct &effect) const{ Room *room = effect.from->getRoom(); if(effect.to->isKongcheng()) return; const Card *card = room->askForCardShow(effect.to, effect.from, objectName()); if(card->getEffectiveId() < 0 && !card->getSubcards().empty()) room->showCard(effect.to, Sanguosha->getCard(card->getSubcards().first())->getId()); else room->showCard(effect.to, card->getEffectiveId()); QString suit_str = card->getSuitString(); QString pattern = QString(".%1").arg(suit_str.at(0).toUpper()); QString prompt = QString("@fire-attack:%1::%2").arg(effect.to->getGeneralName()).arg(suit_str); if(room->askForCard(effect.from, pattern, prompt, QVariant(), CardDiscarded)){ DamageStruct damage; damage.card = this; damage.from = effect.from; damage.to = effect.to; damage.nature = DamageStruct::Fire; room->damage(damage); } if(card->isVirtualCard()) delete card; }
void TianxiangCard::onEffect(const CardEffectStruct &effect) const { Room *room = effect.to->getRoom(); DamageStruct damage = room->getTag("TianxiangDamage").value<DamageStruct>(); damage.to = effect.to; damage.chain = true; room->damage(damage); if(damage.to->isAlive()) damage.to->drawCards(damage.to->getLostHp()); }
void FloodCard::onEffect(const CardEffectStruct &effect) const{ effect.to->throwAllEquips(); Room *room = effect.to->getRoom(); if(!room->askForDiscard(effect.to, "flood", 2, true)){ DamageStruct damage; damage.from = effect.from; damage.to = effect.to; room->damage(damage); } }
virtual void onDamaged(ServerPlayer *xiahou, const DamageStruct &damage) const{ ServerPlayer *from = damage.from; Room *room = xiahou->getRoom(); 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()) { if (from->getHandcardNum() < 2 || !room->askForDiscard(from, objectName(), 2, 2, true)) room->damage(DamageStruct(objectName(), xiahou, from)); } }
virtual bool trigger(TriggerEvent , ServerPlayer *player, QVariant &data) const{ DamageStruct damage = data.value<DamageStruct>(); Room *room = player->getRoom(); if(damage.card && damage.card->inherits("Slash")){ QString choice = room->askForChoice(player, "muramasa", "sky+yks"); if(choice=="yks") damage.from = NULL; else { QList<ServerPlayer *> players = room->getAllPlayers(); ServerPlayer *target = room->askForPlayerChosen(player, players, "muramasa"); damage.from = target; } if(damage.from==player) return false; room->damage(damage); return true; } }
void Shit::onMove(const CardMoveStruct &move) const{ ServerPlayer *from = (ServerPlayer*)move.from; if(from && move.from_place == Player::PlaceHand && from->getRoom()->getCurrent() == move.from && (move.to_place == Player::DiscardPile || move.to_place == Player::PlaceSpecial) && move.to == NULL && from->isAlive()){ LogMessage log; log.card_str = getEffectIdString(); log.from = from; Room *room = from->getRoom(); if(getSuit() == Spade){ log.type = "$ShitLostHp"; room->sendLog(log); room->loseHp(from); return; } DamageStruct damage; damage.from = damage.to = from; damage.card = this; switch(getSuit()){ case Club: damage.nature = DamageStruct::Thunder; break; case Heart: damage.nature = DamageStruct::Fire; break; default: damage.nature = DamageStruct::Normal; } log.type = "$ShitDamage"; room->sendLog(log); room->damage(damage); } }
void SuperFanjianCard::onEffect(const CardEffectStruct &effect) const{ ServerPlayer *superzhouyu = effect.from; ServerPlayer *target = effect.to; Room *room = superzhouyu->getRoom(); int card_id = superzhouyu->getRandomHandCardId(); const Card *card = Sanguosha->getCard(card_id); Card::Suit suit = room->askForSuit(target); LogMessage log; log.type = "#ChooseSuit"; log.from = target; log.arg = Card::Suit2String(suit); room->sendLog(log); room->showCard(target, card_id); room->getThread()->delay(); if(card->getSuit() != suit){ DamageStruct damage; damage.card = NULL; damage.from = superzhouyu; damage.to = target; if(damage.from->hasSkill("jueqing")){ LogMessage log; log.type = "#Jueqing"; log.from = damage.from; log.to << damage.to; log.arg = QString::number(1); room->sendLog(log); room->playSkillEffect("jueqing"); room->loseHp(damage.to, 1); }else{ room->damage(damage); } } target->obtainCard(card); }
void FireAttack::onEffect(const CardEffectStruct &effect) const{ Room *room = effect.from->getRoom(); if (effect.to->isKongcheng()) return; const Card *card = room->askForCardShow(effect.to, effect.from, objectName()); room->showCard(effect.to, card->getEffectiveId()); QString suit_str = card->getSuitString(); QString pattern = QString(".%1").arg(suit_str.at(0).toUpper()); QString prompt = QString("@fire-attack:%1::%2").arg(effect.to->objectName()).arg(suit_str); if (effect.from->isAlive()) { const Card *card_to_throw = room->askForCard(effect.from, pattern, prompt); if (card_to_throw) room->damage(DamageStruct(this, effect.from, effect.to, 1, DamageStruct::Fire)); else effect.from->setFlags("FireAttackFailed_" + effect.to->objectName()); // For AI } if (card->isVirtualCard()) delete 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"); } }
virtual bool onPhaseChange(ServerPlayer *player) const{ if(player->getPhase() != Player::Finish) return false; Room *room = player->getRoom(); QList<ServerPlayer *> splayers = room->findPlayersBySkillName(objectName()); foreach(ServerPlayer *splayer, splayers){ if(player == splayer || splayer->isKongcheng()) continue; if(room->askForCard(splayer, "BasicCard", "@xiaoguo:" + player->objectName(), QVariant::fromValue((PlayerStar)player), CardDiscarded)){ LogMessage log; log.type = "#InvokeSkill"; log.from = splayer; log.arg = objectName(); room->sendLog(log); if(!room->askForCard(player, "EquipCard,TrickCard", "@xiaoguoresponse:" + splayer->objectName(), QVariant(), CardDiscarded)){ room->playSkillEffect(objectName(), qrand() % 2 + 1); LogMessage log; log.type = "#Xiaoguo"; log.from = splayer; log.to << player; log.arg = objectName(); room->sendLog(log); DamageStruct damage; damage.from = splayer; damage.to = player; room->damage(damage); } else room->playSkillEffect(objectName(), 3); } } return false; }
void FireAttack::onEffect(const CardEffectStruct &effect) const{ Room *room = effect.from->getRoom(); if(effect.to->isKongcheng()) return; const Card *card = room->askForCardShow(effect.to, effect.from, objectName()); room->showCard(effect.to, card->getEffectiveId()); QString suit_str = card->getSuitString(); QString pattern = QString(".%1").arg(suit_str.at(0).toUpper()); QString prompt = QString("@fire-attack:%1::%2").arg(effect.to->getGeneralName()).arg(suit_str); if(effect.from->isAlive() && room->askForCard(effect.from, pattern, prompt)){ DamageStruct damage; damage.card = this; damage.from = effect.from; damage.to = effect.to; damage.nature = DamageStruct::Fire; room->damage(damage); } if(card->isVirtualCard()) delete card; }
bool GameRule::trigger(TriggerEvent event, ServerPlayer *player, QVariant &data) const{ Room *room = player->getRoom(); switch(event){ case GameStart: { if(player->getKingdom() == "god"){ QString new_kingdom = room->askForKingdom(player); if(new_kingdom != "god") room->setPlayerProperty(player, "kingdom", new_kingdom); LogMessage log; log.type = "#ChooseKingdom"; log.from = player; log.arg = new_kingdom; room->sendLog(log); } player->drawCards(4, false); break; } case PhaseChange: onPhaseChange(player); break; case CardUsed: { if(data.canConvert<CardUseStruct>()){ CardUseStruct card_use = data.value<CardUseStruct>(); const Card *card = card_use.card; card_use.from->playCardEffect(card); card->use(room, card_use.from, card_use.to); } break; } case Dying:{ DyingStruct dying = data.value<DyingStruct>(); int got = room->askForPeaches(player, dying.peaches); if(got >= dying.peaches) room->setPlayerProperty(player, "hp", got - dying.peaches + 1); else{ ServerPlayer *killer = NULL; if(dying.damage && dying.damage->from) killer = dying.damage->from; room->killPlayer(player, killer); } break; } case Predamaged:{ if(data.canConvert<DamageStruct>()){ DamageStruct damage = data.value<DamageStruct>(); room->sendDamageLog(damage); int new_hp = player->getHp() - damage.damage; room->damage(player, damage.damage); if(new_hp <= 0){ DyingStruct dying; dying.damage = &damage; dying.peaches = 1 - new_hp; QVariant dying_data = QVariant::fromValue(dying); room->getThread()->trigger(Dying, player, dying_data); } bool chained = player->isChained(); if(damage.nature != DamageStruct::Normal && chained){ room->setPlayerProperty(player, "chained", false); // iron chain effect QList<ServerPlayer *> chained_players = room->getAllPlayers(); chained_players.removeOne(player); foreach(ServerPlayer *chained_player, chained_players){ if(chained_player->isChained()){ DamageStruct chain_damage = damage; chain_damage.to = chained_player; chain_damage.chain = true; room->setPlayerProperty(chained_player, "chained", false); room->damage(chain_damage); } } } } break; }