/* 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; }