bool IronChain::targetsFeasible(const QList<const Player *> &targets, const Player *Self) const{
    bool rec = (Sanguosha->currentRoomState()->getCurrentCardUseReason() == CardUseStruct::CARD_USE_REASON_PLAY);
    QList<int> sub;
    if (isVirtualCard())
        sub = subcards;
    else
        sub << getEffectiveId();
    foreach (int id, sub) {
        if (Self->getPile("wooden_ox").contains(id)) {
            rec = false;
            break;
        }
    }

    if (rec && Self->isCardLimited(this, Card::MethodUse))
        return targets.length() == 0;

    if (Sanguosha->currentRoomState()->getCurrentCardUseReason() == CardUseStruct::CARD_USE_REASON_RESPONSE_USE)
        return targets.length() != 0;

    int total_num = 2 + Sanguosha->correctCardTarget(TargetModSkill::ExtraTarget, Self, this);
    if (!rec || getSkillName().contains("guhuo") || getSkillName() == "qice") //why dirty hack?
        return targets.length() > 0 && targets.length() <= total_num;
    else
        return targets.length() <= total_num;
}
Exemple #2
0
bool IronChain::targetsFeasible(const QList<const Player *> &targets, const Player *Self) const{
    //saffah                                                     //铁索连环的目标是否合法?
    if(getSkillName() == "guhuo" or getSkillName() == "lianwang")//如果这张铁索是通过蛊惑或者联网转化的
        return targets.length() == 1 || targets.length() == 2;   //那么要选择1个或两个目标
    else                                                         //如果不是
        return targets.length() <= 2;                            //那么不超过两个目标都可以
}                                                                //不指定目标→重铸
bool IronChain::targetsFeasible(const QList<const Player *> &targets, const Player *Self) const{
    if (Self->isCardLimited(this, Card::MethodUse))
        return targets.length() == 0;
    if (getSkillName() == "guhuo" || getSkillName() == "qice")
        return targets.length() == 1 || targets.length() == 2;
    else
        return targets.length() <= 2;
}
bool IronChain::targetsFeasible(const QList<const Player *> &targets, const Player *Self) const{
    if (Self->isCardLimited(this, Card::MethodUse))
        return targets.length() == 0;
    int total_num = 2 + Sanguosha->correctCardTarget(TargetModSkill::ExtraTarget, Self, this);
    if (getSkillName().contains("guhuo") || getSkillName() == "qice")
        return targets.length() > 0 && targets.length() <= total_num;
    else
        return targets.length() <= total_num;
}
bool IronChain::targetsFeasible(const QList<const Player *> &targets, const Player *Self) const{
    if (Self->isCardLimited(this, Card::MethodUse))
        return targets.length() == 0;

    if (Sanguosha->currentRoomState()->getCurrentCardUseReason() == CardUseStruct::CARD_USE_REASON_RESPONSE_USE)
        return targets.length() != 0;

    int total_num = 2 + Sanguosha->correctCardTarget(TargetModSkill::ExtraTarget, Self, this);
    if (getSkillName().contains("guhuo") || getSkillName() == "qice")
        return targets.length() > 0 && targets.length() <= total_num;
    else
        return targets.length() <= total_num;
}
Exemple #6
0
void DelayedTrick::onEffect(const CardEffectStruct &effect) const
{
    Room *room = effect.to->getRoom();

    CardMoveReason reason(CardMoveReason::S_REASON_USE, effect.to->objectName(), getSkillName(), QString());
    room->moveCardTo(this, NULL, Player::PlaceTable, reason, true);

    LogMessage log;
    log.from = effect.to;
    log.type = "#DelayedTrick";
    log.arg = effect.card->objectName();
    room->sendLog(log);

    JudgeStruct judge_struct = judge;
    judge_struct.who = effect.to;
    room->judge(judge_struct);

    if (judge_struct.negative == judge_struct.isBad()) {
        if (effect.to->isAlive())
            takeEffect(effect.to);
        if (room->getCardOwner(getEffectiveId()) == NULL) {
            CardMoveReason reason(CardMoveReason::S_REASON_NATURAL_ENTER, QString());
            room->throwCard(this, reason, NULL);
        }
    } else if (movable) {
        onNullified(effect.to);
    } else if (returnable && effect.to->isAlive()) {
        if (room->getCardOwner(getEffectiveId()) == NULL) {
            if (isVirtualCard()) {
                Card *delayTrick = Sanguosha->cloneCard(objectName());
                WrappedCard *vs_card = Sanguosha->getWrappedCard(getEffectiveId());
                vs_card->setSkillName(getSkillName());
                vs_card->takeOver(delayTrick);
                room->broadcastUpdateCard(room->getAlivePlayers(), vs_card->getId(), vs_card);
            }
           
            CardsMoveStruct move;
            move.card_ids << getEffectiveId();
            move.to = effect.to;
            move.to_place = Player::PlaceDelayedTrick;
            room->moveCardsAtomic(move, true);
        }
    }
    else {
        if (room->getCardOwner(getEffectiveId()) == NULL) {
            CardMoveReason reason(CardMoveReason::S_REASON_NATURAL_ENTER, QString());
            room->throwCard(this, reason, NULL);
        }
    }
}
Exemple #7
0
void DelayedTrick::onUse(Room *room, const CardUseStruct &card_use) const
{
    CardUseStruct use = card_use;
    WrappedCard *wrapped = Sanguosha->getWrappedCard(getEffectiveId());
    use.card = wrapped;

    LogMessage log;
    log.from = use.from;
    log.to = use.to;
    log.type = "#UseCard";
    log.card_str = toString();
    room->sendLog(log);

    QVariant data = QVariant::fromValue(use);
    RoomThread *thread = room->getThread();
    thread->trigger(PreCardUsed, room, data);

    //CardMoveReason reason(CardMoveReason::S_REASON_USE, use.from->objectName(), use.to.first()->objectName(), getSkillName(), QString());
    //room->moveCardTo(this, use.from, use.to.first(), Player::PlaceDelayedTrick, reason, true);

    CardMoveReason reason(CardMoveReason::S_REASON_USE, use.from->objectName(), QString(), card_use.card->getSkillName(), QString());
    CardsMoveStruct move(card_use.card->getEffectiveId(), NULL, Player::PlaceTable, reason);
    room->moveCardsAtomic(move, true);
    //show hidden after move Event to avoid filter card
    use.from->showHiddenSkill(getSkillName());

    thread->trigger(CardUsed, room, data);
    thread->trigger(CardFinished, room, data);
}
Exemple #8
0
void DelayedTrick::onEffect(const CardEffectStruct &effect) const
{
    Room *room = effect.to->getRoom();

    CardMoveReason reason(CardMoveReason::S_REASON_USE, effect.to->objectName(), getSkillName(), QString());
    room->moveCardTo(this, NULL, Player::PlaceTable, reason, true);

    LogMessage log;
    log.from = effect.to;
    log.type = "#DelayedTrick";
    log.arg = effect.card->objectName();
    room->sendLog(log);

    JudgeStruct judge_struct = judge;
    judge_struct.who = effect.to;
    room->judge(judge_struct);

    if (judge_struct.isBad()) {
        takeEffect(effect.to);
        if (room->getCardOwner(getEffectiveId()) == NULL) {
            CardMoveReason reason(CardMoveReason::S_REASON_NATURAL_ENTER, QString());
            room->throwCard(this, reason, NULL);
        }
    } else if (movable) {
        onNullified(effect.to);
    } else {
        if (room->getCardOwner(getEffectiveId()) == NULL) {
            CardMoveReason reason(CardMoveReason::S_REASON_NATURAL_ENTER, QString());
            room->throwCard(this, reason, NULL);
        }
    }
}
Exemple #9
0
void LijianCard::use(Room *room, ServerPlayer *, QList<ServerPlayer *> &targets) const{
    ServerPlayer *to = targets.at(0);
    ServerPlayer *from = targets.at(1);

    Duel *duel = new Duel(Card::NoSuit, 0);
    duel->setCancelable(duel_cancelable);
    duel->setSkillName(QString("_%1").arg(getSkillName()));
    if (!from->isCardLimited(duel, Card::MethodUse) && !from->isProhibited(to, duel))
        room->useCard(CardUseStruct(duel, from, to));
    else
        delete duel;
}
Exemple #10
0
void Slash::onUse(Room *room, const CardUseStruct &card_use) const{
    ServerPlayer *player = card_use.from;

    if(player->getPhase() == Player::Play
            && player->getMark("SlashCount") >= 1
            && player->hasSkill("paoxiao")
            && getSkillName().isEmpty())
        room->playSkillEffect("paoxiao", player->getGeneral2Name() == "zombie" ? 3 : qrand() % 2 + 1);
    else if(player->getPhase() == Player::Play
            && player->hasSkill("huxiao") && player->getMark("huxiao") > 0) {
        bool toSunquan = false;
        foreach(ServerPlayer *p, card_use.to)
            if(p->getGeneralName().contains("sunquan")) {
            toSunquan = true;
            break;
        }
        if(toSunquan)
            room->playSkillEffect("huxiao", 3);
        else
            room->playSkillEffect("huxiao", 2);
    }
bool Slash::targetFilter(const QList<const Player *> &targets, const Player *to_select, const Player *Self) const{
    int slash_targets = 1;
    if(Self->hasWeapon("halberd") && Self->isLastHandCard(this)){
        slash_targets = 3;
    }

    bool distance_limit = true;

    if(Self->hasFlag("tianyi_success")){
        distance_limit = false;
        slash_targets ++;
    }

    if(Self->hasSkill("lihuo") && inherits("FireSlash"))
        slash_targets ++;

    if(Self->hasSkill("tieji_p") && Self->getWeapon() && Self->getWeapon()->getRange() >= 3){
        slash_targets ++ ;
    }

    if(Self->hasSkill("shenji") && Self->getWeapon() == NULL)
        slash_targets = 3;

    if(targets.length() >= slash_targets)
        return false;

    if(inherits("WushenSlash")){
        distance_limit = false;
    }

    if(getSkillName() == "wusheng" && Self->isSkillEnhance("wusheng", 1)){
        int card_id = getSubcards().first() ;
        if(Sanguosha->getCard(card_id)->getSuit() == Card::Heart)
            distance_limit = false ;
    }

    return Self->canSlash(to_select, distance_limit);
}
Exemple #12
0
bool IronChain::targetsFeasible(const QList<const ClientPlayer *> &targets) const{
    if(getSkillName() == "guhuo")
        return targets.length() == 1 || targets.length() == 2;
    else
        return targets.length() <= 2;
}
Exemple #13
0
void DelayedTrick::use(Room *room, ServerPlayer *source, QList<ServerPlayer *> &targets) const
{
    QStringList nullified_list = room->getTag("CardUseNullifiedList").toStringList();
    bool all_nullified = nullified_list.contains("_ALL_TARGETS");
    if (all_nullified || targets.isEmpty() || targets.first()->isDead()) {
        if (movable) {
            onNullified(source);
            if (room->getCardOwner(getEffectiveId()) != source)
                return;
        }
        CardMoveReason reason(CardMoveReason::S_REASON_USE, source->objectName(), QString(), getSkillName(), QString());
        //room->moveCardTo(this, room->getCardOwner(getEffectiveId()), NULL, Player::DiscardPile, reason, true);
        room->moveCardTo(this, source, NULL, Player::DiscardPile, reason, true);
    } else {
        CardMoveReason reason(CardMoveReason::S_REASON_USE, source->objectName(), targets.first()->objectName(), getSkillName(), QString());
        room->moveCardTo(this, source, targets.first(), Player::PlaceDelayedTrick, reason, true);
    }
}
Exemple #14
0
bool IronChain::targetsFeasible(const QList<const Player *> &targets, const Player *Self) const{
    if(getSkillName() == "guhuo" || getSkillName() == "qice")
        return targets.length() == 1 || targets.length() == 2;
    else
        return targets.length() <= 2;
}
Exemple #15
0
std::string Item::getDescription(const ItemType& it, int32_t lookDistance,
                                 const Item* item /*= NULL*/, int32_t subType /*= -1*/, bool addArticle /*= true*/)
{
	std::ostringstream s;
	s << getNameDescription(it, item, subType, addArticle);

	if (item) {
		subType = item->getSubType();
	}

	if (it.isRune()) {
		if (!it.runeSpellName.empty()) {
			s << " (\"" << it.runeSpellName << "\")";
		}

		if (it.runeLevel > 0 || it.runeMagLevel > 0) {
			int32_t tmpSubType = subType;

			if (item) {
				tmpSubType = item->getSubType();
			}

			s << ". " << (it.stackable && tmpSubType > 1 ? "They" : "It") << " can only be used with";

			if (it.runeLevel > 0) {
				s << " level " << it.runeLevel;
			}

			if (it.runeMagLevel > 0) {
				if (it.runeLevel > 0) {
					s << " and";
				}

				s << " magic level " << it.runeMagLevel;
			}

			s << " or higher";
		}
	} else if (it.weaponType != WEAPON_NONE) {
		if (it.weaponType == WEAPON_DIST && it.ammoType != AMMO_NONE) {
			s << " (Range:" << it.shootRange;

			if (it.attack != 0) {
				s << ", Atk " << std::showpos << it.attack << std::noshowpos;
			}

			if (it.hitChance != 0) {
				s << ", Hit% " << std::showpos << it.hitChance << std::noshowpos;
			}

			s << ")";
		} else if (it.weaponType != WEAPON_AMMO) {
			bool begin = true;

			if (it.attack != 0) {
				begin = false;
				s << " (Atk:" << it.attack;

				if (it.abilities && it.abilities->elementType != COMBAT_NONE && it.abilities->elementDamage != 0) {
					s << " physical + " << it.abilities->elementDamage << " " << getCombatName(it.abilities->elementType);
				}
			}

			if (it.defense != 0 || it.extraDefense != 0) {
				if (begin) {
					begin = false;
					s << " (";
				} else {
					s << ", ";
				}

				s << "Def:" << it.defense;

				if (it.extraDefense != 0 || (item && item->getExtraDefense() != 0)) {
					s << " " << std::showpos << it.extraDefense << std::noshowpos;
				}
			}

			if (it.abilities) {
				for (uint16_t i = SKILL_FIRST; i <= SKILL_LAST; i++) {
					if (!it.abilities->skills[i]) {
						continue;
					}

					if (begin) {
						begin = false;
						s << " (";
					} else {
						s << ", ";
					}

					s << getSkillName(i) << " " << std::showpos << it.abilities->skills[i] << std::noshowpos;
				}

				if (it.abilities->stats[STAT_MAGICPOINTS]) {
					if (begin) {
						begin = false;
						s << " (";
					} else {
						s << ", ";
					}

					s << "magic level " << std::showpos << it.abilities->stats[STAT_MAGICPOINTS] << std::noshowpos;
				}

				int32_t show = it.abilities->absorbPercent[COMBAT_FIRST];

				for (uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_COUNT; ++i) {
					if (it.abilities->absorbPercent[i] == show) {
						continue;
					}

					show = 0;
					break;
				}

				if (!show) {
					bool tmp = true;

					for (uint32_t i = COMBAT_FIRST; i <= COMBAT_COUNT; i++) {
						if (!it.abilities->absorbPercent[i]) {
							continue;
						}

						if (tmp) {
							tmp = false;

							if (begin) {
								begin = false;
								s << " (";
							} else {
								s << ", ";
							}

							s << "protection ";
						} else {
							s << ", ";
						}

						s << getCombatName(indexToCombatType(i)) << " " << std::showpos << it.abilities->absorbPercent[i] << std::noshowpos << "%";
					}
				} else {
					if (begin) {
						begin = false;
						s << " (";
					} else {
						s << ", ";
					}

					s << "protection all " << std::showpos << show << std::noshowpos << "%";
				}

				if (it.abilities->speed) {
					if (begin) {
						begin = false;
						s << " (";
					} else {
						s << ", ";
					}

					s << "speed " << std::showpos << (int32_t)(it.abilities->speed / 2) << std::noshowpos;
				}
			}

			if (!begin) {
				s << ")";
			}
		}
	} else if (it.armor || (item && item->getArmor()) || it.showAttributes) {
		int32_t tmp = it.armor;

		if (item) {
			tmp = item->getArmor();
		}

		bool begin = true;

		if (tmp != 0) {
			s << " (Arm:" << tmp;
			begin = false;
		}

		if (it.abilities) {
			for (uint16_t i = SKILL_FIRST; i <= SKILL_LAST; i++) {
				if (!it.abilities->skills[i]) {
					continue;
				}

				if (begin) {
					begin = false;
					s << " (";
				} else {
					s << ", ";
				}

				s << getSkillName(i) << " " << std::showpos << it.abilities->skills[i] << std::noshowpos;
			}

			if (it.abilities->stats[STAT_MAGICPOINTS]) {
				if (begin) {
					begin = false;
					s << " (";
				} else {
					s << ", ";
				}

				s << "magic level " << std::showpos << it.abilities->stats[STAT_MAGICPOINTS] << std::noshowpos;
			}

			int32_t show = it.abilities->absorbPercent[COMBAT_FIRST];

			for (uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_COUNT; ++i) {
				if (it.abilities->absorbPercent[i] == show) {
					continue;
				}

				show = 0;
				break;
			}

			if (!show) {
				bool protectionBegin = true;
				for (uint32_t i = COMBAT_FIRST; i <= COMBAT_COUNT; i++) {
					if (!it.abilities->absorbPercent[i]) {
						continue;
					}

					if (protectionBegin) {
						protectionBegin = false;

						if (begin) {
							begin = false;
							s << " (";
						} else {
							s << ", ";
						}

						s << "protection ";
					} else {
						s << ", ";
					}

					s << getCombatName(indexToCombatType(i)) << " " << std::showpos << it.abilities->absorbPercent[i] << std::noshowpos << "%";
				}
			} else {
				if (begin) {
					begin = false;
					s << " (";
				} else {
					s << ", ";
				}

				s << "protection all " << std::showpos << show << std::noshowpos << "%";
			}

			if (it.abilities->speed) {
				if (begin) {
					begin = false;
					s << " (";
				} else {
					s << ", ";
				}

				s << "speed " << std::showpos << (int32_t)(it.abilities->speed / 2) << std::noshowpos;
			}
		}

		if (!begin) {
			s << ")";
		}
	} else if (it.isContainer()) {
		s << " (Vol:" << (int32_t)it.maxItems << ")";
	} else {
		bool found = true;

		if (it.abilities) {
			if (it.abilities->speed > 0) {
				s << " (speed " << std::showpos << (it.abilities->speed / 2) << std::noshowpos << ")";
			} else if (it.abilities && hasBitSet(CONDITION_DRUNK, it.abilities->conditionSuppressions)) {
				s << " (hard drinking)";
			} else if (it.abilities->invisible) {
				s << " (invisibility)";
			} else if (it.abilities->regeneration) {
				s << " (faster regeneration)";
			} else if (it.abilities->manaShield) {
				s << " (mana shield)";
			} else {
				found = false;
			}
		} else {
			found = false;
		}

		if (!found) {
			if (it.isKey()) {
				s << " (Key:" << (item ? (int32_t)item->getActionId() : 0) << ")";
			} else if (it.isFluidContainer()) {
				if (subType > 0) {
					const std::string& itemName = items[subType].name;
					s << " of " << (itemName.length() ? itemName : "unknown");
				} else {
					s << ". It is empty";
				}
			} else if (it.isSplash()) {
				s << " of ";

				if (subType > 0 && items[subType].name.length()) {
					s << items[subType].name;
				} else {
					s << "unknown";
				}
			} else if (it.allowDistRead && it.id != 7369 && it.id != 7370 && it.id != 7371) {
				s << "." << std::endl;

				if (lookDistance <= 4) {
					if (item && !item->getText().empty()) {
						if (item->getWriter().length()) {
							s << item->getWriter() << " wrote";
							time_t date = item->getDate();

							if (date > 0) {
								s << " on " << formatDateShort(date);
							}

							s << ": ";
						} else {
							s << "You read: ";
						}

						std::string outtext;

						if (utf8ToLatin1(item->getText().c_str(), outtext)) {
							s << outtext;
						} else {
							s << item->getText();
						}
					} else {
						s << "Nothing is written on it";
					}
				} else {
					s << "You are too far away to read it";
				}
			} else if (it.levelDoor && item && item->getActionId() >= (int32_t)it.levelDoor) {
				s << " for level " << item->getActionId() - it.levelDoor;
			}
		}
	}

	if (it.showCharges) {
		s << " that has " << subType << " charge" << (subType != 1 ? "s" : "") << " left";
	}

	if (it.showDuration) {
		if (item && item->hasAttribute(ATTR_ITEM_DURATION)) {
			int32_t duration = item->getDuration() / 1000;
			s << " that will expire in ";

			if (duration >= 86400) {
				uint16_t days = duration / 86400;
				uint16_t hours = (duration % 86400) / 3600;
				s << days << " day" << (days != 1 ? "s" : "");

				if (hours > 0) {
					s << " and " << hours << " hour" << (hours != 1 ? "s" : "");
				}
			} else if (duration >= 3600) {
				uint16_t hours = duration / 3600;
				uint16_t minutes = (duration % 3600) / 60;
				s << hours << " hour" << (hours != 1 ? "s" : "");

				if (minutes > 0) {
					s << " and " << minutes << " minute" << (minutes != 1 ? "s" : "");
				}
			} else if (duration >= 60) {
				uint16_t minutes = duration / 60;
				s << minutes << " minute" << (minutes != 1 ? "s" : "");
				uint16_t seconds = duration % 60;

				if (seconds > 0) {
					s << " and " << seconds << " second" << (seconds != 1 ? "s" : "");
				}
			} else {
				s << duration << " second" << (duration != 1 ? "s" : "");
			}
		} else {
			s << " that is brand-new";
		}
	}

	if (!it.allowDistRead || item->getText().empty() || (it.id >= 7369 && it.id <= 7371)) {
		s << ".";
	}

	if (it.wieldInfo != 0) {
		s << std::endl << "It can only be wielded properly by ";

		if (it.wieldInfo & WIELDINFO_PREMIUM) {
			s << "premium ";
		}

		if (it.wieldInfo & WIELDINFO_VOCREQ) {
			s << it.vocationString;
		} else {
			s << "players";
		}

		if (it.wieldInfo & WIELDINFO_LEVEL) {
			s << " of level " << (int32_t)it.minReqLevel << " or higher";
		}

		if (it.wieldInfo & WIELDINFO_MAGLV) {
			if (it.wieldInfo & WIELDINFO_LEVEL) {
				s << " and";
			} else {
				s << " of";
			}

			s << " magic level " << (int32_t)it.minReqMagicLevel << " or higher";
		}

		s << ".";
	}

	if (lookDistance <= 1) {
		double weight = (item == NULL ? it.weight : item->getWeight());

		if (weight > 0 && it.pickupable) {
			int32_t count = weight / it.weight;
			s << std::endl << getWeightDescription(it, weight, count);
		}
	}

	if (item && !item->getSpecialDescription().empty()) {
		s << std::endl << item->getSpecialDescription();
	} else if (it.description.length() && lookDistance <= 1) {
		s << std::endl << it.description;
	}

	if (it.allowDistRead && it.id >= 7369 && it.id <= 7371 && !item->getText().empty()) {
		s << std::endl << item->getText();
	}

	return s.str();
}
Exemple #16
0
std::string Item::getDescription(const ItemType& it, int32_t lookDistance, const Item* item/* = NULL*/,
	int32_t subType/* = -1*/, bool addArticle/* = true*/)
{
	std::stringstream s;
	s << getNameDescription(it, item, subType, addArticle);
	if(item)
		subType = item->getSubType();

	bool dot = true;
	if(it.isRune())
	{
		if(!it.runeSpellName.empty())
			s << "(\"" << it.runeSpellName << "\")";

		if(it.runeLevel > 0 || it.runeMagLevel > 0 || (it.vocationString != "" && it.wieldInfo == 0))
		{
			s << "." << std::endl << "It can only be used";
			if(it.vocationString != "" && it.wieldInfo == 0)
				s << " by " << it.vocationString;

			bool begin = true;
			if(g_config.getBool(ConfigManager::USE_RUNE_REQUIREMENTS) && it.runeLevel > 0)
			{
				begin = false;
				s << " with level " << it.runeLevel;
			}

			if(g_config.getBool(ConfigManager::USE_RUNE_REQUIREMENTS) && it.runeMagLevel > 0)
			{
				begin = false;
				s << " " << (begin ? "with" : "and") << " magic level " << it.runeMagLevel;
			}

			if(g_config.getBool(ConfigManager::USE_RUNE_REQUIREMENTS) && !begin)
				s << " or higher";
		}
	}
	else if(it.weaponType != WEAPON_NONE)
	{
		bool begin = true;
		if(it.weaponType == WEAPON_DIST && it.ammoType != AMMO_NONE)
		{
			begin = false;
			s << " (Range:" << int32_t(item ? item->getShootRange() : it.shootRange);
			if(it.attack || it.extraAttack || (item && (item->getAttack() || item->getExtraAttack())))
			{
				s << ", Atk " << std::showpos << int32_t(item ? item->getAttack() : it.attack);
				if(it.extraAttack || (item && item->getExtraAttack()))
					s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos;
			}

			if(it.hitChance != -1 || (item && item->getHitChance() != -1))
				s << ", Hit% " << std::showpos << (item ? item->getHitChance() : it.hitChance) << std::noshowpos;

			if(it.attackSpeed || (item && item->getAttackSpeed()))
				s << ", AS: " << (item ? item->getAttackSpeed() : it.attackSpeed);
		}
		else if(it.weaponType != WEAPON_AMMO && it.weaponType != WEAPON_WAND)
		{
			if(it.attack || it.extraAttack || (item && (item->getAttack() || item->getExtraAttack())))
			{
				begin = false;
				s << " (Atk:";
				if(it.hasAbilities() && it.abilities->elementType != COMBAT_NONE)
				{
					s << std::max((int32_t)0, int32_t((item ? item->getAttack() : it.attack) - it.abilities->elementDamage));
					if(it.extraAttack || (item && item->getExtraAttack()))
						s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos;

					s << " physical + " << it.abilities->elementDamage << " " << getCombatName(it.abilities->elementType);
				}
				else
				{
					s << int32_t(item ? item->getAttack() : it.attack);
					if(it.extraAttack || (item && item->getExtraAttack()))
						s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos;
				}
			}

			if(it.defense || it.extraDefense || (item && (item->getDefense() || item->getExtraDefense())))
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "Def:" << int32_t(item ? item->getDefense() : it.defense);
				if(it.extraDefense || (item && item->getExtraDefense()))
					s << " " << std::showpos << int32_t(item ? item->getExtraDefense() : it.extraDefense) << std::noshowpos;
			}
		}

		if(it.attackSpeed || (item && item->getAttackSpeed()))
		{
			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			s << "AS: " << (item ? item->getAttackSpeed() : it.attackSpeed);
		}

		if(it.hasAbilities())
		{
			for(uint16_t i = SKILL_FIRST; i <= SKILL_LAST; ++i)
			{
				if(!it.abilities->skills[i])
					continue;

				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << getSkillName(i) << " " << std::showpos << (int32_t)it.abilities->skills[i] << std::noshowpos;
			}

			if(it.abilities->stats[STAT_MAGICLEVEL])
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "magic level " << std::showpos << (int32_t)it.abilities->stats[STAT_MAGICLEVEL] << std::noshowpos;
			}

			int32_t show = it.abilities->absorb[COMBAT_ALL];
			if(!show)
			{
				bool tmp = true;
				for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i <<= 1)
				{
					if(!it.abilities->absorb[i])
						continue;

					if(tmp)
					{
						tmp = false;
						if(begin)
						{
							begin = false;
							s << " (";
						}
						else
							s << ", ";

						s << "protection ";
					}
					else
						s << ", ";

					s << getCombatName((CombatType_t)i) << " " << std::showpos << it.abilities->absorb[i] << std::noshowpos << "%";
				}
			}
			else
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "protection all " << std::showpos << show << std::noshowpos << "%";
			}

			show = it.abilities->fieldAbsorb[COMBAT_ALL];
			if(!show)
			{
				bool tmp = true;
				for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i <<= 1)
				{
					if(!it.abilities->fieldAbsorb[i])
						continue;

					if(tmp)
					{
						tmp = false;
						if(begin)
						{
							begin = false;
							s << " (";
						}
						else
							s << ", ";

						s << "protection ";
					}
					else
						s << ", ";

					s << getCombatName((CombatType_t)i) << " field " << std::showpos << it.abilities->absorb[i] << std::noshowpos << "%";
				}
			}
			else
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "protection all fields " << std::showpos << show << std::noshowpos << "%";
			}

			show = it.abilities->reflect[REFLECT_CHANCE][COMBAT_ALL];
			if(!show)
			{
				bool tmp = true;
				for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i <<= 1)
				{
					if(!it.abilities->reflect[REFLECT_CHANCE][i] || !it.abilities->reflect[REFLECT_PERCENT][i])
						continue;

					if(tmp)
					{
						tmp = false;
						if(begin)
						{
							begin = false;
							s << " (";
						}
						else
							s << ", ";

						s << "reflect: ";
					}
					else
						s << ", ";

					s << it.abilities->reflect[REFLECT_CHANCE][i] << "% for ";
					if(it.abilities->reflect[REFLECT_PERCENT][i] > 99)
						s << "whole";
					else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 75)
						s << "huge";
					else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 50)
						s << "medium";
					else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 25)
						s << "small";
					else
						s << "tiny";

					s << getCombatName((CombatType_t)i);
				}

				if(!tmp)
					s << " damage";
			}
			else
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				int32_t tmp = it.abilities->reflect[REFLECT_PERCENT][COMBAT_ALL];
				s << "reflect: " << show << "% for ";
				if(tmp)
				{
					if(tmp > 99)
						s << "whole";
					else if(tmp >= 75)
						s << "huge";
					else if(tmp >= 50)
						s << "medium";
					else if(tmp >= 25)
						s << "small";
					else
						s << "tiny";
				}
				else
					s << "mixed";

				s << " damage";
			}

			if(it.abilities->speed)
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "speed " << std::showpos << (int32_t)(it.abilities->speed / 2) << std::noshowpos;
			}

			if(it.abilities->invisible)
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "invisibility";
			}

			if(it.abilities->regeneration)
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "faster regeneration";
			}

			if(it.abilities->manaShield)
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "mana shield";
			}

			if(hasBitSet(CONDITION_DRUNK, it.abilities->conditionSuppressions))
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "hard drinking";
			}
		}

		if(it.dualWield || (item && item->isDualWield()))
		{
			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			s << "dual wielding";
		}

		if(!begin)
			s << ")";
	}
	else if(it.armor || (item && item->getArmor()) || it.showAttributes)
	{
		int32_t tmp = it.armor;
		if(item)
			tmp = item->getArmor();

		bool begin = true;
		if(tmp)
		{
			s << " (Arm:" << tmp;
			begin = false;
		}

		if(it.hasAbilities())
		{
			for(uint16_t i = SKILL_FIRST; i <= SKILL_LAST; ++i)
			{
				if(!it.abilities->skills[i])
					continue;

				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << getSkillName(i) << " " << std::showpos << (int32_t)it.abilities->skills[i] << std::noshowpos;
			}

			if(it.abilities->stats[STAT_MAGICLEVEL])
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "magic level " << std::showpos << (int32_t)it.abilities->stats[STAT_MAGICLEVEL] << std::noshowpos;
			}

			int32_t show = it.abilities->absorb[COMBAT_ALL];
			if(!show)
			{
				bool tmp = true;
				for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i <<= 1)
				{
					if(!it.abilities->absorb[i])
						continue;

					if(tmp)
					{
						tmp = false;
						if(begin)
						{
							begin = false;
							s << " (";
						}
						else
							s << ", ";

						s << "protection ";
					}
					else
						s << ", ";

					s << getCombatName((CombatType_t)i) << " " << std::showpos << it.abilities->absorb[i] << std::noshowpos << "%";
				}
			}
			else
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "protection all " << std::showpos << show << std::noshowpos << "%";
			}

			show = it.abilities->reflect[REFLECT_CHANCE][COMBAT_ALL];
			if(!show)
			{
				bool tmp = true;
				for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i <<= 1)
				{
					if(!it.abilities->reflect[REFLECT_CHANCE][i] || !it.abilities->reflect[REFLECT_PERCENT][i])
						continue;

					if(tmp)
					{
						tmp = false;
						if(begin)
						{
							begin = false;
							s << " (";
						}
						else
							s << ", ";

						s << "reflect: ";
					}
					else
						s << ", ";

					s << it.abilities->reflect[REFLECT_CHANCE][i] << "% for ";
					if(it.abilities->reflect[REFLECT_PERCENT][i] > 99)
						s << "whole";
					else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 75)
						s << "huge";
					else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 50)
						s << "medium";
					else if(it.abilities->reflect[REFLECT_PERCENT][i] >= 25)
						s << "small";
					else
						s << "tiny";

					s << getCombatName((CombatType_t)i);
				}

				if(!tmp)
					s << " damage";
			}
			else
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				int32_t tmp = it.abilities->reflect[REFLECT_PERCENT][COMBAT_ALL];
				s << "reflect: " << show << "% for ";
				if(tmp)
				{
					if(tmp > 99)
						s << "whole";
					else if(tmp >= 75)
						s << "huge";
					else if(tmp >= 50)
						s << "medium";
					else if(tmp >= 25)
						s << "small";
					else
						s << "tiny";
				}
				else
					s << "mixed";

				s << " damage";
			}

			if(it.abilities->speed)
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "speed " << std::showpos << (int32_t)(it.abilities->speed / 2) << std::noshowpos;
			}

			if(it.abilities->invisible)
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "invisibility";
			}

			if(it.abilities->regeneration)
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "faster regeneration";
			}

			if(it.abilities->manaShield)
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "mana shield";
			}

			if(hasBitSet(CONDITION_DRUNK, it.abilities->conditionSuppressions))
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "hard drinking";
			}

			if(!begin)
				s << ")";
		}
	}
	else if(it.isContainer())
		s << " (Vol:" << (int32_t)it.maxItems << ")";
	else if(it.isKey())
		s << " (Key:" << (item ? (int32_t)item->getActionId() : 0) << ")";
	else if(it.isFluidContainer())
	{
		if(subType > 0)
			s << " of " << (items[subType].name.length() ? items[subType].name : "unknown");
		else
			s << ". It is empty";
	}
	else if(it.isSplash())
	{
		s << " of ";
		if(subType > 0 && items[subType].name.length())
			s << items[subType].name;
		else
			s << "unknown";
	}
	else if(it.allowDistRead)
	{
		s << "." << std::endl;
		if(item && !item->getText().empty())
		{
			if(lookDistance <= 4)
			{
				if(!item->getWriter().empty())
				{
					s << item->getWriter() << " wrote";
					time_t date = item->getDate();
					if(date > 0)
						s << " on " << formatDate(date);

					s << ": ";
				}
				else
					s << "You read: ";

				std::string text = item->getText();
				s << text;

				char end = *text.rbegin();
				if(end == '?' || end == '!' || end == '.')
					dot = false;
			}
			else
				s << "You are too far away to read it";
		}
		else
			s << "Nothing is written on it";
	}
	else if(it.levelDoor && item && item->getActionId() >= (int32_t)it.levelDoor && item->getActionId()
		<= ((int32_t)it.levelDoor + g_config.getNumber(ConfigManager::MAXIMUM_DOOR_LEVEL)))
		s << " for level " << item->getActionId() - it.levelDoor;

	if(it.showCharges)
		s << " that has " << subType << " charge" << (subType != 1 ? "s" : "") << " left";

	if(it.showDuration)
	{
		if(item && item->hasIntegerAttribute("duration"))
		{
			int32_t duration = item->getDuration() / 1000;
			s << " that will expire in ";
			if(duration >= 86400)
			{
				uint16_t days = duration / 86400;
				uint16_t hours = (duration % 86400) / 3600;
				s << days << " day" << (days > 1 ? "s" : "");
				if(hours > 0)
					s << " and " << hours << " hour" << (hours > 1 ? "s" : "");
			}
			else if(duration >= 3600)
			{
				uint16_t hours = duration / 3600;
				uint16_t minutes = (duration % 3600) / 60;
				s << hours << " hour" << (hours > 1 ? "s" : "");
				if(hours > 0)
					s << " and " << minutes << " minute" << (minutes > 1 ? "s" : "");
			}
			else if(duration >= 60)
			{
				uint16_t minutes = duration / 60;
				uint16_t seconds = duration % 60;
				s << minutes << " minute" << (minutes > 1 ? "s" : "");
				if(seconds > 0)
					s << " and " << seconds << " second" << (seconds > 1 ? "s" : "");
			}
			else
				s << duration << " second" << (duration > 1 ? "s" : "");
		}
		else
			s << " that is brand-new";
	}

	if(dot)
		s << ".";

	if(it.wieldInfo)
	{
		s << std::endl << "It can only be wielded properly by ";
		if(it.wieldInfo & WIELDINFO_PREMIUM)
			s << "premium ";

		if(it.wieldInfo & WIELDINFO_VOCREQ)
			s << it.vocationString;
		else
			s << "players";

		if(it.wieldInfo & WIELDINFO_LEVEL)
			s << " of level " << (int32_t)it.minReqLevel << " or higher";

		if(it.wieldInfo & WIELDINFO_MAGLV)
		{
			if(it.wieldInfo & WIELDINFO_LEVEL)
				s << " and";
			else
				s << " of";

			s << " magic level " << (int32_t)it.minReqMagicLevel << " or higher";
		}

		s << ".";
	}

	if(lookDistance <= 1 && it.pickupable)
	{
		std::string tmp;
		if(!item)
			tmp = getWeightDescription(it.weight, it.stackable && it.showCount, subType);
		else
			tmp = item->getWeightDescription();

		if(!tmp.empty())
			s << std::endl << tmp;
	}

	if(item && !item->getSpecialDescription().empty())
		s << std::endl << item->getSpecialDescription();
	else if(!it.description.empty() && lookDistance <= 1)
		s << std::endl << it.description;

	std::string str = s.str();
	if(str.find("|PLAYERNAME|") != std::string::npos)
	{
		std::string tmp = "You";
		if(item)
		{
			if(const Player* player = item->getHoldingPlayer())
				tmp = player->getName();
		}

		replaceString(str, "|PLAYERNAME|", tmp);
	}

	if(str.find("|TIME|") != std::string::npos || str.find("|DATE|") != std::string::npos || str.find(
		"|DAY|") != std::string::npos || str.find("|MONTH|") != std::string::npos || str.find(
		"|YEAR|") != std::string::npos || str.find("|HOUR|") != std::string::npos || str.find(
		"|MINUTES|") != std::string::npos || str.find("|SECONDS|") != std::string::npos ||
		str.find("|WEEKDAY|") != std::string::npos || str.find("|YEARDAY|") != std::string::npos)
	{
		time_t now = time(NULL);
		tm* ts = localtime(&now);

		std::stringstream ss;
		ss << ts->tm_sec;
		replaceString(str, "|SECONDS|", ss.str());

		ss.str("");
		ss << ts->tm_min;
		replaceString(str, "|MINUTES|", ss.str());

		ss.str("");
		ss << ts->tm_hour;
		replaceString(str, "|HOUR|", ss.str());

		ss.str("");
		ss << ts->tm_mday;
		replaceString(str, "|DAY|", ss.str());

		ss.str("");
		ss << (ts->tm_mon + 1);
		replaceString(str, "|MONTH|", ss.str());

		ss.str("");
		ss << (ts->tm_year + 1900);
		replaceString(str, "|YEAR|", ss.str());

		ss.str("");
		ss << ts->tm_wday;
		replaceString(str, "|WEEKDAY|", ss.str());

		ss.str("");
		ss << ts->tm_yday;
		replaceString(str, "|YEARDAY|", ss.str());

		ss.str("");
		ss << ts->tm_hour << ":" << ts->tm_min << ":" << ts->tm_sec;
		replaceString(str, "|TIME|", ss.str());

		ss.str("");
		replaceString(str, "|DATE|", formatDateEx(now));
	}

	return str;
}
Exemple #17
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 {
Exemple #18
0
void IronChain::use(Room *room, ServerPlayer *source, const QList<ServerPlayer *> &targets) const{
    if(getSkillName() != "lianhuan")
        source->playCardEffect("@tiesuo");
    TrickCard::use(room, source, targets);
}
Exemple #19
0
std::string Item::getDescription(const ItemType& it, int32_t lookDistance, const Item* item/* = NULL*/,
	int32_t subType/* = -1*/, bool addArticle/* = true*/)
{
	std::stringstream s;
	s << getNameDescription(it, item, subType, addArticle);
	if(item)
		subType = item->getSubType();

	bool dot = true;
	if(it.isRune())
	{
		s << "(";
		if(!it.runeSpellName.empty())
			s << "\"" << it.runeSpellName << "\", ";

		s << "Charges:" << subType << ")";
		if(it.runeLevel > 0 || it.runeMagLevel > 0 || (it.vocationString != "" && it.wieldInfo == 0))
		{
			s << "." << std::endl << "It can only be used";
			if(it.vocationString != "" && it.wieldInfo == 0)
				s << " by " << it.vocationString;

			bool begin = true;
			if(it.runeLevel > 0)
			{
				begin = false;
				s << " with level " << it.runeLevel;
			}

			if(it.runeMagLevel > 0)
			{
				begin = false;
				s << " " << (begin ? "with" : "and") << " magic level " << it.runeMagLevel;
			}

			if(!begin)
				s << " or higher";
		}
	}
	else if(it.weaponType != WEAPON_NONE)
	{
		bool begin = true;
		if(it.weaponType == WEAPON_DIST && it.ammoType != AMMO_NONE)
		{
			begin = false;
			s << " (Range:" << int32_t(item ? item->getShootRange() : it.shootRange);
			if(it.attack || it.extraAttack || (item && (item->getAttack() || item->getExtraAttack())))
			{
				s << ", Atk " << std::showpos << int32_t(item ? item->getAttack() : it.attack);
				if(it.extraAttack || (item && item->getExtraAttack()))
					s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos;
			}

			if(it.hitChance != -1 || (item && item->getHitChance() != -1))
				s << ", Hit% " << std::showpos << (item ? item->getHitChance() : it.hitChance) << std::noshowpos;
		}
		else if(it.weaponType != WEAPON_AMMO && it.weaponType != WEAPON_WAND)
		{
			if(it.attack || it.extraAttack || (item && (item->getAttack() || item->getExtraAttack())))
			{
				begin = false;
				s << " (Atk:";
				if(it.abilities.elementType != COMBAT_NONE && it.decayTo < 1)
				{
					s << std::max((int32_t)0, int32_t((item ? item->getAttack() : it.attack) - it.abilities.elementDamage));
					if(it.extraAttack || (item && item->getExtraAttack()))
						s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos;

					s << " physical + " << it.abilities.elementDamage << " " << getCombatName(it.abilities.elementType);
				}
				else
				{
					s << int32_t(item ? item->getAttack() : it.attack);
					if(it.extraAttack || (item && item->getExtraAttack()))
						s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos;
				}
			}

			if(it.defense || it.extraDefense || (item && (item->getDefense() || item->getExtraDefense())))
			{
				if(begin)
				{
					begin = false;
					s << " (";
				}
				else
					s << ", ";

				s << "Def:" << int32_t(item ? item->getDefense() : it.defense);
				if(it.extraDefense || (item && item->getExtraDefense()))
					s << " " << std::showpos << int32_t(item ? item->getExtraDefense() : it.extraDefense) << std::noshowpos;
			}
		}

		for(uint16_t i = SKILL_FIRST; i <= SKILL_LAST; i++)
		{
			if(!it.abilities.skills[i])
				continue;

			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			s << getSkillName(i) << " " << std::showpos << (int32_t)it.abilities.skills[i] << std::noshowpos;
		}

		if(it.abilities.stats[STAT_MAGICLEVEL])
		{
			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			s << "magic level " << std::showpos << (int32_t)it.abilities.stats[STAT_MAGICLEVEL] << std::noshowpos;
		}

		int32_t show = it.abilities.absorb[COMBAT_FIRST];
		for(uint32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i++)
		{
			if(it.abilities.absorb[i] == show)
				continue;

			show = 0;
			break;
		}

		// TODO: update to the latest (from below)
		if(!show)
		{
			bool tmp = true;
			for(uint32_t i = COMBAT_FIRST; i <= COMBAT_LAST; i++)
			{
				if(!it.abilities.absorb[i])
					continue;

				if(tmp)
				{
					if(begin)
					{
						begin = false;
						s << " (";
					}
					else
						s << ", ";

					tmp = false;
					s << "protection ";
				}
				else
					s << ", ";

				s << getCombatName((CombatType_t)i) << " " << std::showpos << it.abilities.absorb[i] << std::noshowpos << "%";
			}
		}
		else
		{
			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			s << "protection all " << std::showpos << show << std::noshowpos << "%";
		}

		if(it.abilities.speed)
		{
			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			s << "speed " << std::showpos << (int32_t)(it.abilities.speed / 2) << std::noshowpos;
		}

		if(it.dualWield || (item && item->isDualWield()))
		{
			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			s << "dual wielding";
		}

		if(!begin)
			s << ")";
	}
	else if(it.armor || (item && item->getArmor()) || it.showAttributes)
	{
		int32_t tmp = it.armor;
		if(item)
			tmp = item->getArmor();

		bool begin = true;
		if(tmp)
		{
			s << " (Arm:" << tmp;
			begin = false;
		}

		for(uint16_t i = SKILL_FIRST; i <= SKILL_LAST; i++)
		{
			if(!it.abilities.skills[i])
				continue;

			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			s << getSkillName(i) << " " << std::showpos << (int32_t)it.abilities.skills[i] << std::noshowpos;
		}

		if(it.abilities.stats[STAT_MAGICLEVEL])
		{
			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			s << "magic level " << std::showpos << (int32_t)it.abilities.stats[STAT_MAGICLEVEL] << std::noshowpos;
		}

		// TODO: we should find some better way of completing this
		int32_t show = it.abilities.absorb[COMBAT_FIRST];
		for(int32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i++)
		{
			if(it.abilities.absorb[i] == show)
				continue;

			show = 0;
			break;
		}

		if(!show)
		{
			bool tmp = true;
			for(int32_t i = COMBAT_FIRST; i <= COMBAT_LAST; i++)
			{
				if(!it.abilities.absorb[i])
					continue;

				if(tmp)
				{
					tmp = false;
					if(begin)
					{
						begin = false;
						s << " (";
					}
					else
						s << ", ";

					s << "protection ";
				}
				else
					s << ", ";

				s << getCombatName((CombatType_t)i) << " " << std::showpos << it.abilities.absorb[i] << std::noshowpos << "%";
			}
		}
		else
		{
			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			s << "protection all " << std::showpos << show << std::noshowpos << "%";
		}

		// TODO: same case as absorbs...
		show = it.abilities.reflect[REFLECT_CHANCE][COMBAT_FIRST];
		for(int32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i++)
		{
			if(it.abilities.reflect[REFLECT_CHANCE][i] == show)
				continue;

			show = 0;
			break;
		}

		if(!show)
		{
			bool tmp = true;
			for(int32_t i = COMBAT_FIRST; i <= COMBAT_LAST; i++)
			{
				if(!it.abilities.reflect[REFLECT_CHANCE][i] || !it.abilities.reflect[REFLECT_PERCENT][i])
					continue;

				if(tmp)
				{
					tmp = false;
					if(begin)
					{
						begin = false;
						s << " (";
					}
					else
						s << ", ";

					s << "reflect: ";
				}
				else
					s << ", ";

				s << it.abilities.reflect[REFLECT_CHANCE][i] << "% for ";
				if(it.abilities.reflect[REFLECT_PERCENT][i] > 99)
					s << "whole";
				else if(it.abilities.reflect[REFLECT_PERCENT][i] >= 75)
					s << "huge";
				else if(it.abilities.reflect[REFLECT_PERCENT][i] >= 50)
					s << "medium";
				else if(it.abilities.reflect[REFLECT_PERCENT][i] >= 25)
					s << "small";
				else
					s << "tiny";

				s << getCombatName((CombatType_t)i);
			}

			if(!tmp)
				s << " damage";
		}
		else
		{
			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			int32_t tmp = it.abilities.reflect[REFLECT_PERCENT][COMBAT_FIRST];
			for(int32_t i = (COMBAT_FIRST + 1); i <= COMBAT_LAST; i++)
			{
				if(it.abilities.reflect[REFLECT_PERCENT][i] == tmp)
					continue;

				tmp = 0;
				break;
			}

			s << "reflect: " << show << "% for ";
			if(tmp)
			{
				if(tmp > 99)
					s << "whole";
				else if(tmp >= 75)
					s << "huge";
				else if(tmp >= 50)
					s << "medium";
				else if(tmp >= 25)
					s << "small";
				else
					s << "tiny";
			}
			else
				s << "mixed";

			s << " damage";
		}

		if(it.abilities.speed)
		{
			if(begin)
			{
				begin = false;
				s << " (";
			}
			else
				s << ", ";

			s << "speed " << std::showpos << (int32_t)(it.abilities.speed / 2) << std::noshowpos;
		}

		if(!begin)
			s << ")";
	}
	else if(it.isContainer())
		s << " (Vol:" << (int32_t)it.maxItems << ")";
	else if(it.isKey())
		s << " (Key:" << (item ? (int32_t)item->getActionId() : 0) << ")";
	else if(it.isFluidContainer())
	{
		if(subType > 0)
			s << " of " << (items[subType].name.length() ? items[subType].name : "unknown");
		else
			s << ". It is empty";
	}
	else if(it.isSplash())
	{
		s << " of ";
		if(subType > 0 && items[subType].name.length())
			s << items[subType].name;
		else
			s << "unknown";
	}
	else if(it.allowDistRead)
	{
		s << std::endl;
		if(item && !item->getText().empty())
		{
			if(lookDistance <= 4)
			{
				if(!item->getWriter().empty())
				{
					s << item->getWriter() << " wrote";
					time_t date = item->getDate();
					if(date > 0)
						s << " on " << formatDate(date);

					s << ": ";
				}
				else
					s << "You read: ";

				std::string text = item->getText();
				s << text;
				if(!text.empty())
				{
					char end = *text.rbegin();
					if(end == '?' || end == '!' || end == '.')
						dot = false;
				}
			}
			else
				s << "You are too far away to read it";
		}
		else
			s << "Nothing is written on it";
	}
	else if(it.levelDoor && item && item->getActionId() >= (int32_t)it.levelDoor && item->getActionId()
		<= ((int32_t)it.levelDoor + g_config.getNumber(ConfigManager::MAXIMUM_DOOR_LEVEL)))
		s << " for level " << item->getActionId() - it.levelDoor;

	if(it.showCharges)
		s << " that has " << subType << " charge" << (subType != 1 ? "s" : "") << " left";

	if(it.showDuration)
	{
		if(item && item->hasIntegerAttribute("duration"))
		{
			int32_t duration = item->getDuration() / 1000;
			s << " that has energy for ";

			if(duration >= 120)
				s << duration / 60 << " minutes left";
			else if(duration > 60)
				s << "1 minute left";
			else
				s << " less than a minute left";
		}
		else
			s << " that is brand-new";
	}

	if(dot)
		s << ".";

	if(it.wieldInfo)
	{
		s << std::endl << "It can only be wielded properly by ";
		if(it.wieldInfo & WIELDINFO_PREMIUM)
			s << "premium ";

		if(it.wieldInfo & WIELDINFO_VOCREQ)
			s << it.vocationString;
		else
			s << "players";

		if(it.wieldInfo & WIELDINFO_LEVEL)
			s << " of level " << (int32_t)it.minReqLevel << " or higher";

		if(it.wieldInfo & WIELDINFO_MAGLV)
		{
			if(it.wieldInfo & WIELDINFO_LEVEL)
				s << " and";
			else
				s << " of";

			s << " magic level " << (int32_t)it.minReqMagicLevel << " or higher";
		}

		s << ".";
	}

	if(lookDistance <= 1 && it.pickupable)
	{
		std::string tmp;
		if(!item)
			tmp = getWeightDescription(it.weight, it.stackable, subType);
		else
			tmp = item->getWeightDescription();

		if(!tmp.empty())
			s << std::endl << tmp;
	}

	if(it.abilities.elementType != COMBAT_NONE && it.decayTo > 0)
	{
		s << std::endl << "It is temporarily enchanted with " << getCombatName(it.abilities.elementType) << " (";
		s << std::max((int32_t)0, int32_t((item ? item->getAttack() : it.attack) - it.abilities.elementDamage));
		if(it.extraAttack || (item && item->getExtraAttack()))
			s << " " << std::showpos << int32_t(item ? item->getExtraAttack() : it.extraAttack) << std::noshowpos;

		s << " physical + " << it.abilities.elementDamage << " " << getCombatName(it.abilities.elementType) << " damage).";
	}

	std::string str;
	if(item && !item->getSpecialDescription().empty())
		str = item->getSpecialDescription();
	else if(!it.description.empty() && lookDistance <= 1)
		str = it.description;

	if(str.empty())
		return s.str();

	if(str.find("|PLAYERNAME|") != std::string::npos)
	{
		std::string tmp = "You";
		if(item)
		{
			if(const Player* player = item->getHoldingPlayer())
				tmp = player->getName();
		}

		replaceString(str, "|PLAYERNAME|", tmp);
	}

	if(str.find("|TIME|") != std::string::npos || str.find("|DATE|") != std::string::npos || str.find(
		"|DAY|") != std::string::npos || str.find("|MONTH|") != std::string::npos || str.find(
		"|YEAR|") != std::string::npos || str.find("|HOUR|") != std::string::npos || str.find(
		"|MINUTES|") != std::string::npos || str.find("|SECONDS|") != std::string::npos ||
		str.find("|WEEKDAY|") != std::string::npos || str.find("|YEARDAY|") != std::string::npos)
	{
		time_t now = time(NULL);
		tm* ts = localtime(&now);

		std::stringstream ss;
		ss << ts->tm_sec;
		replaceString(str, "|SECONDS|", ss.str());

		ss.str("");
		ss << ts->tm_min;
		replaceString(str, "|MINUTES|", ss.str());

		ss.str("");
		ss << ts->tm_hour;
		replaceString(str, "|HOUR|", ss.str());

		ss.str("");
		ss << ts->tm_mday;
		replaceString(str, "|DAY|", ss.str());

		ss.str("");
		ss << (ts->tm_mon + 1);
		replaceString(str, "|MONTH|", ss.str());

		ss.str("");
		ss << (ts->tm_year + 1900);
		replaceString(str, "|YEAR|", ss.str());

		ss.str("");
		ss << ts->tm_wday;
		replaceString(str, "|WEEKDAY|", ss.str());

		ss.str("");
		ss << ts->tm_yday;
		replaceString(str, "|YEARDAY|", ss.str());

		ss.str("");
		ss << ts->tm_hour << ":" << ts->tm_min << ":" << ts->tm_sec;
		replaceString(str, "|TIME|", ss.str());

		ss.str("");
		replaceString(str, "|DATE|", formatDateEx(now));
	}

	s << std::endl << str;
	return s.str();
}
Exemple #20
0
void EquipCard::use(Room *room, ServerPlayer *source, QList<ServerPlayer *> &targets) const
{
    if (targets.isEmpty()) {
        CardMoveReason reason(CardMoveReason::S_REASON_USE, source->objectName(), QString(), getSkillName(), QString());
        room->moveCardTo(this, source, NULL, Player::DiscardPile, reason, true);
        return;
    }
    int equipped_id = Card::S_UNKNOWN_CARD_ID;
    ServerPlayer *target = targets.first();
    if (target->getEquip(location()))
        equipped_id = target->getEquip(location())->getEffectiveId();

    QList<CardsMoveStruct> exchangeMove;
    CardsMoveStruct move1(getEffectiveId(), target, Player::PlaceEquip, CardMoveReason(CardMoveReason::S_REASON_USE, target->objectName()));
    exchangeMove.push_back(move1);
    if (equipped_id != Card::S_UNKNOWN_CARD_ID) {
        CardsMoveStruct move2(equipped_id, NULL, Player::DiscardPile, CardMoveReason(CardMoveReason::S_REASON_CHANGE_EQUIP, target->objectName()));
        exchangeMove.push_back(move2);
    }
    LogMessage log;
    log.from = target;
    log.type = "$Install";
    log.card_str = QString::number(getEffectiveId());
    room->sendLog(log);

    room->moveCardsAtomic(exchangeMove, true);
}