2022-03-05 12:44:06 +02:00
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "dungeon.h"
|
|
|
|
|
#include "char.h"
|
|
|
|
|
#include "char_manager.h"
|
|
|
|
|
#include "party.h"
|
|
|
|
|
#include "affect.h"
|
|
|
|
|
#include "packet.h"
|
|
|
|
|
#include "desc.h"
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#include "regen.h"
|
|
|
|
|
#include "start_position.h"
|
|
|
|
|
#include "item.h"
|
|
|
|
|
#include "item_manager.h"
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
#include "questmanager.h"
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
CDungeon::CDungeon(IdType id, int lOriginalMapIndex, int lMapIndex)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
: m_id(id),
|
|
|
|
|
m_lOrigMapIndex(lOriginalMapIndex),
|
|
|
|
|
m_lMapIndex(lMapIndex),
|
|
|
|
|
m_map_Area(SECTREE_MANAGER::instance().GetDungeonArea(lOriginalMapIndex))
|
|
|
|
|
{
|
|
|
|
|
Initialize();
|
|
|
|
|
//sys_log(0,"DUNGEON create orig %d real %d", lOriginalMapIndex, lMapIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CDungeon::~CDungeon()
|
|
|
|
|
{
|
|
|
|
|
if (m_pParty != NULL)
|
|
|
|
|
{
|
|
|
|
|
m_pParty->SetDungeon_for_Only_party (NULL);
|
|
|
|
|
}
|
|
|
|
|
//sys_log(0,"DUNGEON destroy orig %d real %d", m_lOrigMapIndex, m_lMapIndex );
|
|
|
|
|
ClearRegen();
|
|
|
|
|
event_cancel(&deadEvent);
|
|
|
|
|
// <Factor>
|
|
|
|
|
event_cancel(&exit_all_event_);
|
|
|
|
|
event_cancel(&jump_to_event_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::Initialize()
|
|
|
|
|
{
|
|
|
|
|
deadEvent = NULL;
|
|
|
|
|
// <Factor>
|
|
|
|
|
exit_all_event_ = NULL;
|
|
|
|
|
jump_to_event_ = NULL;
|
|
|
|
|
regen_id_ = 0;
|
|
|
|
|
|
|
|
|
|
m_iMobKill = 0;
|
|
|
|
|
m_iStoneKill = 0;
|
|
|
|
|
m_bUsePotion = false;
|
|
|
|
|
m_bUseRevive = false;
|
|
|
|
|
|
|
|
|
|
m_iMonsterCount = 0;
|
|
|
|
|
|
|
|
|
|
m_bExitAllAtEliminate = false;
|
|
|
|
|
m_bWarpAtEliminate = false;
|
|
|
|
|
|
|
|
|
|
m_iWarpDelay = 0;
|
|
|
|
|
m_lWarpMapIndex = 0;
|
|
|
|
|
m_lWarpX = 0;
|
|
|
|
|
m_lWarpY = 0;
|
|
|
|
|
|
|
|
|
|
m_stRegenFile = "";
|
|
|
|
|
|
|
|
|
|
m_pParty = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::SetFlag(std::string name, int value)
|
|
|
|
|
{
|
|
|
|
|
itertype(m_map_Flag) it = m_map_Flag.find(name);
|
|
|
|
|
if (it != m_map_Flag.end())
|
|
|
|
|
it->second = value;
|
|
|
|
|
else
|
|
|
|
|
m_map_Flag.insert(make_pair(name, value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int CDungeon::GetFlag(std::string name)
|
|
|
|
|
{
|
|
|
|
|
itertype(m_map_Flag) it = m_map_Flag.find(name);
|
|
|
|
|
if (it != m_map_Flag.end())
|
|
|
|
|
return it->second;
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct FSendDestPosition
|
|
|
|
|
{
|
2022-03-12 11:39:41 +02:00
|
|
|
|
FSendDestPosition(int x, int y)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
p1.bHeader = HEADER_GC_DUNGEON;
|
|
|
|
|
p1.subheader = DUNGEON_SUBHEADER_GC_DESTINATION_POSITION;
|
|
|
|
|
p2.x = x;
|
|
|
|
|
p2.y = y;
|
|
|
|
|
p1.size = sizeof(p1)+sizeof(p2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator()(LPCHARACTER ch)
|
|
|
|
|
{
|
2022-03-12 11:39:41 +02:00
|
|
|
|
ch->GetDesc()->RawPacket(&p1, sizeof(TPacketGCDungeon));
|
2022-03-05 12:44:06 +02:00
|
|
|
|
ch->GetDesc()->Packet(&p2, sizeof(TPacketGCDungeonDestPosition));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TPacketGCDungeon p1;
|
|
|
|
|
TPacketGCDungeonDestPosition p2;
|
|
|
|
|
};
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
void CDungeon::SendDestPositionToParty(LPPARTY pParty, int x, int y)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
if (m_map_pkParty.find(pParty) == m_map_pkParty.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("PARTY %u not in DUNGEON %d", pParty->GetLeaderPID(), m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FSendDestPosition f(x, y);
|
|
|
|
|
pParty->ForEachNearMember(f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct FWarpToDungeon
|
|
|
|
|
{
|
2022-03-12 11:39:41 +02:00
|
|
|
|
FWarpToDungeon(int lMapIndex, LPDUNGEON d)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
: m_lMapIndex(lMapIndex), m_pkDungeon(d)
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(lMapIndex);
|
|
|
|
|
m_x = pkSectreeMap->m_setting.posSpawn.x;
|
|
|
|
|
m_y = pkSectreeMap->m_setting.posSpawn.y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator () (LPCHARACTER ch)
|
|
|
|
|
{
|
|
|
|
|
ch->SaveExitLocation();
|
|
|
|
|
ch->WarpSet(m_x, m_y, m_lMapIndex);
|
|
|
|
|
//m_pkDungeon->IncPartyMember(ch->GetParty());
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
int m_lMapIndex;
|
|
|
|
|
int m_x;
|
|
|
|
|
int m_y;
|
2022-03-05 12:44:06 +02:00
|
|
|
|
LPDUNGEON m_pkDungeon;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void CDungeon::Join(LPCHARACTER ch)
|
|
|
|
|
{
|
|
|
|
|
if (SECTREE_MANAGER::instance().GetMap(m_lMapIndex) == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
FWarpToDungeon(m_lMapIndex, this) (ch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::JoinParty(LPPARTY pParty)
|
|
|
|
|
{
|
|
|
|
|
pParty->SetDungeon(this);
|
|
|
|
|
m_map_pkParty.insert(std::make_pair(pParty,0));
|
|
|
|
|
|
|
|
|
|
if (SECTREE_MANAGER::instance().GetMap(m_lMapIndex) == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
FWarpToDungeon f(m_lMapIndex, this);
|
|
|
|
|
pParty->ForEachOnlineMember(f);
|
|
|
|
|
//sys_log(0, "DUNGEON-PARTY join %p %p", this, pParty);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::QuitParty(LPPARTY pParty)
|
|
|
|
|
{
|
|
|
|
|
pParty->SetDungeon(NULL);
|
|
|
|
|
//sys_log(0, "DUNGEON-PARTY quit %p %p", this, pParty);
|
|
|
|
|
TPartyMap::iterator it = m_map_pkParty.find(pParty);
|
|
|
|
|
|
|
|
|
|
if (it != m_map_pkParty.end())
|
|
|
|
|
m_map_pkParty.erase(it);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EVENTINFO(dungeon_id_info)
|
|
|
|
|
{
|
|
|
|
|
CDungeon::IdType dungeon_id;
|
|
|
|
|
|
|
|
|
|
dungeon_id_info()
|
|
|
|
|
: dungeon_id(0)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
EVENTFUNC(dungeon_dead_event)
|
|
|
|
|
{
|
|
|
|
|
dungeon_id_info* info = dynamic_cast<dungeon_id_info*>( event->info );
|
|
|
|
|
|
|
|
|
|
if ( info == NULL )
|
|
|
|
|
{
|
|
|
|
|
sys_err( "dungeon_dead_event> <Factor> Null pointer" );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPDUNGEON pDungeon = CDungeonManager::instance().Find(info->dungeon_id);
|
|
|
|
|
if (pDungeon == NULL) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pDungeon->deadEvent = NULL;
|
|
|
|
|
|
|
|
|
|
CDungeonManager::instance().Destroy(info->dungeon_id);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::IncMember(LPCHARACTER ch)
|
|
|
|
|
{
|
|
|
|
|
if (m_set_pkCharacter.find(ch) == m_set_pkCharacter.end())
|
|
|
|
|
m_set_pkCharacter.insert(ch);
|
|
|
|
|
|
|
|
|
|
event_cancel(&deadEvent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::DecMember(LPCHARACTER ch)
|
|
|
|
|
{
|
|
|
|
|
itertype(m_set_pkCharacter) it = m_set_pkCharacter.find(ch);
|
|
|
|
|
|
|
|
|
|
if (it == m_set_pkCharacter.end()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_set_pkCharacter.erase(it);
|
|
|
|
|
|
|
|
|
|
if (m_set_pkCharacter.empty())
|
|
|
|
|
{
|
|
|
|
|
dungeon_id_info* info = AllocEventInfo<dungeon_id_info>();
|
|
|
|
|
info->dungeon_id = m_id;
|
|
|
|
|
|
|
|
|
|
event_cancel(&deadEvent);
|
|
|
|
|
deadEvent = event_create(dungeon_dead_event, info, PASSES_PER_SEC(10));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::IncPartyMember(LPPARTY pParty, LPCHARACTER ch)
|
|
|
|
|
{
|
|
|
|
|
//sys_log(0, "DUNGEON-PARTY inc %p %p", this, pParty);
|
|
|
|
|
TPartyMap::iterator it = m_map_pkParty.find(pParty);
|
|
|
|
|
|
|
|
|
|
if (it != m_map_pkParty.end())
|
|
|
|
|
it->second++;
|
|
|
|
|
else
|
|
|
|
|
m_map_pkParty.insert(std::make_pair(pParty,1));
|
|
|
|
|
|
|
|
|
|
IncMember(ch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::DecPartyMember(LPPARTY pParty, LPCHARACTER ch)
|
|
|
|
|
{
|
|
|
|
|
//sys_log(0, "DUNGEON-PARTY dec %p %p", this, pParty);
|
|
|
|
|
TPartyMap::iterator it = m_map_pkParty.find(pParty);
|
|
|
|
|
|
|
|
|
|
if (it == m_map_pkParty.end())
|
|
|
|
|
sys_err("cannot find party");
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
it->second--;
|
|
|
|
|
|
|
|
|
|
if (it->second == 0)
|
|
|
|
|
QuitParty(pParty);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DecMember(ch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct FWarpToPosition
|
|
|
|
|
{
|
2022-03-12 11:39:41 +02:00
|
|
|
|
int lMapIndex;
|
|
|
|
|
int x;
|
|
|
|
|
int y;
|
|
|
|
|
FWarpToPosition(int lMapIndex, int x, int y)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
: lMapIndex(lMapIndex), x(x), y(y)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
void operator()(LPENTITY ent)
|
|
|
|
|
{
|
|
|
|
|
if (!ent->IsType(ENTITY_CHARACTER)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
LPCHARACTER ch = (LPCHARACTER)ent;
|
|
|
|
|
if (!ch->IsPC()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (ch->GetMapIndex() == lMapIndex)
|
|
|
|
|
{
|
|
|
|
|
ch->Show(lMapIndex, x, y, 0);
|
|
|
|
|
ch->Stop();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ch->WarpSet(x,y,lMapIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct FWarpToPositionForce
|
|
|
|
|
{
|
2022-03-12 11:39:41 +02:00
|
|
|
|
int lMapIndex;
|
|
|
|
|
int x;
|
|
|
|
|
int y;
|
|
|
|
|
FWarpToPositionForce(int lMapIndex, int x, int y)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
: lMapIndex(lMapIndex), x(x), y(y)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
void operator()(LPENTITY ent)
|
|
|
|
|
{
|
|
|
|
|
if (!ent->IsType(ENTITY_CHARACTER)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
LPCHARACTER ch = (LPCHARACTER)ent;
|
|
|
|
|
if (!ch->IsPC()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ch->WarpSet(x,y,lMapIndex);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
void CDungeon::JumpAll(int lFromMapIndex, int x, int y)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
x *= 100;
|
|
|
|
|
y *= 100;
|
|
|
|
|
|
|
|
|
|
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(lFromMapIndex);
|
|
|
|
|
|
|
|
|
|
if (!pMap)
|
|
|
|
|
{
|
|
|
|
|
sys_err("cannot find map by index %d", lFromMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FWarpToPosition f(m_lMapIndex, x, y);
|
|
|
|
|
|
|
|
|
|
// <Factor> SECTREE::for_each -> SECTREE::for_each_entity
|
|
|
|
|
pMap->for_each(f);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
void CDungeon::WarpAll(int lFromMapIndex, int x, int y)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
x *= 100;
|
|
|
|
|
y *= 100;
|
|
|
|
|
|
|
|
|
|
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(lFromMapIndex);
|
|
|
|
|
|
|
|
|
|
if (!pMap)
|
|
|
|
|
{
|
|
|
|
|
sys_err("cannot find map by index %d", lFromMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FWarpToPositionForce f(m_lMapIndex, x, y);
|
|
|
|
|
|
|
|
|
|
// <Factor> SECTREE::for_each -> SECTREE::for_each_entity
|
|
|
|
|
pMap->for_each(f);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
void CDungeon::JumpParty(LPPARTY pParty, int lFromMapIndex, int x, int y)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
x *= 100;
|
|
|
|
|
y *= 100;
|
|
|
|
|
|
|
|
|
|
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(lFromMapIndex);
|
|
|
|
|
|
|
|
|
|
if (!pMap)
|
|
|
|
|
{
|
|
|
|
|
sys_err("cannot find map by index %d", lFromMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pParty->GetDungeon_for_Only_party() == NULL)
|
|
|
|
|
{
|
|
|
|
|
if (m_pParty == NULL)
|
|
|
|
|
{
|
|
|
|
|
m_pParty = pParty;
|
|
|
|
|
}
|
|
|
|
|
else if (m_pParty != pParty)
|
|
|
|
|
{
|
|
|
|
|
sys_err ("Dungeon already has party. Another party cannot jump in dungeon : index %d", GetMapIndex());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
pParty->SetDungeon_for_Only_party (this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FWarpToPosition f(m_lMapIndex, x, y);
|
|
|
|
|
|
|
|
|
|
pParty->ForEachOnMapMember(f, lFromMapIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::SetPartyNull()
|
|
|
|
|
{
|
|
|
|
|
m_pParty = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CDungeonManager::Destroy(CDungeon::IdType dungeon_id)
|
|
|
|
|
{
|
|
|
|
|
sys_log(0, "DUNGEON destroy : map index %u", dungeon_id);
|
|
|
|
|
LPDUNGEON pDungeon = Find(dungeon_id);
|
|
|
|
|
if (pDungeon == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
m_map_pkDungeon.erase(dungeon_id);
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
int lMapIndex = pDungeon->m_lMapIndex;
|
2022-03-05 12:44:06 +02:00
|
|
|
|
m_map_pkMapDungeon.erase(lMapIndex);
|
|
|
|
|
|
|
|
|
|
DWORD server_timer_arg = lMapIndex;
|
|
|
|
|
quest::CQuestManager::instance().CancelServerTimers(server_timer_arg);
|
|
|
|
|
|
|
|
|
|
SECTREE_MANAGER::instance().DestroyPrivateMap(lMapIndex);
|
|
|
|
|
M2_DELETE(pDungeon);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPDUNGEON CDungeonManager::Find(CDungeon::IdType dungeon_id)
|
|
|
|
|
{
|
|
|
|
|
itertype(m_map_pkDungeon) it = m_map_pkDungeon.find(dungeon_id);
|
|
|
|
|
if (it != m_map_pkDungeon.end())
|
|
|
|
|
return it->second;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
LPDUNGEON CDungeonManager::FindByMapIndex(int lMapIndex)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
itertype(m_map_pkMapDungeon) it = m_map_pkMapDungeon.find(lMapIndex);
|
|
|
|
|
if (it != m_map_pkMapDungeon.end()) {
|
|
|
|
|
return it->second;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
LPDUNGEON CDungeonManager::Create(int lOriginalMapIndex)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
DWORD lMapIndex = SECTREE_MANAGER::instance().CreatePrivateMap(lOriginalMapIndex);
|
|
|
|
|
|
|
|
|
|
if (!lMapIndex)
|
|
|
|
|
{
|
|
|
|
|
sys_log( 0, "Fail to Create Dungeon : OrginalMapindex %d NewMapindex %d", lOriginalMapIndex, lMapIndex );
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <Factor> TODO: Change id assignment, or drop it
|
|
|
|
|
CDungeon::IdType id = next_id_++;
|
|
|
|
|
while (Find(id) != NULL) {
|
|
|
|
|
id = next_id_++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPDUNGEON pDungeon = M2_NEW CDungeon(id, lOriginalMapIndex, lMapIndex);
|
|
|
|
|
if (!pDungeon)
|
|
|
|
|
{
|
|
|
|
|
sys_err("M2_NEW CDungeon failed");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
m_map_pkDungeon.insert(std::make_pair(id, pDungeon));
|
|
|
|
|
m_map_pkMapDungeon.insert(std::make_pair(lMapIndex, pDungeon));
|
|
|
|
|
|
|
|
|
|
return pDungeon;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CDungeonManager::CDungeonManager()
|
|
|
|
|
: next_id_(0)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CDungeonManager::~CDungeonManager()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::UniqueSetMaxHP(const std::string& key, int iMaxHP)
|
|
|
|
|
{
|
|
|
|
|
TUniqueMobMap::iterator it = m_map_UniqueMob.find(key);
|
|
|
|
|
if (it == m_map_UniqueMob.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Unknown Key : %s", key.c_str());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
it->second->SetMaxHP(iMaxHP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::UniqueSetHP(const std::string& key, int iHP)
|
|
|
|
|
{
|
|
|
|
|
TUniqueMobMap::iterator it = m_map_UniqueMob.find(key);
|
|
|
|
|
if (it == m_map_UniqueMob.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Unknown Key : %s", key.c_str());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
it->second->SetHP(iHP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::UniqueSetDefGrade(const std::string& key, int iGrade)
|
|
|
|
|
{
|
|
|
|
|
TUniqueMobMap::iterator it = m_map_UniqueMob.find(key);
|
|
|
|
|
if (it == m_map_UniqueMob.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Unknown Key : %s", key.c_str());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
it->second->PointChange(POINT_DEF_GRADE,iGrade - it->second->GetPoint(POINT_DEF_GRADE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::SpawnMoveUnique(const char* key, DWORD vnum, const char* pos_from, const char* pos_to)
|
|
|
|
|
{
|
|
|
|
|
TAreaMap::iterator it_to = m_map_Area.find(pos_to);
|
|
|
|
|
if (it_to == m_map_Area.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Wrong position string : %s", pos_to);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TAreaMap::iterator it_from = m_map_Area.find(pos_from);
|
|
|
|
|
if (it_from == m_map_Area.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Wrong position string : %s", pos_from);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TAreaInfo & ai = it_from->second;
|
|
|
|
|
TAreaInfo & ai_to = it_to->second;
|
|
|
|
|
int dir = ai.dir;
|
|
|
|
|
if (dir==-1)
|
|
|
|
|
dir = number(0,359);
|
|
|
|
|
|
|
|
|
|
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (pkSectreeMap == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for (int i=0;i<100;i++)
|
|
|
|
|
{
|
|
|
|
|
int dx = number(ai.sx, ai.ex);
|
|
|
|
|
int dy = number(ai.sy, ai.ey);
|
|
|
|
|
int tx = number(ai_to.sx, ai_to.ex);
|
|
|
|
|
int ty = number(ai_to.sy, ai_to.ey);
|
|
|
|
|
|
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().SpawnMob(vnum, m_lMapIndex, pkSectreeMap->m_setting.iBaseX+dx, pkSectreeMap->m_setting.iBaseY+dy, 0, false, dir);
|
|
|
|
|
|
|
|
|
|
if (ch)
|
|
|
|
|
{
|
|
|
|
|
m_map_UniqueMob.insert(make_pair(std::string(key), ch));
|
|
|
|
|
ch->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
|
|
|
|
|
ch->SetDungeon(this);
|
|
|
|
|
|
|
|
|
|
if (ch->Goto(pkSectreeMap->m_setting.iBaseX+tx, pkSectreeMap->m_setting.iBaseY+ty))
|
|
|
|
|
ch->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sys_err("Cannot spawn at %d %d", pkSectreeMap->m_setting.iBaseX+((ai.sx+ai.ex)>>1), pkSectreeMap->m_setting.iBaseY+((ai.sy+ai.ey)>>1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::SpawnUnique(const char* key, DWORD vnum, const char* pos)
|
|
|
|
|
{
|
|
|
|
|
TAreaMap::iterator it = m_map_Area.find(pos);
|
|
|
|
|
if (it == m_map_Area.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Wrong position string : %s", pos);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TAreaInfo & ai = it->second;
|
|
|
|
|
int dir = ai.dir;
|
|
|
|
|
if (dir==-1)
|
|
|
|
|
dir = number(0,359);
|
|
|
|
|
|
|
|
|
|
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (pkSectreeMap == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for (int i=0;i<100;i++)
|
|
|
|
|
{
|
|
|
|
|
int dx = number(ai.sx, ai.ex);
|
|
|
|
|
int dy = number(ai.sy, ai.ey);
|
|
|
|
|
|
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().SpawnMob(vnum, m_lMapIndex, pkSectreeMap->m_setting.iBaseX+dx, pkSectreeMap->m_setting.iBaseY+dy, 0, false, dir);
|
|
|
|
|
|
|
|
|
|
if (ch)
|
|
|
|
|
{
|
|
|
|
|
m_map_UniqueMob.insert(make_pair(std::string(key), ch));
|
|
|
|
|
ch->SetDungeon(this);
|
|
|
|
|
ch->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sys_err("Cannot spawn at %d %d", pkSectreeMap->m_setting.iBaseX+((ai.sx+ai.ex)>>1), pkSectreeMap->m_setting.iBaseY+((ai.sy+ai.ey)>>1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::SetUnique(const char* key, DWORD vid)
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().Find(vid);
|
|
|
|
|
if (ch)
|
|
|
|
|
{
|
|
|
|
|
m_map_UniqueMob.insert(make_pair(std::string(key), ch));
|
|
|
|
|
ch->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::SpawnStoneDoor(const char* key, const char* pos)
|
|
|
|
|
{
|
|
|
|
|
SpawnUnique(key, 13001, pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::SpawnWoodenDoor(const char* key, const char* pos)
|
|
|
|
|
{
|
|
|
|
|
SpawnUnique(key, 13000, pos);
|
|
|
|
|
UniqueSetMaxHP(key, 10000);
|
|
|
|
|
UniqueSetHP(key, 10000);
|
|
|
|
|
UniqueSetDefGrade(key, 300);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::PurgeUnique(const std::string& key)
|
|
|
|
|
{
|
|
|
|
|
TUniqueMobMap::iterator it = m_map_UniqueMob.find(key);
|
|
|
|
|
if (it == m_map_UniqueMob.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Unknown Key or Dead: %s", key.c_str());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
LPCHARACTER ch = it->second;
|
|
|
|
|
m_map_UniqueMob.erase(it);
|
|
|
|
|
M2_DESTROY_CHARACTER(ch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::KillUnique(const std::string& key)
|
|
|
|
|
{
|
|
|
|
|
TUniqueMobMap::iterator it = m_map_UniqueMob.find(key);
|
|
|
|
|
if (it == m_map_UniqueMob.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Unknown Key or Dead: %s", key.c_str());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
LPCHARACTER ch = it->second;
|
|
|
|
|
m_map_UniqueMob.erase(it);
|
|
|
|
|
ch->Dead();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD CDungeon::GetUniqueVid(const std::string& key)
|
|
|
|
|
{
|
|
|
|
|
TUniqueMobMap::iterator it = m_map_UniqueMob.find(key);
|
|
|
|
|
if (it == m_map_UniqueMob.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Unknown Key or Dead: %s", key.c_str());
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
LPCHARACTER ch = it->second;
|
|
|
|
|
return ch->GetVID();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float CDungeon::GetUniqueHpPerc(const std::string& key)
|
|
|
|
|
{
|
|
|
|
|
TUniqueMobMap::iterator it = m_map_UniqueMob.find(key);
|
|
|
|
|
if (it == m_map_UniqueMob.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Unknown Key : %s", key.c_str());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return (100.f*it->second->GetHP())/it->second->GetMaxHP();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::DeadCharacter(LPCHARACTER ch)
|
|
|
|
|
{
|
|
|
|
|
if (!ch->IsPC())
|
|
|
|
|
{
|
|
|
|
|
TUniqueMobMap::iterator it = m_map_UniqueMob.begin();
|
|
|
|
|
while (it!=m_map_UniqueMob.end())
|
|
|
|
|
{
|
|
|
|
|
if (it->second == ch)
|
|
|
|
|
{
|
|
|
|
|
//sys_log(0,"Dead unique %s", it->first.c_str());
|
|
|
|
|
m_map_UniqueMob.erase(it);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++it;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CDungeon::IsUniqueDead(const std::string& key)
|
|
|
|
|
{
|
|
|
|
|
TUniqueMobMap::iterator it = m_map_UniqueMob.find(key);
|
|
|
|
|
|
|
|
|
|
if (it == m_map_UniqueMob.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Unknown Key or Dead : %s", key.c_str());
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return it->second->IsDead();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::Spawn(DWORD vnum, const char* pos)
|
|
|
|
|
{
|
|
|
|
|
//sys_log(0,"DUNGEON Spawn %u %s", vnum, pos);
|
|
|
|
|
TAreaMap::iterator it = m_map_Area.find(pos);
|
|
|
|
|
|
|
|
|
|
if (it == m_map_Area.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Wrong position string : %s", pos);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TAreaInfo & ai = it->second;
|
|
|
|
|
int dir = ai.dir;
|
|
|
|
|
if (dir==-1)
|
|
|
|
|
dir = number(0,359);
|
|
|
|
|
|
|
|
|
|
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (pkSectreeMap == NULL)
|
|
|
|
|
{
|
|
|
|
|
sys_err("cannot find map by index %d", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
int dx = number(ai.sx, ai.ex);
|
|
|
|
|
int dy = number(ai.sy, ai.ey);
|
|
|
|
|
|
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().SpawnMob(vnum, m_lMapIndex, pkSectreeMap->m_setting.iBaseX+dx, pkSectreeMap->m_setting.iBaseY+dy, 0, false, dir);
|
|
|
|
|
if (ch)
|
|
|
|
|
ch->SetDungeon(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPCHARACTER CDungeon::SpawnMob(DWORD vnum, int x, int y, int dir)
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (pkSectreeMap == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
sys_log(0, "CDungeon::SpawnMob %u %d %d", vnum, x, y);
|
|
|
|
|
|
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().SpawnMob(vnum, m_lMapIndex, pkSectreeMap->m_setting.iBaseX+x*100, pkSectreeMap->m_setting.iBaseY+y*100, 0, false, dir == 0 ? -1 : (dir - 1) * 45);
|
|
|
|
|
|
|
|
|
|
if (ch)
|
|
|
|
|
{
|
|
|
|
|
ch->SetDungeon(this);
|
|
|
|
|
sys_log(0, "CDungeon::SpawnMob name %s", ch->GetName());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ch;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPCHARACTER CDungeon::SpawnMob_ac_dir(DWORD vnum, int x, int y, int dir)
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (pkSectreeMap == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
sys_log(0, "CDungeon::SpawnMob %u %d %d", vnum, x, y);
|
|
|
|
|
|
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().SpawnMob(vnum, m_lMapIndex, pkSectreeMap->m_setting.iBaseX+x*100, pkSectreeMap->m_setting.iBaseY+y*100, 0, false, dir);
|
|
|
|
|
|
|
|
|
|
if (ch)
|
|
|
|
|
{
|
|
|
|
|
ch->SetDungeon(this);
|
|
|
|
|
sys_log(0, "CDungeon::SpawnMob name %s", ch->GetName());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ch;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::SpawnNameMob(DWORD vnum, int x, int y, const char* name)
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (pkSectreeMap == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().SpawnMob(vnum, m_lMapIndex, pkSectreeMap->m_setting.iBaseX+x, pkSectreeMap->m_setting.iBaseY+y, 0, false, -1);
|
|
|
|
|
if (ch)
|
|
|
|
|
{
|
|
|
|
|
ch->SetName(name);
|
|
|
|
|
ch->SetDungeon(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
void CDungeon::SpawnGotoMob(int lFromX, int lFromY, int lToX, int lToY)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
const int MOB_GOTO_VNUM = 20039;
|
|
|
|
|
|
|
|
|
|
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (pkSectreeMap == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sys_log(0, "SpawnGotoMob %d %d to %d %d", lFromX, lFromY, lToX, lToY);
|
|
|
|
|
|
|
|
|
|
lFromX = pkSectreeMap->m_setting.iBaseX+lFromX*100;
|
|
|
|
|
lFromY = pkSectreeMap->m_setting.iBaseY+lFromY*100;
|
|
|
|
|
|
|
|
|
|
LPCHARACTER ch = CHARACTER_MANAGER::instance().SpawnMob(MOB_GOTO_VNUM, m_lMapIndex, lFromX, lFromY, 0, false, -1);
|
|
|
|
|
|
|
|
|
|
if (ch)
|
|
|
|
|
{
|
|
|
|
|
char buf[30+1];
|
2022-03-12 11:39:41 +02:00
|
|
|
|
snprintf(buf, sizeof(buf), ". %d %d", lToX, lToY);
|
2022-03-05 12:44:06 +02:00
|
|
|
|
|
|
|
|
|
ch->SetName(buf);
|
|
|
|
|
ch->SetDungeon(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
LPCHARACTER CDungeon::SpawnGroup(DWORD vnum, int x, int y, float radius, bool bAggressive, int count)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (pkSectreeMap == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int iRadius = (int) radius;
|
|
|
|
|
|
|
|
|
|
int sx = pkSectreeMap->m_setting.iBaseX + x - iRadius;
|
|
|
|
|
int sy = pkSectreeMap->m_setting.iBaseY + y - iRadius;
|
|
|
|
|
int ex = sx + iRadius;
|
|
|
|
|
int ey = sy + iRadius;
|
|
|
|
|
|
|
|
|
|
LPCHARACTER ch = NULL;
|
|
|
|
|
|
|
|
|
|
while (count--)
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER chLeader = CHARACTER_MANAGER::instance().SpawnGroup(vnum, m_lMapIndex, sx, sy, ex, ey, NULL, bAggressive, this);
|
|
|
|
|
if (chLeader && !ch)
|
|
|
|
|
ch = chLeader;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ch;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::SpawnRegen(const char* filename, bool bOnce)
|
|
|
|
|
{
|
|
|
|
|
if (!filename)
|
|
|
|
|
{
|
|
|
|
|
sys_err("CDungeon::SpawnRegen(filename=NULL, bOnce=%d) - m_lMapIndex[%d]", bOnce, m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (!pkSectreeMap)
|
|
|
|
|
{
|
|
|
|
|
sys_err("CDungeon::SpawnRegen(filename=%s, bOnce=%d) - m_lMapIndex[%d]", filename, bOnce, m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
regen_do(filename, m_lMapIndex, pkSectreeMap->m_setting.iBaseX, pkSectreeMap->m_setting.iBaseY, this, bOnce);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::AddRegen(LPREGEN regen)
|
|
|
|
|
{
|
|
|
|
|
regen->id = regen_id_++;
|
|
|
|
|
m_regen.push_back(regen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::ClearRegen()
|
|
|
|
|
{
|
|
|
|
|
for (itertype(m_regen) it = m_regen.begin(); it != m_regen.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
LPREGEN regen = *it;
|
|
|
|
|
|
|
|
|
|
event_cancel(®en->event);
|
|
|
|
|
M2_DELETE(regen);
|
|
|
|
|
}
|
|
|
|
|
m_regen.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CDungeon::IsValidRegen(LPREGEN regen, size_t regen_id) {
|
|
|
|
|
itertype(m_regen) it = std::find(m_regen.begin(), m_regen.end(), regen);
|
|
|
|
|
if (it == m_regen.end()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
LPREGEN found = *it;
|
|
|
|
|
return (found->id == regen_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::SpawnMoveGroup(DWORD vnum, const char* pos_from, const char* pos_to, int count)
|
|
|
|
|
{
|
|
|
|
|
TAreaMap::iterator it_to = m_map_Area.find(pos_to);
|
|
|
|
|
|
|
|
|
|
if (it_to == m_map_Area.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Wrong position string : %s", pos_to);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TAreaMap::iterator it_from = m_map_Area.find(pos_from);
|
|
|
|
|
|
|
|
|
|
if (it_from == m_map_Area.end())
|
|
|
|
|
{
|
|
|
|
|
sys_err("Wrong position string : %s", pos_from);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TAreaInfo & ai = it_from->second;
|
|
|
|
|
TAreaInfo & ai_to = it_to->second;
|
|
|
|
|
int dir = ai.dir;
|
|
|
|
|
|
|
|
|
|
if (dir == -1)
|
|
|
|
|
dir = number(0,359);
|
|
|
|
|
|
|
|
|
|
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (pkSectreeMap == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (count--)
|
|
|
|
|
{
|
|
|
|
|
int tx = number(ai_to.sx, ai_to.ex)+pkSectreeMap->m_setting.iBaseX;
|
|
|
|
|
int ty = number(ai_to.sy, ai_to.ey)+pkSectreeMap->m_setting.iBaseY;
|
|
|
|
|
CHARACTER_MANAGER::instance().SpawnMoveGroup(vnum, m_lMapIndex, pkSectreeMap->m_setting.iBaseX+ai.sx, pkSectreeMap->m_setting.iBaseY+ai.sy, pkSectreeMap->m_setting.iBaseX+ai.ex, pkSectreeMap->m_setting.iBaseY+ai.ey, tx, ty, NULL, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
// DUNGEON_KILL_ALL_BUG_FIX
|
|
|
|
|
struct FKillSectree
|
|
|
|
|
{
|
|
|
|
|
void operator () (LPENTITY ent)
|
|
|
|
|
{
|
|
|
|
|
if (ent->IsType(ENTITY_CHARACTER))
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER ch = (LPCHARACTER) ent;
|
|
|
|
|
|
|
|
|
|
if (!ch->IsPC() && !ch->IsPet())
|
|
|
|
|
ch->Dead();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
// END_OF_DUNGEON_KILL_ALL_BUG_FIX
|
|
|
|
|
|
|
|
|
|
struct FPurgeSectree
|
|
|
|
|
{
|
|
|
|
|
void operator () (LPENTITY ent)
|
|
|
|
|
{
|
|
|
|
|
if (ent->IsType(ENTITY_CHARACTER))
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER ch = (LPCHARACTER) ent;
|
|
|
|
|
|
|
|
|
|
if (!ch->IsPC() && !ch->IsPet()) {
|
|
|
|
|
M2_DESTROY_CHARACTER(ch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (ent->IsType(ENTITY_ITEM))
|
|
|
|
|
{
|
|
|
|
|
LPITEM item = (LPITEM) ent;
|
|
|
|
|
M2_DESTROY_ITEM(item);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
sys_err("unknown entity type %d is in dungeon", ent->GetType());
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DUNGEON_KILL_ALL_BUG_FIX
|
|
|
|
|
void CDungeon::KillAll()
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_MAP pkMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (pkMap == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
FKillSectree f;
|
|
|
|
|
pkMap->for_each(f);
|
|
|
|
|
}
|
|
|
|
|
// END_OF_DUNGEON_KILL_ALL_BUG_FIX
|
|
|
|
|
|
|
|
|
|
void CDungeon::Purge()
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_MAP pkMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
if (pkMap == NULL) {
|
|
|
|
|
sys_err("CDungeon: SECTREE_MAP not found for #%ld", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
FPurgeSectree f;
|
|
|
|
|
pkMap->for_each(f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::IncKillCount(LPCHARACTER pkKiller, LPCHARACTER pkVictim)
|
|
|
|
|
{
|
|
|
|
|
if (pkVictim->IsStone())
|
|
|
|
|
m_iStoneKill ++;
|
|
|
|
|
else
|
|
|
|
|
m_iMobKill ++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::UsePotion(LPCHARACTER ch)
|
|
|
|
|
{
|
|
|
|
|
m_bUsePotion = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::UseRevive(LPCHARACTER ch)
|
|
|
|
|
{
|
|
|
|
|
m_bUseRevive = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CDungeon::IsUsePotion()
|
|
|
|
|
{
|
|
|
|
|
return m_bUsePotion;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CDungeon::IsUseRevive()
|
|
|
|
|
{
|
|
|
|
|
return m_bUseRevive;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int CDungeon::GetKillMobCount()
|
|
|
|
|
{
|
|
|
|
|
return m_iMobKill;
|
|
|
|
|
}
|
|
|
|
|
int CDungeon::GetKillStoneCount()
|
|
|
|
|
{
|
|
|
|
|
return m_iStoneKill;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct FCountMonster
|
|
|
|
|
{
|
|
|
|
|
int n;
|
|
|
|
|
FCountMonster() : n(0) {};
|
|
|
|
|
void operator()(LPENTITY ent)
|
|
|
|
|
{
|
|
|
|
|
if (ent->IsType(ENTITY_CHARACTER))
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER ch = (LPCHARACTER) ent;
|
|
|
|
|
if (!ch->IsPC())
|
|
|
|
|
n++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int CDungeon::CountRealMonster()
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(m_lOrigMapIndex);
|
|
|
|
|
|
|
|
|
|
if (!pMap)
|
|
|
|
|
{
|
|
|
|
|
sys_err("cannot find map by index %d", m_lOrigMapIndex);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FCountMonster f;
|
|
|
|
|
|
|
|
|
|
// <Factor> SECTREE::for_each -> SECTREE::for_each_entity
|
|
|
|
|
pMap->for_each(f);
|
|
|
|
|
return f.n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct FExitDungeon
|
|
|
|
|
{
|
|
|
|
|
void operator()(LPENTITY ent)
|
|
|
|
|
{
|
|
|
|
|
if (ent->IsType(ENTITY_CHARACTER))
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER ch = (LPCHARACTER) ent;
|
|
|
|
|
|
|
|
|
|
if (ch->IsPC())
|
|
|
|
|
ch->ExitToSavedLocation();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void CDungeon::ExitAll()
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
|
|
|
|
|
if (!pMap)
|
|
|
|
|
{
|
|
|
|
|
sys_err("cannot find map by index %d", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FExitDungeon f;
|
|
|
|
|
|
|
|
|
|
// <Factor> SECTREE::for_each -> SECTREE::for_each_entity
|
|
|
|
|
pMap->for_each(f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DUNGEON_NOTICE
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
struct FNotice
|
|
|
|
|
{
|
|
|
|
|
FNotice(const char * psz) : m_psz(psz)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator() (LPENTITY ent)
|
|
|
|
|
{
|
|
|
|
|
if (ent->IsType(ENTITY_CHARACTER))
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER ch = (LPCHARACTER) ent;
|
|
|
|
|
ch->ChatPacket(CHAT_TYPE_NOTICE, "%s", m_psz);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char * m_psz;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::Notice(const char* msg)
|
|
|
|
|
{
|
|
|
|
|
sys_log(0, "XXX Dungeon Notice %p %s", this, msg);
|
|
|
|
|
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
|
|
|
|
|
if (!pMap)
|
|
|
|
|
{
|
|
|
|
|
sys_err("cannot find map by index %d", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FNotice f(msg);
|
|
|
|
|
pMap->for_each(f);
|
|
|
|
|
}
|
|
|
|
|
// END_OF_DUNGEON_NOTICE
|
|
|
|
|
|
|
|
|
|
struct FExitDungeonToStartPosition
|
|
|
|
|
{
|
|
|
|
|
void operator () (LPENTITY ent)
|
|
|
|
|
{
|
|
|
|
|
if (ent->IsType(ENTITY_CHARACTER))
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER ch = (LPCHARACTER) ent;
|
|
|
|
|
|
|
|
|
|
if (ch->IsPC())
|
|
|
|
|
{
|
|
|
|
|
PIXEL_POSITION posWarp;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD> <20><> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ƴ϶<C6B4> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20>ִ´<D6B4>.
|
|
|
|
|
if (SECTREE_MANAGER::instance().GetRecallPositionByEmpire(g_start_map[ch->GetEmpire()], ch->GetEmpire(), posWarp))
|
|
|
|
|
ch->WarpSet(posWarp.x, posWarp.y);
|
|
|
|
|
else
|
|
|
|
|
ch->ExitToSavedLocation();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void CDungeon::ExitAllToStartPosition()
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
|
|
|
|
|
if (!pMap)
|
|
|
|
|
{
|
|
|
|
|
sys_err("cannot find map by index %d", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FExitDungeonToStartPosition f;
|
|
|
|
|
|
|
|
|
|
// <Factor> SECTREE::for_each -> SECTREE::for_each_entity
|
|
|
|
|
pMap->for_each(f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EVENTFUNC(dungeon_jump_to_event)
|
|
|
|
|
{
|
|
|
|
|
dungeon_id_info * info = dynamic_cast<dungeon_id_info *>(event->info);
|
|
|
|
|
|
|
|
|
|
if ( info == NULL )
|
|
|
|
|
{
|
|
|
|
|
sys_err( "dungeon_jump_to_event> <Factor> Null pointer" );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPDUNGEON pDungeon = CDungeonManager::instance().Find(info->dungeon_id);
|
|
|
|
|
pDungeon->jump_to_event_ = NULL;
|
|
|
|
|
|
|
|
|
|
if (pDungeon)
|
|
|
|
|
pDungeon->JumpToEliminateLocation();
|
|
|
|
|
else
|
|
|
|
|
sys_err("cannot find dungeon with map index %u", info->dungeon_id);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EVENTFUNC(dungeon_exit_all_event)
|
|
|
|
|
{
|
|
|
|
|
dungeon_id_info * info = dynamic_cast<dungeon_id_info *>(event->info);
|
|
|
|
|
|
|
|
|
|
if ( info == NULL )
|
|
|
|
|
{
|
|
|
|
|
sys_err( "dungeon_exit_all_event> <Factor> Null pointer" );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPDUNGEON pDungeon = CDungeonManager::instance().Find(info->dungeon_id);
|
|
|
|
|
pDungeon->exit_all_event_ = NULL;
|
|
|
|
|
|
|
|
|
|
if (pDungeon)
|
|
|
|
|
pDungeon->ExitAll();
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::CheckEliminated()
|
|
|
|
|
{
|
|
|
|
|
if (m_iMonsterCount > 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (m_bExitAllAtEliminate)
|
|
|
|
|
{
|
|
|
|
|
sys_log(0, "CheckEliminated: exit");
|
|
|
|
|
m_bExitAllAtEliminate = false;
|
|
|
|
|
|
|
|
|
|
if (m_iWarpDelay)
|
|
|
|
|
{
|
|
|
|
|
dungeon_id_info* info = AllocEventInfo<dungeon_id_info>();
|
|
|
|
|
info->dungeon_id = m_id;
|
|
|
|
|
|
|
|
|
|
event_cancel(&exit_all_event_);
|
|
|
|
|
exit_all_event_ = event_create(dungeon_exit_all_event, info, PASSES_PER_SEC(m_iWarpDelay));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ExitAll();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (m_bWarpAtEliminate)
|
|
|
|
|
{
|
|
|
|
|
sys_log(0, "CheckEliminated: warp");
|
|
|
|
|
m_bWarpAtEliminate = false;
|
|
|
|
|
|
|
|
|
|
if (m_iWarpDelay)
|
|
|
|
|
{
|
|
|
|
|
dungeon_id_info* info = AllocEventInfo<dungeon_id_info>();
|
|
|
|
|
info->dungeon_id = m_id;
|
|
|
|
|
|
|
|
|
|
event_cancel(&jump_to_event_);
|
|
|
|
|
jump_to_event_ = event_create(dungeon_jump_to_event, info, PASSES_PER_SEC(m_iWarpDelay));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
JumpToEliminateLocation();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
sys_log(0, "CheckEliminated: none");
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
void CDungeon::SetExitAllAtEliminate(int time)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
sys_log(0, "SetExitAllAtEliminate: time %d", time);
|
|
|
|
|
m_bExitAllAtEliminate = true;
|
|
|
|
|
m_iWarpDelay = time;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
void CDungeon::SetWarpAtEliminate(int time, int lMapIndex, int x, int y, const char* regen_file)
|
2022-03-05 12:44:06 +02:00
|
|
|
|
{
|
|
|
|
|
m_bWarpAtEliminate = true;
|
|
|
|
|
m_iWarpDelay = time;
|
|
|
|
|
m_lWarpMapIndex = lMapIndex;
|
|
|
|
|
m_lWarpX = x;
|
|
|
|
|
m_lWarpY = y;
|
|
|
|
|
|
|
|
|
|
if (!regen_file || !*regen_file)
|
|
|
|
|
m_stRegenFile.clear();
|
|
|
|
|
else
|
|
|
|
|
m_stRegenFile = regen_file;
|
|
|
|
|
|
|
|
|
|
sys_log(0, "SetWarpAtEliminate: time %d map %d %dx%d regenfile %s", time, lMapIndex, x, y, m_stRegenFile.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::JumpToEliminateLocation()
|
|
|
|
|
{
|
|
|
|
|
LPDUNGEON pDungeon = CDungeonManager::instance().FindByMapIndex(m_lWarpMapIndex);
|
|
|
|
|
|
|
|
|
|
if (pDungeon)
|
|
|
|
|
{
|
|
|
|
|
pDungeon->JumpAll(m_lMapIndex, m_lWarpX, m_lWarpY);
|
|
|
|
|
|
|
|
|
|
if (!m_stRegenFile.empty())
|
|
|
|
|
{
|
|
|
|
|
pDungeon->SpawnRegen(m_stRegenFile.c_str());
|
|
|
|
|
m_stRegenFile.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// <20>Ϲ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
|
|
|
|
|
if (!pMap)
|
|
|
|
|
{
|
|
|
|
|
sys_err("no map by index %d", m_lMapIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FWarpToPosition f(m_lWarpMapIndex, m_lWarpX * 100, m_lWarpY * 100);
|
|
|
|
|
|
|
|
|
|
// <Factor> SECTREE::for_each -> SECTREE::for_each_entity
|
|
|
|
|
pMap->for_each(f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct FNearPosition
|
|
|
|
|
{
|
2022-03-12 11:39:41 +02:00
|
|
|
|
int x;
|
|
|
|
|
int y;
|
2022-03-05 12:44:06 +02:00
|
|
|
|
int dist;
|
|
|
|
|
bool ret;
|
|
|
|
|
|
2022-03-12 11:39:41 +02:00
|
|
|
|
FNearPosition(int x, int y, int d) :
|
2022-03-05 12:44:06 +02:00
|
|
|
|
x(x), y(y), dist(d), ret(true)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator()(LPENTITY ent)
|
|
|
|
|
{
|
|
|
|
|
if (ret == false)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (ent->IsType(ENTITY_CHARACTER))
|
|
|
|
|
{
|
|
|
|
|
LPCHARACTER ch = (LPCHARACTER) ent;
|
|
|
|
|
|
|
|
|
|
if (ch->IsPC())
|
|
|
|
|
{
|
|
|
|
|
if (DISTANCE_APPROX(ch->GetX() - x * 100, ch->GetY() - y * 100) > dist * 100)
|
|
|
|
|
ret = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bool CDungeon::IsAllPCNearTo(int x, int y, int dist)
|
|
|
|
|
{
|
|
|
|
|
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex);
|
|
|
|
|
|
|
|
|
|
if (!pMap)
|
|
|
|
|
{
|
|
|
|
|
sys_err("cannot find map by index %d", m_lMapIndex);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FNearPosition f(x, y, dist);
|
|
|
|
|
|
|
|
|
|
// <Factor> SECTREE::for_each -> SECTREE::for_each_entity
|
|
|
|
|
pMap->for_each(f);
|
|
|
|
|
|
|
|
|
|
return f.ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDungeon::CreateItemGroup (std::string& group_name, ItemGroup& item_group)
|
|
|
|
|
{
|
|
|
|
|
m_map_ItemGroup.insert (ItemGroupMap::value_type (group_name, item_group));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const CDungeon::ItemGroup* CDungeon::GetItemGroup (std::string& group_name)
|
|
|
|
|
{
|
|
|
|
|
ItemGroupMap::iterator it = m_map_ItemGroup.find (group_name);
|
|
|
|
|
if (it != m_map_ItemGroup.end())
|
|
|
|
|
return &(it->second);
|
|
|
|
|
else
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|