/*
EQ2Emulator: Everquest II Server Emulator
Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
This file is part of EQ2Emulator.
EQ2Emulator 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.
EQ2Emulator 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 EQ2Emulator. If not, see .
*/
#include "Collections.h"
#include "../../common/Log.h"
#include
extern MasterCollectionList master_collection_list;
Collection::Collection() {
id = 0;
memset(name, 0, sizeof(name));
memset(category, 0, sizeof(category));
level = 0;
reward_coin = 0;
reward_xp = 0;
completed = false;
save_needed = false;
}
Collection::Collection(Collection *in) {
vector *collection_items_in;
vector *reward_items_in;
vector::iterator itr;
vector::iterator itr2;
struct CollectionItem *collection_item;
struct CollectionRewardItem *reward_item;
assert(in);
id = in->GetID();
strncpy(name, in->GetName(), sizeof(name));
strncpy(category, in->GetCategory(), sizeof(category));
level = in->GetLevel();
reward_coin = in->GetRewardCoin();
reward_xp = in->GetRewardXP();
completed = in->GetCompleted();
save_needed = in->GetSaveNeeded();
collection_items_in = in->GetCollectionItems();
for (itr = collection_items_in->begin(); itr != collection_items_in->end(); itr++) {
collection_item = new struct CollectionItem;
collection_item->item = (*itr)->item;
collection_item->index = (*itr)->index;
collection_item->found = (*itr)->found;
collection_items.push_back(collection_item);
}
reward_items_in = in->GetRewardItems();
for (itr2 = reward_items_in->begin(); itr2 != reward_items_in->end(); itr2++) {
reward_item = new struct CollectionRewardItem;
reward_item->item = (*itr2)->item;
reward_item->quantity = (*itr2)->quantity;
reward_items.push_back(reward_item);
}
reward_items_in = in->GetSelectableRewardItems();
for (itr2 = reward_items_in->begin(); itr2 != reward_items_in->end(); itr2++) {
reward_item = new struct CollectionRewardItem;
reward_item->item = (*itr2)->item;
reward_item->quantity = (*itr2)->quantity;
selectable_reward_items.push_back(reward_item);
}
}
Collection::~Collection() {
vector::iterator itr;
vector::iterator itr2;
for (itr = collection_items.begin(); itr != collection_items.end(); itr++)
safe_delete(*itr);
for (itr2 = reward_items.begin(); itr2 != reward_items.end(); itr2++)
safe_delete(*itr2);
for (itr2 = selectable_reward_items.begin(); itr2 != selectable_reward_items.end(); itr2++)
safe_delete(*itr2);
}
void Collection::AddCollectionItem(struct CollectionItem *collection_item) {
assert(collection_item);
collection_items.push_back(collection_item);
}
void Collection::AddRewardItem(struct CollectionRewardItem *reward_item) {
assert(reward_item);
reward_items.push_back(reward_item);
}
void Collection::AddSelectableRewardItem(struct CollectionRewardItem *reward_item) {
assert(reward_item);
selectable_reward_items.push_back(reward_item);
}
bool Collection::NeedsItem(Item *item) {
vector::iterator itr;
struct CollectionItem *collection_item;
assert(item);
if (completed)
return false;
for (itr = collection_items.begin(); itr != collection_items.end(); itr++) {
collection_item = *itr;
if (collection_item->item == item->details.item_id) {
if (collection_item->found)
return false;
else
return true;
}
}
/* item is not required by this collection at all */
return false;
}
struct CollectionItem * Collection::GetCollectionItemByItemID(int32 item_id) {
vector::iterator itr;
struct CollectionItem *collection_item;
for (itr = collection_items.begin(); itr != collection_items.end(); itr++) {
collection_item = *itr;
if (collection_item->item == item_id)
return collection_item;
}
return 0;
}
bool Collection::GetIsReadyToTurnIn() {
vector::iterator itr;
if (completed)
return false;
for (itr = collection_items.begin(); itr != collection_items.end(); itr++) {
if (!(*itr)->found)
return false;
}
return true;
}
MasterCollectionList::MasterCollectionList() {
mutex_collections.SetName("MasterCollectionList::collections");
}
MasterCollectionList::~MasterCollectionList() {
ClearCollections();
}
bool MasterCollectionList::AddCollection(Collection *collection) {
bool ret = false;
assert(collection);
mutex_collections.writelock(__FUNCTION__, __LINE__);
if (collections.count(collection->GetID()) == 0) {
collections[collection->GetID()] = collection;
ret = true;
}
mutex_collections.releasewritelock(__FUNCTION__, __LINE__);
return ret;
}
Collection * MasterCollectionList::GetCollection(int32 collection_id) {
Collection *collection = 0;
mutex_collections.readlock(__FUNCTION__, __LINE__);
if (collections.count(collection_id) > 0)
collection = collections[collection_id];
mutex_collections.releasereadlock(__FUNCTION__, __LINE__);
return collection;
}
void MasterCollectionList::ClearCollections() {
map::iterator itr;
mutex_collections.writelock(__FUNCTION__, __LINE__);
for (itr = collections.begin(); itr != collections.end(); itr++)
safe_delete(itr->second);
collections.clear();
mutex_collections.releasewritelock(__FUNCTION__, __LINE__);
}
int32 MasterCollectionList::Size() {
int32 size;
mutex_collections.readlock(__FUNCTION__, __LINE__);
size = collections.size();
mutex_collections.releasereadlock(__FUNCTION__, __LINE__);
return size;
}
bool MasterCollectionList::NeedsItem(Item *item) {
map::iterator itr;
bool ret = false;
assert(item);
mutex_collections.readlock(__FUNCTION__, __LINE__);
for (itr = collections.begin(); itr != collections.end(); itr++) {
if (itr->second->NeedsItem(item)) {
ret = true;
break;
}
}
mutex_collections.releasereadlock(__FUNCTION__, __LINE__);
return ret;
}
PlayerCollectionList::PlayerCollectionList() {
}
PlayerCollectionList::~PlayerCollectionList() {
ClearCollections();
}
bool PlayerCollectionList::AddCollection(Collection *collection) {
assert(collection);
if (collections.count(collection->GetID()) == 0) {
collections[collection->GetID()] = collection;
return true;
}
return false;
}
Collection * PlayerCollectionList::GetCollection(int32 collection_id) {
if (collections.count(collection_id) > 0)
return collections[collection_id];
return 0;
}
void PlayerCollectionList::ClearCollections() {
map::iterator itr;
for (itr = collections.begin(); itr != collections.end(); itr++)
safe_delete(itr->second);
collections.clear();
}
int32 PlayerCollectionList::Size() {
return collections.size();
}
bool PlayerCollectionList::NeedsItem(Item *item) {
map *master_collections;
map::iterator itr;
Collection *collection;
Mutex *master_mutex;
bool ret = false;
assert(item);
for (itr = collections.begin(); itr != collections.end(); itr++) {
if (itr->second->NeedsItem(item)) {
ret = true;
break;
}
}
/* if the player doesnt have a collection that needs the item, check the master collection list to see if there's a collection
* in there that needs the item that the player does not have yet */
if (!ret) {
master_mutex = master_collection_list.GetMutex();
master_collections = master_collection_list.GetCollections();
master_mutex->readlock(__FUNCTION__, __LINE__);
for (itr = master_collections->begin(); itr != master_collections->end(); itr++) {
collection = itr->second;
if (collection->NeedsItem(item) && !GetCollection(collection->GetID())) {
ret = true;
break;
}
}
master_mutex->releasereadlock(__FUNCTION__, __LINE__);
}
return ret;
}
bool PlayerCollectionList::HasCollectionsToHandIn() {
map::iterator itr;
for (itr = collections.begin(); itr != collections.end(); itr++) {
if (itr->second->GetIsReadyToTurnIn())
return true;
}
return false;
}