2020-03-16 11:23:38 -06:00
|
|
|
#include "ChestTrap.h"
|
|
|
|
#include <vector>
|
|
|
|
#include <algorithm> // std::random_shuffle
|
2020-03-16 12:54:54 -06:00
|
|
|
#include <string.h>
|
2020-03-16 11:23:38 -06:00
|
|
|
|
|
|
|
int32 ChestTrapList::Size() {
|
|
|
|
|
|
|
|
MChestTrapList.readlock(__FUNCTION__, __LINE__);
|
|
|
|
int32 size = chesttrap_list.size();
|
|
|
|
MChestTrapList.releasereadlock(__FUNCTION__, __LINE__);
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ChestTrapList::AddChestTrap(ChestTrap* trap) {
|
|
|
|
if (trap->GetDBID() < 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
MChestTrapList.writelock(__FUNCTION__, __LINE__);
|
|
|
|
if (chesttrap_list.count(trap->GetDBID()) > 0)
|
|
|
|
{
|
|
|
|
ChestTrap* tmpTrap = chesttrap_list[trap->GetDBID()];
|
|
|
|
chesttrap_list.erase(trap->GetDBID());
|
|
|
|
safe_delete(tmpTrap);
|
|
|
|
}
|
|
|
|
|
|
|
|
chesttrap_list[trap->GetDBID()] = trap;
|
|
|
|
MChestTrapList.releasewritelock(__FUNCTION__, __LINE__);
|
|
|
|
}
|
|
|
|
|
2020-03-16 12:54:54 -06:00
|
|
|
bool ChestTrapList::GetChestTrap(int32 id, ChestTrap::ChestTrapInfo* cti) {
|
2020-03-16 11:23:38 -06:00
|
|
|
ChestTrap* res = 0;
|
|
|
|
MChestTrapList.readlock(__FUNCTION__, __LINE__);
|
|
|
|
if (chesttrap_list.count(id) > 0)
|
|
|
|
res = chesttrap_list[id];
|
|
|
|
|
2020-03-16 12:54:54 -06:00
|
|
|
memset(cti, 0, sizeof(ChestTrap::ChestTrapInfo));
|
2020-03-16 11:23:38 -06:00
|
|
|
if (res)
|
2020-03-16 13:02:10 -06:00
|
|
|
memcpy(cti, res->GetChestTrapInfo(), sizeof(ChestTrap::ChestTrapInfo));
|
2020-03-16 11:23:38 -06:00
|
|
|
MChestTrapList.releasereadlock(__FUNCTION__, __LINE__);
|
|
|
|
|
|
|
|
return cti;
|
|
|
|
}
|
|
|
|
|
2020-03-16 12:54:54 -06:00
|
|
|
bool ChestTrapList::GetNextTrap(int32 zoneid, int32 chest_difficulty, ChestTrap::ChestTrapInfo* cti)
|
2020-03-16 11:23:38 -06:00
|
|
|
{
|
|
|
|
MChestListsInUse.writelock(__FUNCTION__, __LINE__);
|
|
|
|
ChestTrapList* zoneTrapList = GetChestListByZone(zoneid);
|
|
|
|
ChestTrapList* zoneDifficultyTrapList = zoneTrapList->GetChestListByDifficulty(chest_difficulty);
|
|
|
|
|
2020-04-14 14:23:37 -06:00
|
|
|
bool ret = zoneTrapList->GetNextChestTrap(cti);
|
2020-03-16 11:23:38 -06:00
|
|
|
MChestListsInUse.releasewritelock(__FUNCTION__, __LINE__);
|
|
|
|
|
2020-04-14 14:23:37 -06:00
|
|
|
return ret;
|
2020-03-16 11:23:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void ChestTrapList::Clear() {
|
|
|
|
MChestListsInUse.writelock(__FUNCTION__, __LINE__);
|
|
|
|
ClearTraps();
|
|
|
|
ClearTrapList();
|
|
|
|
MChestListsInUse.releasewritelock(__FUNCTION__, __LINE__);
|
|
|
|
}
|
|
|
|
|
2020-03-16 12:54:54 -06:00
|
|
|
bool ChestTrapList::GetNextChestTrap(ChestTrap::ChestTrapInfo* cti) {
|
2020-03-16 11:38:55 -06:00
|
|
|
MChestTrapList.readlock(__FUNCTION__, __LINE__);
|
2020-03-16 11:23:38 -06:00
|
|
|
if (cycleItr == chesttrap_list.end())
|
|
|
|
{
|
2020-03-16 11:38:55 -06:00
|
|
|
MChestTrapList.releasereadlock(__FUNCTION__, __LINE__);
|
2020-03-16 11:23:38 -06:00
|
|
|
//re-shuffle the map, we reached the end
|
|
|
|
shuffleMap(this);
|
|
|
|
}
|
2020-03-16 11:38:55 -06:00
|
|
|
else
|
|
|
|
MChestTrapList.releasereadlock(__FUNCTION__, __LINE__);
|
2020-03-16 11:23:38 -06:00
|
|
|
|
2020-04-14 14:23:37 -06:00
|
|
|
if (cycleItr == chesttrap_list.end())
|
|
|
|
return false;
|
|
|
|
|
2020-03-16 11:38:55 -06:00
|
|
|
MChestTrapList.writelock(__FUNCTION__, __LINE__);
|
2020-03-16 11:23:38 -06:00
|
|
|
ChestTrap* trap = cycleItr->second;
|
|
|
|
|
2020-03-16 12:54:54 -06:00
|
|
|
memset(cti, 0, sizeof(ChestTrap::ChestTrapInfo));
|
2020-03-16 11:23:38 -06:00
|
|
|
if (trap)
|
2020-03-16 13:02:10 -06:00
|
|
|
memcpy(cti, trap->GetChestTrapInfo(), sizeof(ChestTrap::ChestTrapInfo));
|
2020-03-16 11:23:38 -06:00
|
|
|
|
|
|
|
cycleItr++;
|
2020-03-16 11:38:55 -06:00
|
|
|
MChestTrapList.releasewritelock(__FUNCTION__, __LINE__);
|
2020-03-16 11:23:38 -06:00
|
|
|
|
2020-03-16 12:54:54 -06:00
|
|
|
return true;
|
2020-03-16 11:23:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
ChestTrapList* ChestTrapList::GetChestListByDifficulty(int32 difficulty) {
|
2020-03-16 17:22:06 -06:00
|
|
|
ChestTrapList* usedList = 0;
|
|
|
|
|
|
|
|
int32 id = 0;
|
|
|
|
if (ChestTrapParent)
|
|
|
|
{
|
|
|
|
usedList = GetChestTrapList(ChestTrapBaseList::DIFFICULTY);
|
|
|
|
id = ChestTrapBaseList::DIFFICULTY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
usedList = GetChestTrapListByID(difficulty);
|
|
|
|
id = difficulty;
|
|
|
|
}
|
|
|
|
|
2020-03-16 11:23:38 -06:00
|
|
|
if (usedList && usedList->IsListLoaded())
|
|
|
|
return usedList;
|
|
|
|
else if (!usedList)
|
2020-03-16 17:22:06 -06:00
|
|
|
{
|
|
|
|
usedList = new ChestTrapList();
|
|
|
|
AddChestTrapList(usedList, id);
|
|
|
|
}
|
2020-03-16 11:23:38 -06:00
|
|
|
|
|
|
|
MChestTrapList.writelock(__FUNCTION__, __LINE__);
|
|
|
|
map<int32, ChestTrap*>::iterator itr;
|
|
|
|
for (itr = chesttrap_list.begin(); itr != chesttrap_list.end(); itr++) {
|
|
|
|
ChestTrap* curTrap = itr->second;
|
|
|
|
if ((curTrap->GetMinChestDifficulty() <= difficulty && difficulty <= curTrap->GetMaxChestDifficulty()) ||
|
|
|
|
(curTrap->GetMinChestDifficulty() == 0 && curTrap->GetMaxChestDifficulty() == 0))
|
|
|
|
usedList->AddChestTrap(curTrap);
|
|
|
|
}
|
|
|
|
|
|
|
|
shuffleMap(usedList);
|
|
|
|
usedList->SetListLoaded(true);
|
|
|
|
|
|
|
|
MChestTrapList.releasewritelock(__FUNCTION__, __LINE__);
|
|
|
|
|
|
|
|
return usedList;
|
|
|
|
}
|
|
|
|
|
|
|
|
ChestTrapList* ChestTrapList::GetChestListByZone(int32 zoneid) {
|
2020-03-16 17:22:06 -06:00
|
|
|
ChestTrapList* usedList = 0;
|
|
|
|
|
|
|
|
int32 id = 0;
|
|
|
|
if (ChestTrapParent)
|
|
|
|
{
|
|
|
|
usedList = GetChestTrapList(ChestTrapBaseList::ZONE);
|
|
|
|
id = ChestTrapBaseList::ZONE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
usedList = GetChestTrapListByID(zoneid);
|
|
|
|
id = zoneid;
|
|
|
|
}
|
|
|
|
|
2020-03-16 11:23:38 -06:00
|
|
|
if (usedList && usedList->IsListLoaded())
|
|
|
|
return usedList;
|
|
|
|
else if (!usedList)
|
2020-03-16 17:22:06 -06:00
|
|
|
{
|
|
|
|
usedList = new ChestTrapList();
|
|
|
|
AddChestTrapList(usedList, id);
|
|
|
|
}
|
2020-03-16 11:23:38 -06:00
|
|
|
|
|
|
|
MChestTrapList.writelock(__FUNCTION__, __LINE__);
|
|
|
|
map<int32, ChestTrap*>::iterator itr;
|
|
|
|
for (itr = chesttrap_list.begin(); itr != chesttrap_list.end(); itr++) {
|
|
|
|
ChestTrap* curTrap = itr->second;
|
|
|
|
if (curTrap->GetApplicableZoneID() == zoneid || curTrap->GetApplicableZoneID() == -1)
|
|
|
|
usedList->AddChestTrap(curTrap);
|
|
|
|
}
|
|
|
|
|
|
|
|
shuffleMap(usedList);
|
|
|
|
usedList->SetListLoaded(true);
|
|
|
|
|
|
|
|
MChestTrapList.releasewritelock(__FUNCTION__, __LINE__);
|
|
|
|
|
|
|
|
return usedList;
|
|
|
|
}
|
|
|
|
|
|
|
|
map<int32, ChestTrap*>* ChestTrapList::GetAllChestTraps() { return &chesttrap_list; }
|
|
|
|
bool ChestTrapList::IsListLoaded() { return ListLoaded; }
|
|
|
|
void ChestTrapList::SetListLoaded(bool val) { ListLoaded = val; }
|
|
|
|
|
2020-03-16 17:22:06 -06:00
|
|
|
void ChestTrapList::AddChestTrapList(ChestTrapList* traplist, int32 id) {
|
|
|
|
if (chesttrap_innerlist.count(id) > 0)
|
|
|
|
{
|
|
|
|
ChestTrapList* tmpTrapList = chesttrap_innerlist[id];
|
|
|
|
chesttrap_innerlist.erase(id);
|
|
|
|
safe_delete(tmpTrapList);
|
|
|
|
}
|
|
|
|
|
|
|
|
chesttrap_innerlist[id] = traplist;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-03-16 11:23:38 -06:00
|
|
|
ChestTrapList* ChestTrapList::GetChestTrapList(ChestTrapBaseList listName) {
|
|
|
|
ChestTrapList* ctl = 0;
|
|
|
|
MChestTrapInnerList.readlock(__FUNCTION__, __LINE__);
|
|
|
|
if (chesttrap_innerlist.count(listName) > 0)
|
|
|
|
ctl = chesttrap_innerlist[listName];
|
|
|
|
MChestTrapInnerList.releasereadlock(__FUNCTION__, __LINE__);
|
|
|
|
|
|
|
|
return ctl;
|
|
|
|
}
|
|
|
|
|
2020-03-16 17:22:06 -06:00
|
|
|
ChestTrapList* ChestTrapList::GetChestTrapListByID(int32 id) {
|
|
|
|
ChestTrapList* ctl = 0;
|
|
|
|
MChestTrapInnerList.readlock(__FUNCTION__, __LINE__);
|
|
|
|
if (chesttrap_innerlist.count(id) > 0)
|
|
|
|
ctl = chesttrap_innerlist[id];
|
|
|
|
MChestTrapInnerList.releasereadlock(__FUNCTION__, __LINE__);
|
|
|
|
|
|
|
|
return ctl;
|
|
|
|
}
|
|
|
|
|
2020-03-16 11:23:38 -06:00
|
|
|
void ChestTrapList::ClearTraps() {
|
|
|
|
MChestTrapList.writelock(__FUNCTION__, __LINE__);
|
|
|
|
map<int32, ChestTrap*>::iterator itr;
|
|
|
|
for (itr = chesttrap_list.begin(); itr != chesttrap_list.end(); itr++)
|
|
|
|
safe_delete(itr->second);
|
|
|
|
chesttrap_list.clear();
|
|
|
|
MChestTrapList.releasewritelock(__FUNCTION__, __LINE__);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ChestTrapList::ClearTrapList() {
|
|
|
|
MChestTrapInnerList.writelock(__FUNCTION__, __LINE__);
|
|
|
|
map<int32, ChestTrapList*>::iterator itr2;
|
|
|
|
for (itr2 = chesttrap_innerlist.begin(); itr2 != chesttrap_innerlist.end(); itr2++)
|
|
|
|
safe_delete(itr2->second);
|
|
|
|
chesttrap_innerlist.clear();
|
|
|
|
MChestTrapInnerList.releasewritelock(__FUNCTION__, __LINE__);
|
|
|
|
|
|
|
|
// reinstantiate the base lists (zone/difficulty/etc)
|
|
|
|
InstantiateLists(ChestTrapParent);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ChestTrapList::SetupMutexes()
|
|
|
|
{
|
|
|
|
MChestTrapList.SetName("ChestTrapList");
|
|
|
|
MChestTrapInnerList.SetName("MChestTrapInnerList");
|
|
|
|
MChestListsInUse.SetName("MChestListsInUse");
|
|
|
|
}
|
|
|
|
|
|
|
|
void ChestTrapList::InstantiateLists(bool parent)
|
|
|
|
{
|
2020-03-16 17:22:06 -06:00
|
|
|
if (parent)
|
|
|
|
{
|
|
|
|
difficultyList = new ChestTrapList(false);
|
|
|
|
zoneList = new ChestTrapList(false);
|
|
|
|
MChestTrapInnerList.writelock(__FUNCTION__, __LINE__);
|
|
|
|
chesttrap_innerlist[ChestTrapBaseList::DIFFICULTY] = difficultyList;
|
|
|
|
chesttrap_innerlist[ChestTrapBaseList::ZONE] = zoneList;
|
|
|
|
MChestTrapInnerList.releasewritelock(__FUNCTION__, __LINE__);
|
|
|
|
}
|
2020-03-16 11:23:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void ChestTrapList::shuffleMap(ChestTrapList* list) {
|
|
|
|
std::vector<ChestTrap*> tmp_chests;
|
|
|
|
|
|
|
|
map<int32, ChestTrap*>::iterator itr;
|
|
|
|
for (itr = chesttrap_list.begin(); itr != chesttrap_list.end(); itr++) {
|
|
|
|
ChestTrap* curTrap = itr->second;
|
|
|
|
tmp_chests.push_back(curTrap);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::random_shuffle(tmp_chests.begin(), tmp_chests.end());
|
|
|
|
|
|
|
|
chesttrap_list.clear();
|
|
|
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
for (std::vector<ChestTrap*>::iterator it = tmp_chests.begin(); it != tmp_chests.end(); ++it)
|
|
|
|
{
|
|
|
|
chesttrap_list[count] = *it;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
cycleItr = chesttrap_list.begin();
|
|
|
|
}
|