/* * Copyright 2008-2009 Ben Boeckel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ // Header include #include "Player.h" // Sigencore includes #include "Team.h" // Sigscript includes #include #include #include #include using namespace Sigscript; using namespace Sigencore; Player::Player(GameWrapper* game, Config* parent) : Client(game, parent), m_world(NULL), m_arena(NULL), m_team(new Team(game, this)), m_money(0) { } Player::~Player() { } Overworld* Player::world() const { return m_world; } bool Player::enterWorld(Overworld* world) { // TODO } void Player::exitWorld() { // TODO } Arena* Player::arena() const { return m_arena; } bool Player::enterArena(Arena* arena) { m_active.clear(); for (int i = 0; (m_active.size() < m_game->rules()->maxFight()) && (i < m_team->numMembers()); ++i) { TeamMember* member = m_team->teamMembers()[i]; if (member->currentHp()) { m_active.append(member); member->makeActive(arena); } } return (m_active.size() && Client::enterArena(arena)); } void Player::exitArena() { foreach (TeamMember* teamMember, m_active) teamMember->exitArena(); m_active.clear(); Client::exitArena(); } int Player::itemWeightTotal(const bool distinct) const { QList items = m_items.keys(); int weight = 0; foreach (ItemWrapper* item, items) weight += item->weight() * (distinct ? m_items[item] : 1); return weight; } int Player::itemWeightType(const int type, const bool distinct) const { if (type < 0) return itemWeightTotal(distinct); QList items = m_items.keys(); int weight = 0; foreach (ItemWrapper* item, items) { if (item->type()->id() == type) weight += item->weight() * (distinct ? m_items[item] : 1); } return weight; } int Player::itemWeight(const int item, const bool distinct) const { if (item < 0) return itemWeightTotal(distinct); ItemWrapper* itemd = m_game->item(item); int weight = 0; if (itemd && m_items.contains(itemd)) weight += itemd->weight() * (distinct ? m_items[itemd] : 1); return weight; } int Player::itemCountTotal(const bool distinct) const { QList items = m_items.keys(); int count = 0; foreach (ItemWrapper* item, items) count += (distinct ? m_items[item] : 1); return count; } int Player::itemCountType(const int type, const bool distinct) const { if (type < 0) return itemCountTotal(distinct); QList items = m_items.keys(); int count = 0; foreach (ItemWrapper* item, items) { if (item->type()->id() == type) count += (distinct ? m_items[item] : 1); } return count; } int Player::itemCount(const int item, const bool distinct) const { if (item < 0) return itemCountTotal(distinct); ItemWrapper* itemd = m_game->item(item); int count = 0; if (itemd && m_items.contains(itemd)) count += (distinct ? m_items[itemd] : 1); return count; } QMap Player::items(const int type) const { if (type < 0) return m_items; QMap itemMap = m_items; QList items = itemMap.keys(); foreach (ItemWrapper* item, items) { if (item->id() != type) itemMap.remove(item); } return itemMap; } int Player::giveItems(ItemWrapper* item, const int count, const bool allOrNothing) { const int id = item->id(); const QString name = item->name(); const int typeId = item->type()->id(); const QString typeName = item->type()->name(); const int addWeight = count * item->weight(); int end = 0; if (count < 0) { int minWeight = 0; int minWeightType = 0; int minWeightTotal = 0; valueOfType(QString("weight-item-minimum-%1").arg(name), &minWeight); valueOfType(QString("weight-item-type-minimum-%1").arg(typeName), &minWeightType); valueOfType("weight-item-total-minimum", &minWeightTotal); const int diffWeight = (itemWeight(id) + addWeight) - minWeight; const int diffWeightType = (itemWeightType(typeId) + addWeight) - minWeightType; const int diffWeightTotal = (itemWeight() + addWeight) - minWeightTotal; int minCount = 0; int minCountType = 0; int minCountTotal = 0; valueOfType(QString("count-item-minimum-%1").arg(name), &minCount); valueOfType(QString("count-item-type-minimum-%1").arg(typeName), &minCountType); valueOfType("count-item-total-minimum", &minCountTotal); const int diffCount = qMax(0, itemCount(id) + count) - minCount; const int diffCountType = qMax(0, itemCountType(typeId) + count) - minCountType; const int diffCountTotal = qMax(0, itemCount(-1) + count) - minCountTotal; if ((0 < diffWeight) && (0 < diffWeightType) && (0 < diffWeightTotal) && (0 < diffCount) && (0 < diffCountType) && (0 < diffCountTotal)) end = count; else if (!allOrNothing) { const int weightUnderflow = qAbs(qMin(diffWeight, qMin(diffWeightType, diffWeightTotal))); const int countUnderflow = qMax(diffCount, qMax(diffCountType, diffCountTotal)); end = count + qMax((weightUnderflow / item->weight()) - !!(weightUnderflow % item->weight()), countUnderflow); } } else if (0 < count) { int maxWeight = INT_MAX; int maxWeightType = item->type()->maxWeight(); maxWeightType = (maxWeightType == -1) ? INT_MAX : maxWeightType; int maxWeightTotal = m_game->rules()->maxTotalWeight(); maxWeightTotal = (maxWeightTotal == -1) ? INT_MAX : maxWeightTotal; valueOfType(QString("weight-item-maximum-%1").arg(name), &maxWeight); valueOfType(QString("weight-item-type-maximum-%1").arg(typeName), &maxWeightType); valueOfType("weight-item-total-maximum", &maxWeightTotal); const int diffWeight = maxWeight - (itemWeight(id) + addWeight); const int diffWeightType = maxWeight - (itemWeightType(typeId) + addWeight); const int diffWeightTotal = maxWeight - (itemWeight() + addWeight); int maxCount = item->type()->player(); int maxCountType = item->type()->player(); maxCountType = maxCountType ? maxCountType : INT_MAX; int maxCountTotal = INT_MAX; valueOfType(QString("count-item-maximum-%1").arg(name), &maxCount); valueOfType(QString("count-item-type-maximum-%1").arg(typeName), &maxCountType); valueOfType("count-item-total-maximum", &maxCountTotal); const int diffCount = maxCount - (itemCount(id) + count); const int diffCountType = maxCountType - (itemCountType(typeId) + count); const int diffCountTotal = maxCountTotal - (itemCount(-1) + count); if ((0 < diffWeight) && (0 < diffWeightType) && (0 < diffWeightTotal) && (0 < diffCount) && (0 < diffCountType) && (0 < diffCountTotal)) end = count; else if (!allOrNothing) { const int weightOverflow = qAbs(qMin(diffWeight, qMin(diffWeightType, diffWeightTotal))); const int countOverflow = qMax(diffCount, qMax(diffCountType, diffCountTotal)); end = count - qMax((weightOverflow / item->weight()) - !!(countOverflow % item->weight()), countOverflow); } } end = qBound(qMin(0, count), end, qMax(count, 0)); if (end) { m_items[item] += end; emit(itemsGiven(item, end)); } return count - end; } bool Player::giveMoney(const int amount, const bool allOrNothing) { int playerMin = 0; int playerMax = m_game->rules()->maxMoney(); valueOfType("money-minimum", &playerMin); valueOfType("money-maximum", &playerMax); const int newUnbounded = m_money + amount; const int newAmount = qBound(qMax(0, playerMin), newUnbounded, qMin(playerMax, INT_MAX)); if (allOrNothing || (newUnbounded == newAmount)) { m_money = newAmount; emit(moneyChanged(m_money)); } return qAbs(newUnbounded - newAmount); } Team* Player::team() const { return m_team; } TeamMember* Player::findMember(const QUuid& id) const { return m_team->findTeamMember(id); } QList Player::active() const { return m_active; } void Player::switchOut(TeamMember* oldActive, TeamMember* newActive) { oldActive->exitArena(); newActive->makeActive(m_arena); m_active.removeAll(oldActive); m_active.append(newActive); } bool Player::isKnockedOut() const { return m_team->isKnockedOut(); } int Player::money() const { return m_money; }