zaela-Server/zone/spawngroup.cpp

389 lines
7.8 KiB
C++
Raw Permalink Normal View History

2013-05-09 10:44:08 -04:00
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
2013-02-16 16:14:39 -08:00
2013-05-09 10:44:08 -04:00
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; version 2 of the License.
2013-05-06 13:07:41 -04:00
2013-05-09 10:44:08 -04:00
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
2013-02-16 16:14:39 -08:00
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
2013-05-09 10:44:08 -04:00
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
2013-05-06 13:07:41 -04:00
2013-05-09 10:44:08 -04:00
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2013-02-16 16:14:39 -08:00
*/
#include <fmt/format.h>
#include "../common/global_define.h"
#include "../common/types.h"
#include "entity.h"
#include "spawngroup.h"
#include "zone.h"
#include "zonedb.h"
2013-02-16 16:14:39 -08:00
extern EntityList entity_list;
extern Zone *zone;
2013-02-16 16:14:39 -08:00
SpawnEntry::SpawnEntry(uint32 in_NPCType, int in_chance, uint16 in_filter, uint8 in_npc_spawn_limit)
{
NPCType = in_NPCType;
chance = in_chance;
condition_value_filter = in_filter;
npc_spawn_limit = in_npc_spawn_limit;
2013-02-16 16:14:39 -08:00
}
SpawnGroup::SpawnGroup(
uint32 in_id,
char *name,
int in_group_spawn_limit,
float dist,
float maxx,
float minx,
float maxy,
float miny,
int delay_in,
int despawn_in,
uint32 despawn_timer_in,
2020-01-24 15:11:08 -08:00
int min_delay_in,
bool wp_spawns_in
)
{
2013-02-16 16:14:39 -08:00
id = in_id;
strn0cpy(name_, name, 120);
2013-02-16 16:14:39 -08:00
group_spawn_limit = in_group_spawn_limit;
roambox[0] = maxx;
roambox[1] = minx;
roambox[2] = maxy;
roambox[3] = miny;
roamdist = dist;
min_delay = min_delay_in;
delay = delay_in;
despawn = despawn_in;
despawn_timer = despawn_timer_in;
2020-01-24 15:11:08 -08:00
wp_spawns = wp_spawns_in;
2013-02-16 16:14:39 -08:00
}
uint32 SpawnGroup::GetNPCType(uint16 in_filter)
{
int npcType = 0;
2013-02-16 16:14:39 -08:00
int totalchance = 0;
2013-05-06 13:07:41 -04:00
if (!entity_list.LimitCheckGroup(id, group_spawn_limit)) {
return (0);
}
2013-05-06 13:07:41 -04:00
std::list<SpawnEntry *>::iterator cur, end;
std::list<SpawnEntry *> possible;
2013-02-16 16:14:39 -08:00
cur = list_.begin();
end = list_.end();
for (; cur != end; ++cur) {
2013-02-16 16:14:39 -08:00
SpawnEntry *se = *cur;
2013-05-06 13:07:41 -04:00
if (!entity_list.LimitCheckType(se->NPCType, se->npc_spawn_limit)) {
2013-02-16 16:14:39 -08:00
continue;
}
2013-05-06 13:07:41 -04:00
if (se->condition_value_filter != in_filter)
continue;
2013-02-16 16:14:39 -08:00
totalchance += se->chance;
possible.push_back(se);
}
if (totalchance == 0) {
2013-02-16 16:14:39 -08:00
return 0;
}
2013-05-06 13:07:41 -04:00
2013-02-16 16:14:39 -08:00
int32 roll = 0;
roll = zone->random.Int(0, totalchance - 1);
2013-05-06 13:07:41 -04:00
2013-02-16 16:14:39 -08:00
cur = possible.begin();
end = possible.end();
for (; cur != end; ++cur) {
2013-02-16 16:14:39 -08:00
SpawnEntry *se = *cur;
if (roll < se->chance) {
npcType = se->NPCType;
break;
}
else {
2013-02-16 16:14:39 -08:00
roll -= se->chance;
}
}
return npcType;
}
void SpawnGroup::AddSpawnEntry(SpawnEntry *newEntry)
{
list_.push_back(newEntry);
2013-02-16 16:14:39 -08:00
}
SpawnGroup::~SpawnGroup()
{
std::list<SpawnEntry *>::iterator cur, end;
2013-02-16 16:14:39 -08:00
cur = list_.begin();
end = list_.end();
for (; cur != end; ++cur) {
SpawnEntry *tmp = *cur;
2013-02-16 16:14:39 -08:00
safe_delete(tmp);
}
list_.clear();
}
SpawnGroupList::~SpawnGroupList()
{
std::map<uint32, SpawnGroup *>::iterator cur, end;
cur = m_spawn_groups.begin();
end = m_spawn_groups.end();
for (; cur != end; ++cur) {
SpawnGroup *tmp = cur->second;
2013-02-16 16:14:39 -08:00
safe_delete(tmp);
}
m_spawn_groups.clear();
2013-02-16 16:14:39 -08:00
}
void SpawnGroupList::AddSpawnGroup(SpawnGroup *new_group)
{
if (new_group == nullptr) {
2013-02-16 16:14:39 -08:00
return;
}
m_spawn_groups[new_group->id] = new_group;
2013-02-16 16:14:39 -08:00
}
SpawnGroup *SpawnGroupList::GetSpawnGroup(uint32 in_id)
{
if (m_spawn_groups.count(in_id) != 1) {
2013-05-23 20:22:42 -04:00
return nullptr;
}
return (m_spawn_groups[in_id]);
2013-02-16 16:14:39 -08:00
}
bool SpawnGroupList::RemoveSpawnGroup(uint32 in_id)
{
if (m_spawn_groups.count(in_id) != 1) {
return (false);
}
m_spawn_groups.erase(in_id);
return (true);
}
void SpawnGroupList::ReloadSpawnGroups()
{
ClearSpawnGroups();
database.LoadSpawnGroups(zone->GetShortName(), zone->GetInstanceVersion(), &zone->spawn_group_list);
}
2013-05-06 13:07:41 -04:00
void SpawnGroupList::ClearSpawnGroups()
{
m_spawn_groups.clear();
2013-02-16 16:14:39 -08:00
}
bool ZoneDatabase::LoadSpawnGroups(const char *zone_name, uint16 version, SpawnGroupList *spawn_group_list)
{
std::string query = fmt::format(
SQL(
SELECT
DISTINCT(spawngroupID),
spawngroup.name,
spawngroup.spawn_limit,
spawngroup.dist,
spawngroup.max_x,
spawngroup.min_x,
spawngroup.max_y,
spawngroup.min_y,
spawngroup.delay,
spawngroup.despawn,
spawngroup.despawn_timer,
2020-01-24 15:11:08 -08:00
spawngroup.mindelay,
spawngroup.wp_spawns
FROM
spawn2,
spawngroup
WHERE
spawn2.spawngroupID = spawngroup.ID
AND
spawn2.version = {} and zone = '{}'
),
version,
zone_name
);
auto results = QueryDatabase(query);
if (!results.Success()) {
2013-02-16 16:14:39 -08:00
return false;
}
for (auto row = results.begin(); row != results.end(); ++row) {
auto new_spawn_group = new SpawnGroup(
atoi(row[0]),
row[1],
atoi(row[2]),
atof(row[3]),
atof(row[4]),
atof(row[5]),
atof(row[6]),
atof(row[7]),
atoi(row[8]),
atoi(row[9]),
atoi(row[10]),
2020-01-24 15:11:08 -08:00
atoi(row[11]),
atoi(row[12])
);
spawn_group_list->AddSpawnGroup(new_spawn_group);
}
query = fmt::format(
SQL(
SELECT
DISTINCT
spawnentry.spawngroupID,
npcid,
chance,
condition_value_filter,
npc_types.spawn_limit
AS sl
FROM
spawnentry,
spawn2,
npc_types
WHERE
spawnentry.npcID = npc_types.id
AND
spawnentry.spawngroupID = spawn2.spawngroupID
AND
zone = '{}'),
zone_name
);
results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
2013-02-16 16:14:39 -08:00
for (auto row = results.begin(); row != results.end(); ++row) {
auto new_spawn_entry = new SpawnEntry(
atoi(row[1]),
atoi(row[2]),
atoi(row[3]),
(row[4] ? atoi(row[4]) : 0)
);
SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0]));
if (!spawn_group) {
safe_delete(new_spawn_entry);
continue;
2013-02-16 16:14:39 -08:00
}
spawn_group->AddSpawnEntry(new_spawn_entry);
}
2013-02-16 16:14:39 -08:00
return true;
}
/**
* @param spawn_group_id
* @param spawn_group_list
* @return
*/
bool ZoneDatabase::LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList *spawn_group_list)
{
std::string query = fmt::format(
SQL(
SELECT DISTINCT
(spawngroup.id),
spawngroup.name,
spawngroup.spawn_limit,
spawngroup.dist,
spawngroup.max_x,
spawngroup.min_x,
spawngroup.max_y,
spawngroup.min_y,
spawngroup.delay,
spawngroup.despawn,
spawngroup.despawn_timer,
2020-01-24 15:11:08 -08:00
spawngroup.mindelay,
spawngroup.wp_spawns
FROM
spawngroup
WHERE
spawngroup.ID = '{}'
),
spawn_group_id
);
auto results = QueryDatabase(query);
if (!results.Success()) {
2013-02-16 16:14:39 -08:00
return false;
}
2013-02-16 16:14:39 -08:00
for (auto row = results.begin(); row != results.end(); ++row) {
auto new_spawn_group = new SpawnGroup(
atoi(row[0]),
row[1],
atoi(row[2]),
atof(row[3]),
atof(row[4]),
atof(row[5]),
atof(row[6]),
atof(row[7]),
atoi(row[8]),
atoi(row[9]),
atoi(row[10]),
2020-01-24 15:11:08 -08:00
atoi(row[11]),
atoi(row[12])
);
spawn_group_list->AddSpawnGroup(new_spawn_group);
}
query = fmt::format(
SQL(
SELECT DISTINCT
(spawnentry.spawngroupID),
spawnentry.npcid,
spawnentry.chance,
spawnentry.condition_value_filter,
spawngroup.spawn_limit
FROM
spawnentry,
spawngroup
WHERE
spawnentry.spawngroupID = '{}'
AND spawngroup.spawn_limit = '0'
ORDER BY chance),
spawn_group_id
);
results = QueryDatabase(query);
if (!results.Success()) {
2013-02-16 16:14:39 -08:00
return false;
}
for (auto row = results.begin(); row != results.end(); ++row) {
auto new_spawn_entry = new SpawnEntry(
atoi(row[1]),
atoi(row[2]),
atoi(row[3]),
(row[4] ? atoi(row[4]) : 0)
);
SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0]));
if (!spawn_group) {
safe_delete(new_spawn_entry);
continue;
}
spawn_group->AddSpawnEntry(new_spawn_entry);
}
2013-02-16 16:14:39 -08:00
return true;
}