Added support to create duplicated zones of public zones (non city zone). Additionally spawn locations can be limited to the primary public zone and not replicated (for epics).
This commit is contained in:
parent
7f138c5bef
commit
42173ceef2
@ -793,7 +793,7 @@ void Entity::GetWeaponDamage(Item* item, int32* low_damage, int32* high_damage)
|
||||
|
||||
Skill* masterySkill = ((Player*)this)->skill_list.GetSkill(item->generic_info.skill_req2);
|
||||
if(masterySkill) {
|
||||
LogWrite(PLAYER__ERROR, 0, "Player", "Item has skill %s %u requirement", masterySkill->name.data.c_str(), item->generic_info.skill_req2);
|
||||
LogWrite(PLAYER__DEBUG, 0, "Player", "Item %s has skill %s %u requirement", item->name.c_str(), masterySkill->name.data.c_str(), item->generic_info.skill_req2);
|
||||
int16 skillID = master_item_list.GetItemStatIDByName(masterySkill->name.data);
|
||||
int32 skill_chance = (int32)CalculateSkillWithBonus((char*)masterySkill->name.data.c_str(), master_item_list.GetItemStatIDByName(masterySkill->name.data), false);
|
||||
if(skill_chance >= min_level_skill && skill_chance < rec_level_skill) {
|
||||
|
@ -1623,6 +1623,7 @@ void LuaInterface::DeletePendingSpells(bool all) {
|
||||
for (del_itr = tmp_deletes.begin(); del_itr != tmp_deletes.end(); del_itr++) {
|
||||
spell = *del_itr;
|
||||
|
||||
spells_pending_delete.erase(spell);
|
||||
SetLuaUserDataStale(spell);
|
||||
RemoveCurrentSpell(spell->state, spell, false);
|
||||
|
||||
@ -1639,9 +1640,10 @@ void LuaInterface::DeletePendingSpells(bool all) {
|
||||
if(!targetZone)
|
||||
continue;
|
||||
|
||||
spellDeleted = true;
|
||||
|
||||
if(!spellDeleted)
|
||||
targetZone->GetSpellProcess()->DeleteActiveSpell(spell, true);
|
||||
|
||||
spellDeleted = true;
|
||||
}
|
||||
spell->MSpellTargets.releasereadlock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
@ -1651,8 +1653,6 @@ void LuaInterface::DeletePendingSpells(bool all) {
|
||||
}
|
||||
}
|
||||
|
||||
spells_pending_delete.erase(spell);
|
||||
|
||||
if (spell->spell->IsCopiedSpell())
|
||||
{
|
||||
RemoveCustomSpell(spell->spell->GetSpellID());
|
||||
@ -2694,7 +2694,7 @@ bool LuaInterface::RunRegionScript(string script_name, const char* function_name
|
||||
void LuaInterface::AddPendingSpellDelete(LuaSpell* spell) {
|
||||
MSpellDelete.lock();
|
||||
if ( spells_pending_delete.count(spell) == 0 )
|
||||
spells_pending_delete[spell] = Timer::GetCurrentTime2() + 10000;
|
||||
spells_pending_delete[spell] = Timer::GetCurrentTime2() + 100;
|
||||
MSpellDelete.unlock();
|
||||
}
|
||||
|
||||
|
@ -362,6 +362,8 @@ void RuleManager::Init()
|
||||
RULE_INIT(R_Zone, UseMapUnderworldCoords, "1"); // use maps lowest Y coordinate to establish underworld markers
|
||||
RULE_INIT(R_Zone, MapUnderworldCoordOffset, "-200.0"); // adds (or in the case of negative value subtracts) so that the underworld marker is lower when map is using its lowest Y coordinate
|
||||
|
||||
RULE_INIT(R_Zone, SharedZoneMaxPlayers, "30"); // max players in a shared zone (non instanced) before splitting to another zone, city_zone flagged are exempt
|
||||
|
||||
RULE_INIT(R_Loot, LootRadius, "5.0");
|
||||
RULE_INIT(R_Loot, AutoDisarmChest, "1");
|
||||
RULE_INIT(R_Loot, ChestTriggerRadiusGroup, "10.0"); // radius at which chest will trigger against group members
|
||||
|
@ -208,6 +208,7 @@ enum RuleType {
|
||||
HOTime,
|
||||
UseMapUnderworldCoords,
|
||||
MapUnderworldCoordOffset,
|
||||
SharedZoneMaxPlayers,
|
||||
|
||||
/* LOOT */
|
||||
LootRadius,
|
||||
|
@ -150,6 +150,7 @@ Spawn::Spawn(){
|
||||
reset_movement = false;
|
||||
respawn_offset_low = 0;
|
||||
respawn_offset_high = 0;
|
||||
duplicated_spawn = true;
|
||||
ResetKnockedBack();
|
||||
}
|
||||
|
||||
|
@ -905,7 +905,8 @@ public:
|
||||
void SetRespawnOffsetLow(sint32 time);
|
||||
sint32 GetRespawnOffsetHigh();
|
||||
void SetRespawnOffsetHigh(sint32 time);
|
||||
|
||||
bool DuplicatedSpawn() { return duplicated_spawn; }
|
||||
void SetDuplicateSpawn(bool val) { duplicated_spawn = val; }
|
||||
int32 GetExpireTime() { return expire_time; }
|
||||
void SetExpireTime(int32 new_expire_time) { expire_time = new_expire_time; }
|
||||
int32 GetExpireOffsetTime();
|
||||
@ -1505,6 +1506,7 @@ private:
|
||||
int32 respawn;
|
||||
sint32 respawn_offset_low;
|
||||
sint32 respawn_offset_high;
|
||||
bool duplicated_spawn;
|
||||
int32 expire_time;
|
||||
int32 expire_offset;
|
||||
float x_offset;
|
||||
|
@ -48,6 +48,7 @@ struct SpawnEntry{
|
||||
int32 respawn;
|
||||
sint32 respawn_offset_low;
|
||||
sint32 respawn_offset_high;
|
||||
bool duplicated_spawn;
|
||||
int32 expire_time;
|
||||
int32 expire_offset;
|
||||
//devn00b: added spawn location overrides, added these to accomodate.
|
||||
|
@ -23,9 +23,11 @@ along with EQ2Emu. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "../net.h"
|
||||
#include "../PlayerGroups.h"
|
||||
#include "HTTPSClientPool.h"
|
||||
#include "../Rules/Rules.h"
|
||||
|
||||
extern NetConnection net;
|
||||
extern HTTPSClientPool peer_https_pool;
|
||||
extern RuleManager rule_manager;
|
||||
|
||||
// HealthCheck method definitions
|
||||
void HealthCheck::updateStatus(HealthStatus newStatus) {
|
||||
@ -215,7 +217,10 @@ std::string PeerManager::getZonePeerId(const std::string& inc_zone_name, int32 i
|
||||
match = true;
|
||||
}
|
||||
|
||||
if(!instance_zone && num_players >= 30 && !city_zone) {
|
||||
int32 max_players = rule_manager.GetZoneRule(zone_id, R_Zone, SharedZoneMaxPlayers)->GetInt32();
|
||||
if(max_players < 1) // default of 30
|
||||
max_players = 30;
|
||||
if(!instance_zone && num_players >= max_players && !city_zone) {
|
||||
match = false;
|
||||
setZonePeerData(opt_details, peerId, peer->worldAddr, peer->internalWorldAddr, peer->worldPort, peer->webAddr, peer->webPort, zone_file_name, zone_name, zone_id, instance_id,
|
||||
safe_x, safe_y, safe_z, safe_heading, lock_state, min_status, min_level, max_level, min_version, default_lockout_time, default_reenter_time, instance_type, num_players, city_zone);
|
||||
@ -239,6 +244,50 @@ std::string PeerManager::getZonePeerId(const std::string& inc_zone_name, int32 i
|
||||
return fullZoneId;
|
||||
}
|
||||
|
||||
int32 PeerManager::getZoneHighestDuplicateId(const std::string& inc_zone_name, int32 inc_zone_id) {
|
||||
int32 highestID = 0;
|
||||
bool matched_zone = false;
|
||||
for (auto& [peerId, peer] : peers) {
|
||||
if (peer->healthCheck.status != HealthStatus::OK)
|
||||
continue;
|
||||
try {
|
||||
std::lock_guard<std::mutex> lock(peer->dataMutex);
|
||||
for (const auto& zone : peer->zone_tree->get_child("Zones")) {
|
||||
// Access each field within the current zone
|
||||
std::string zone_name = zone.second.get<std::string>("zone_name");
|
||||
bool instance_zone = zone.second.get<std::string>("instance_zone") == "true";
|
||||
std::string zone_file_name = zone.second.get<std::string>("zone_file_name");
|
||||
int32 zone_id = zone.second.get<int32>("zone_id");
|
||||
int32 instance_id = zone.second.get<int32>("instance_id");
|
||||
int32 duplicate_id = zone.second.get<int32>("duplicated_id");
|
||||
|
||||
bool match = false;
|
||||
if (!instance_zone && inc_zone_id > 0 && zone_id == inc_zone_id) {
|
||||
match = true;
|
||||
}
|
||||
else if (!instance_zone && inc_zone_name.length() > 0 && strncasecmp(zone_name.c_str(), inc_zone_name.c_str(), inc_zone_name.length()) == 0) {
|
||||
match = true;
|
||||
}
|
||||
|
||||
if (match) {
|
||||
matched_zone = true;
|
||||
if(duplicate_id > highestID)
|
||||
highestID = duplicate_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
LogWrite(PEERING__ERROR, 0, "Peering", "%s: Error Parsing Zones for %s:%u", __FUNCTION__, peer->webAddr.c_str(), peer->webPort);
|
||||
}
|
||||
}
|
||||
|
||||
if(matched_zone) {
|
||||
highestID++;
|
||||
}
|
||||
|
||||
return highestID;
|
||||
}
|
||||
|
||||
void PeerManager::handlePrimaryConflict(const std::string& reconnectingPeerId) {
|
||||
// Compare IDs or priorities to decide on the primary role
|
||||
auto currentPrimary = getCurrentPrimary();
|
||||
|
@ -182,6 +182,7 @@ public:
|
||||
void SendPeersGuildChannelMessage(int32 guild_id, std::string fromName, std::string message, int16 channel, int32 language_id = 0);
|
||||
void sendZonePeerList(Client* client);
|
||||
std::string getZonePeerId(const std::string& inc_zone_name, int32 inc_zone_id, int32 inc_instance_id, ZoneChangeDetails* opt_details = nullptr, bool only_always_loaded = false);
|
||||
int32 getZoneHighestDuplicateId(const std::string& inc_zone_name, int32 inc_zone_id);
|
||||
void setZonePeerData(ZoneChangeDetails* opt_details);
|
||||
void setPrimary(const std::string& id);
|
||||
bool hasPrimary();
|
||||
|
@ -504,6 +504,7 @@ void ZoneList::PopulateZoneList(boost::property_tree::ptree& pt) {
|
||||
zone_pt.put("instance_type", static_cast<int8>(tmp->GetInstanceType()));
|
||||
zone_pt.put("always_loaded", tmp->AlwaysLoaded());
|
||||
zone_pt.put("duplicated_zone", tmp->DuplicatedZone());
|
||||
zone_pt.put("duplicated_id", tmp->DuplicatedID());
|
||||
|
||||
maintree.push_back(std::make_pair("", zone_pt));
|
||||
}
|
||||
@ -629,6 +630,7 @@ void World::Web_worldhandle_startzone(const http::request<http::string_body>& re
|
||||
int32 zoneId = 0;
|
||||
std::string zoneName("");
|
||||
bool alwaysLoaded = false, duplicatedZone = false;
|
||||
int32 duplicatedID = 0;
|
||||
int32 minLevel = 0, maxLevel = 0, avgLevel = 0, firstLevel = 0;
|
||||
if (auto inst_id = json_tree.get_optional<int32>("instance_id")) {
|
||||
instanceId = inst_id.get();
|
||||
@ -650,6 +652,10 @@ void World::Web_worldhandle_startzone(const http::request<http::string_body>& re
|
||||
duplicatedZone = duplicated_zone.get();
|
||||
}
|
||||
|
||||
if (auto duplicated_id = json_tree.get_optional<int32>("duplicated_id")) {
|
||||
duplicatedID = duplicated_id.get();
|
||||
}
|
||||
|
||||
if (auto level = json_tree.get_optional<int32>("min_level")) {
|
||||
minLevel = level.get();
|
||||
}
|
||||
@ -672,7 +678,16 @@ void World::Web_worldhandle_startzone(const http::request<http::string_body>& re
|
||||
if (!instanceId) {
|
||||
if ((zone_list.GetZone(&details, zoneId, zoneName, true, false, false, false, false, alwaysLoaded, false, duplicatedZone))) {
|
||||
if(details.zonePtr) {
|
||||
((ZoneServer*)details.zonePtr)->SetDuplicatedZone(duplicatedZone);
|
||||
ZoneServer* tmpZone = ((ZoneServer*)details.zonePtr);
|
||||
tmpZone->SetDuplicatedZone(duplicatedZone);
|
||||
tmpZone->SetDuplicatedID(duplicatedID);
|
||||
if(duplicatedZone) {
|
||||
std::string desc = "";
|
||||
if(tmpZone->GetZoneDescription())
|
||||
desc = std::string(tmpZone->GetZoneDescription());
|
||||
desc += " " + std::to_string(duplicatedID);
|
||||
tmpZone->SetZoneDescription((char*)desc.c_str());
|
||||
}
|
||||
}
|
||||
success = 1;
|
||||
}
|
||||
|
@ -699,8 +699,12 @@ bool ZoneList::GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::
|
||||
if(!check_instances && tmp->IsInstanceZone())
|
||||
continue;
|
||||
|
||||
int32 max_players = rule_manager.GetZoneRule(tmp->GetZoneID(), R_Zone, SharedZoneMaxPlayers)->GetInt32();
|
||||
if(max_players < 1) // default of 30
|
||||
max_players = 30;
|
||||
|
||||
if(!tmp->isZoneShuttingDown() && ((opt_zone_id > 0 && tmp->GetZoneID() == opt_zone_id) || (opt_zone_name.length() > 0 && strncasecmp(tmp->GetZoneName(), opt_zone_name.c_str(), opt_zone_name.length())==0))){
|
||||
if(tmp->NumPlayers() < 30 || tmp->IsCityZone()) {
|
||||
if(tmp->NumPlayers() < max_players || tmp->IsCityZone()) {
|
||||
ret = tmp;
|
||||
if(increment_zone) {
|
||||
ret->IncrementIncomingClients();
|
||||
@ -719,8 +723,10 @@ bool ZoneList::GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::
|
||||
if(!ret && check_peers) {
|
||||
std::string peerId = peer_manager.getZonePeerId(opt_zone_name, opt_zone_id, 0, zone_details, only_always_loaded);
|
||||
if(peerId.size() > 0) {
|
||||
|
||||
if(zone_details->instanceType == 0 && zone_details->numPlayers >= 30 && !zone_details->isCityZone) {
|
||||
int32 max_players = rule_manager.GetZoneRule(zone_details->zoneId, R_Zone, SharedZoneMaxPlayers)->GetInt32();
|
||||
if(max_players < 1) // default of 30
|
||||
max_players = 30;
|
||||
if(zone_details->instanceType == 0 && zone_details->numPlayers >= max_players && !zone_details->isCityZone) {
|
||||
LogWrite(WORLD__WARNING, 0, "World", "Peer %s is providing zone %s for zone %s id %u, however the zone is full, omitting result.", peerId.c_str(), zone_details->zoneName.c_str(), opt_zone_name.c_str(), opt_zone_id);
|
||||
hadFullZone = true;
|
||||
}
|
||||
@ -750,6 +756,7 @@ bool ZoneList::GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::
|
||||
root.put("zone_id", std::to_string(opt_zone_id));
|
||||
root.put("always_loaded", only_always_loaded);
|
||||
root.put("duplicated_zone", hadFullZone);
|
||||
root.put("duplicated_id", zone_list.GetHighestDuplicateID(opt_zone_name, opt_zone_id));
|
||||
|
||||
root.put("min_level", minLevel);
|
||||
root.put("max_level", maxLevel);
|
||||
@ -772,6 +779,14 @@ bool ZoneList::GetZone(ZoneChangeDetails* zone_details, int32 opt_zone_id, std::
|
||||
tmp = new ZoneServer(opt_zone_name.c_str());
|
||||
database.LoadZoneInfo(tmp, minLevel, maxLevel, avgLevel, firstLevel);
|
||||
tmp->SetDuplicatedZone(hadFullZone);
|
||||
if(hadFullZone) {
|
||||
tmp->SetDuplicatedID(zone_list.GetHighestDuplicateID(opt_zone_name, opt_zone_id));
|
||||
std::string desc = "";
|
||||
if(tmp->GetZoneDescription())
|
||||
desc = std::string(tmp->GetZoneDescription());
|
||||
desc += " " + std::to_string(tmp->DuplicatedID());
|
||||
tmp->SetZoneDescription((char*)desc.c_str());
|
||||
}
|
||||
tmp->Init();
|
||||
tmp->SetAlwaysLoaded(only_always_loaded);
|
||||
}
|
||||
@ -835,6 +850,8 @@ bool ZoneList::GetZoneByInstance(ZoneChangeDetails* zone_details, int32 instance
|
||||
root.put("zone_name", zonename);
|
||||
root.put("zone_id", std::to_string(zone_id));
|
||||
root.put("always_loaded", false);
|
||||
root.put("duplicated_zone", false); // instances dont duplicate, only shared zones
|
||||
root.put("duplicated_id", 0);
|
||||
|
||||
root.put("min_level", minLevel);
|
||||
root.put("max_level", maxLevel);
|
||||
@ -1590,6 +1607,40 @@ void ZoneList::ReloadSpawns() {
|
||||
MZoneList.releasereadlock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
|
||||
int32 ZoneList::GetHighestDuplicateID(const std::string& inc_zone_name, int32 inc_zone_id)
|
||||
{
|
||||
list<ZoneServer*>::iterator zone_iter;
|
||||
ZoneServer* tmp = 0;
|
||||
int32 highest_id = peer_manager.getZoneHighestDuplicateId(inc_zone_name, inc_zone_id);
|
||||
MZoneList.readlock(__FUNCTION__, __LINE__);
|
||||
bool match = false;
|
||||
bool matched_peer = (highest_id>0);
|
||||
for(zone_iter=zlist.begin(); zone_iter!=zlist.end(); zone_iter++)
|
||||
{
|
||||
tmp = *zone_iter;
|
||||
|
||||
if(tmp->IsInstanceZone())
|
||||
continue;
|
||||
|
||||
if(((inc_zone_id > 0 && tmp->GetZoneID() == inc_zone_id) || (inc_zone_name.length() > 0 && strncasecmp(tmp->GetZoneName(), inc_zone_name.c_str(), inc_zone_name.length())==0))){
|
||||
if(tmp->DuplicatedID() > highest_id) {
|
||||
highest_id = tmp->DuplicatedID();
|
||||
matched_peer = false;
|
||||
}
|
||||
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
MZoneList.releasereadlock(__FUNCTION__, __LINE__);
|
||||
|
||||
if(match && !matched_peer)
|
||||
highest_id++;
|
||||
|
||||
return highest_id;
|
||||
}
|
||||
|
||||
bool World::ReportBug(string data, char* player_name, int32 account_id, const char* spawn_name, int32 spawn_id, int32 zone_id){
|
||||
//loginserver
|
||||
vector<string> list;
|
||||
|
@ -512,6 +512,8 @@ class ZoneList {
|
||||
void ReloadMail();
|
||||
void ReloadSpawns();
|
||||
|
||||
int32 GetHighestDuplicateID(const std::string& inc_zone_name, int32 inc_zone_id);
|
||||
|
||||
void WatchdogHeartbeat();
|
||||
|
||||
void SendTimeUpdate();
|
||||
|
@ -3278,6 +3278,8 @@ void WorldDatabase::LoadSpecialZones(){
|
||||
if(zone) {
|
||||
LogWrite(ZONE__INFO, 0, "Zone", "Static zone %s will be spundown due to another peer taking over.", row[1]);
|
||||
zone->SetAlwaysLoaded(false);
|
||||
zone->SetDuplicatedZone(true);
|
||||
zone->SetDuplicatedID(zone_list.GetHighestDuplicateID(std::string(zone->GetZoneName()), zone->GetZoneID()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3465,25 +3467,26 @@ int32 WorldDatabase::ProcessSpawnLocations(ZoneServer* zone, const char* sql_que
|
||||
entry->respawn = atoul(row[11]);
|
||||
entry->respawn_offset_low = atoi(row[12]);
|
||||
entry->respawn_offset_high = atoi(row[13]);
|
||||
entry->expire_time = atoul(row[16]);
|
||||
entry->expire_offset = atoul(row[17]);
|
||||
entry->duplicated_spawn = atoul(row[14]);
|
||||
entry->expire_time = atoul(row[17]);
|
||||
entry->expire_offset = atoul(row[18]);
|
||||
//devn00b add stat overrides. Just a slight increase in size. Used in ZoneServer::AddNPCSpawn.
|
||||
entry->lvl_override = atoul(row[21]);
|
||||
entry->hp_override = atoul(row[22]);
|
||||
entry->mp_override = atoul(row[23]);
|
||||
entry->str_override = atoul(row[24]);
|
||||
entry->sta_override = atoul(row[25]);
|
||||
entry->wis_override = atoul(row[26]);
|
||||
entry->int_override = atoul(row[27]);
|
||||
entry->agi_override = atoul(row[28]);
|
||||
entry->heat_override = atoul(row[29]);
|
||||
entry->cold_override = atoul(row[30]);
|
||||
entry->magic_override = atoul(row[31]);
|
||||
entry->mental_override = atoul(row[32]);
|
||||
entry->divine_override = atoul(row[33]);
|
||||
entry->disease_override = atoul(row[34]);
|
||||
entry->poison_override = atoul(row[35]);
|
||||
entry->difficulty_override = atoul(row[36]);
|
||||
entry->lvl_override = atoul(row[22]);
|
||||
entry->hp_override = atoul(row[23]);
|
||||
entry->mp_override = atoul(row[24]);
|
||||
entry->str_override = atoul(row[25]);
|
||||
entry->sta_override = atoul(row[26]);
|
||||
entry->wis_override = atoul(row[27]);
|
||||
entry->int_override = atoul(row[28]);
|
||||
entry->agi_override = atoul(row[29]);
|
||||
entry->heat_override = atoul(row[30]);
|
||||
entry->cold_override = atoul(row[31]);
|
||||
entry->magic_override = atoul(row[32]);
|
||||
entry->mental_override = atoul(row[33]);
|
||||
entry->divine_override = atoul(row[34]);
|
||||
entry->disease_override = atoul(row[35]);
|
||||
entry->poison_override = atoul(row[36]);
|
||||
entry->difficulty_override = atoul(row[37]);
|
||||
spawn_location->x = atof(row[2]);
|
||||
spawn_location->y = atof(row[3]);
|
||||
spawn_location->z = atof(row[4]);
|
||||
@ -3491,12 +3494,12 @@ int32 WorldDatabase::ProcessSpawnLocations(ZoneServer* zone, const char* sql_que
|
||||
spawn_location->y_offset = atof(row[6]);
|
||||
spawn_location->z_offset = atof(row[7]);
|
||||
spawn_location->heading = atof(row[8]);
|
||||
spawn_location->pitch = atof(row[18]);
|
||||
spawn_location->roll = atof(row[19]);
|
||||
spawn_location->conditional = atoi(row[20]);
|
||||
spawn_location->pitch = atof(row[19]);
|
||||
spawn_location->roll = atof(row[20]);
|
||||
spawn_location->conditional = atoi(row[21]);
|
||||
spawn_location->total_percentage += entry->spawn_percentage;
|
||||
spawn_location->grid_id = strtoul(row[14], NULL, 0);
|
||||
spawn_location->placement_id = strtoul(row[15], NULL, 0);
|
||||
spawn_location->grid_id = strtoul(row[15], NULL, 0);
|
||||
spawn_location->placement_id = strtoul(row[16], NULL, 0);
|
||||
spawn_location->AddSpawn(entry);
|
||||
|
||||
}
|
||||
@ -3535,21 +3538,21 @@ void WorldDatabase::LoadSpawns(ZoneServer* zone)
|
||||
LogWrite(SPAWN__TRACE, 0, "Spawn", "Enter LoadSpawns");
|
||||
|
||||
if(zone->GetInstanceID() == 0) {
|
||||
npcs = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_npcs sn where sn.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%u and slp.instance_id=%u ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_NPC);
|
||||
objects = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_objects so where so.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%u and slp.instance_id=%u ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_OBJECT);
|
||||
widgets = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_widgets sw where sw.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%u and slp.instance_id=%u ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_WIDGET);
|
||||
signs = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_signs ss where ss.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%u and slp.instance_id=%u ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_SIGN);
|
||||
ground_spawns = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_ground sg where sg.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%u and slp.instance_id=%u ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_GROUNDSPAWN);
|
||||
npcs = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.duplicated_spawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_npcs sn where sn.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%u and slp.instance_id=%u ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_NPC);
|
||||
objects = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.duplicated_spawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_objects so where so.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%u and slp.instance_id=%u ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_OBJECT);
|
||||
widgets = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.duplicated_spawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_widgets sw where sw.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%u and slp.instance_id=%u ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_WIDGET);
|
||||
signs = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.duplicated_spawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_signs ss where ss.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%u and slp.instance_id=%u ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_SIGN);
|
||||
ground_spawns = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.duplicated_spawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_ground sg where sg.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%u and slp.instance_id=%u ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_GROUNDSPAWN);
|
||||
spawn_groups = LoadSpawnLocationGroups(zone);
|
||||
spawn_group_associations = LoadSpawnLocationGroupAssociations(zone);
|
||||
spawn_group_chances = LoadSpawnGroupChances(zone);
|
||||
}
|
||||
else {
|
||||
npcs = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_npcs sn where sn.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i and (slp.instance_id = 0 or slp.instance_id=%u) ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_NPC);
|
||||
objects = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_objects so where so.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i and (slp.instance_id = 0 or slp.instance_id=%u) ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_OBJECT);
|
||||
widgets = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_widgets sw where sw.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i and (slp.instance_id = 0 or slp.instance_id=%u) ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_WIDGET);
|
||||
signs = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_signs ss where ss.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i and (slp.instance_id = 0 or slp.instance_id=%u) ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_SIGN);
|
||||
ground_spawns = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_ground sg where sg.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i and (slp.instance_id = 0 or slp.instance_id=%u) ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_GROUNDSPAWN);
|
||||
npcs = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.duplicated_spawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_npcs sn where sn.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i and (slp.instance_id = 0 or slp.instance_id=%u) ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_NPC);
|
||||
objects = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.duplicated_spawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_objects so where so.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i and (slp.instance_id = 0 or slp.instance_id=%u) ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_OBJECT);
|
||||
widgets = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.duplicated_spawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_widgets sw where sw.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i and (slp.instance_id = 0 or slp.instance_id=%u) ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_WIDGET);
|
||||
signs = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.duplicated_spawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_signs ss where ss.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i and (slp.instance_id = 0 or slp.instance_id=%u) ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_SIGN);
|
||||
ground_spawns = ProcessSpawnLocations(zone, "SELECT sln.id, sle.id, slp.x, slp.y, slp.z, slp.x_offset, slp.y_offset, slp.z_offset, slp.heading, sle.spawn_id, sle.spawnpercentage, slp.respawn, slp.respawn_offset_low, slp.respawn_offset_high, slp.duplicated_spawn, slp.grid_id, slp.id, slp.expire_timer, slp.expire_offset, slp.pitch, slp.roll, sle.condition, slp.lvl_override, slp.hp_override, slp.mp_override, slp.str_override, slp.sta_override, slp.wis_override, slp.int_override, slp.agi_override, slp.heat_override, slp.cold_override, slp.magic_override, slp.mental_override, slp.divine_override, slp.disease_override, slp.poison_override, difficulty_override FROM spawn_location_placement slp, spawn_location_name sln, spawn_location_entry sle, spawn_ground sg where sg.spawn_id = sle.spawn_id and sln.id = sle.spawn_location_id and sln.id = slp.spawn_location_id and slp.zone_id=%i and (slp.instance_id = 0 or slp.instance_id=%u) ORDER BY sln.id, sle.id", SPAWN_ENTRY_TYPE_GROUNDSPAWN);
|
||||
spawn_groups = LoadSpawnLocationGroups(zone);
|
||||
spawn_group_associations = LoadSpawnLocationGroupAssociations(zone);
|
||||
spawn_group_chances = LoadSpawnGroupChances(zone);
|
||||
|
@ -185,6 +185,7 @@ ZoneServer::ZoneServer(const char* name) {
|
||||
is_initialized = false;
|
||||
isInstance = false;
|
||||
duplicated_zone = false;
|
||||
duplicated_id = 0;
|
||||
}
|
||||
|
||||
typedef map <int32, bool> ChangedSpawnMapType;
|
||||
@ -2525,7 +2526,9 @@ Spawn* ZoneServer::ProcessSpawnLocation(SpawnLocation* spawnlocation, map<int32,
|
||||
{
|
||||
if(spawnlocation->entities[i]->spawn_percentage == 0)
|
||||
continue;
|
||||
|
||||
if(DuplicatedZone() && !spawnlocation->entities[i]->duplicated_spawn) {
|
||||
return nullptr; // dupe public/shared zone, we have turned off duplicating spawns for this location
|
||||
}
|
||||
|
||||
int32 spawnTime = 1;
|
||||
|
||||
@ -2994,6 +2997,7 @@ NPC* ZoneServer::AddNPCSpawn(SpawnLocation* spawnlocation, SpawnEntry* spawnentr
|
||||
npc->SetRespawnTime(spawnentry->respawn);
|
||||
npc->SetRespawnOffsetLow(spawnentry->respawn_offset_low);
|
||||
npc->SetRespawnOffsetHigh(spawnentry->respawn_offset_high);
|
||||
npc->SetDuplicateSpawn(spawnentry->duplicated_spawn);
|
||||
npc->SetExpireTime(spawnentry->expire_time);
|
||||
|
||||
//devn00b add overrides for some spawns
|
||||
@ -3417,6 +3421,7 @@ Sign* ZoneServer::AddSignSpawn(SpawnLocation* spawnlocation, SpawnEntry* spawnen
|
||||
sign->SetRespawnTime(spawnentry->respawn);
|
||||
sign->SetRespawnOffsetLow(spawnentry->respawn_offset_low);
|
||||
sign->SetRespawnOffsetHigh(spawnentry->respawn_offset_high);
|
||||
sign->SetDuplicateSpawn(spawnentry->duplicated_spawn);
|
||||
sign->SetExpireTime(spawnentry->expire_time);
|
||||
if (spawnentry->expire_time > 0)
|
||||
AddSpawnExpireTimer(sign, spawnentry->expire_time, spawnentry->expire_offset);
|
||||
@ -3448,6 +3453,7 @@ Widget* ZoneServer::AddWidgetSpawn(SpawnLocation* spawnlocation, SpawnEntry* spa
|
||||
widget->SetRespawnTime(spawnentry->respawn);
|
||||
widget->SetRespawnOffsetLow(spawnentry->respawn_offset_low);
|
||||
widget->SetRespawnOffsetHigh(spawnentry->respawn_offset_high);
|
||||
widget->SetDuplicateSpawn(spawnentry->duplicated_spawn);
|
||||
widget->SetExpireTime(spawnentry->expire_time);
|
||||
widget->SetSpawnOrigHeading(widget->GetHeading());
|
||||
if (spawnentry->expire_time > 0)
|
||||
@ -3474,6 +3480,7 @@ Object* ZoneServer::AddObjectSpawn(SpawnLocation* spawnlocation, SpawnEntry* spa
|
||||
object->SetRespawnTime(spawnentry->respawn);
|
||||
object->SetRespawnOffsetLow(spawnentry->respawn_offset_low);
|
||||
object->SetRespawnOffsetHigh(spawnentry->respawn_offset_high);
|
||||
object->SetDuplicateSpawn(spawnentry->duplicated_spawn);
|
||||
object->SetExpireTime(spawnentry->expire_time);
|
||||
if (spawnentry->expire_time > 0)
|
||||
AddSpawnExpireTimer(object, spawnentry->expire_time, spawnentry->expire_offset);
|
||||
@ -3499,6 +3506,7 @@ GroundSpawn* ZoneServer::AddGroundSpawn(SpawnLocation* spawnlocation, SpawnEntry
|
||||
spawn->SetRespawnTime(spawnentry->respawn);
|
||||
spawn->SetRespawnOffsetLow(spawnentry->respawn_offset_low);
|
||||
spawn->SetRespawnOffsetHigh(spawnentry->respawn_offset_high);
|
||||
spawn->SetDuplicateSpawn(spawnentry->duplicated_spawn);
|
||||
spawn->SetExpireTime(spawnentry->expire_time);
|
||||
|
||||
if(spawn->GetRandomizeHeading()) {
|
||||
@ -5280,7 +5288,7 @@ void ZoneServer::KillSpawn(bool spawnListLocked, Spawn* dead, Spawn* killer, boo
|
||||
else if ( dead->IsObject ( ) )
|
||||
database.CreateInstanceSpawnRemoved(dead->GetSpawnLocationID(),SPAWN_ENTRY_TYPE_OBJECT, dead->GetRespawnTime(),dead->GetZone()->GetInstanceID());
|
||||
}
|
||||
else if(!groupMemberAlive && dead->GetSpawnLocationID() > 0) {
|
||||
else if(!groupMemberAlive && dead->GetSpawnLocationID() > 0 && !DuplicatedZone()) {
|
||||
if(dead->IsNPC())
|
||||
database.CreatePersistedRespawn(dead->GetSpawnLocationID(),SPAWN_ENTRY_TYPE_NPC,dead->GetRespawnTime(),GetZoneID());
|
||||
else if(dead->IsObject())
|
||||
|
@ -532,9 +532,11 @@ public:
|
||||
inline bool IsCityZone() { return cityzone; }
|
||||
inline bool AlwaysLoaded() { return always_loaded; }
|
||||
inline bool DuplicatedZone() { return duplicated_zone; }
|
||||
inline int32 DuplicatedID() { return duplicated_id; }
|
||||
void SetCityZone(bool val) { cityzone = val; }
|
||||
void SetAlwaysLoaded(bool val) { always_loaded = val; }
|
||||
void SetDuplicatedZone(bool val) { duplicated_zone = val; }
|
||||
void SetDuplicatedID(int32 id) { duplicated_id = id; }
|
||||
int32 NumPlayers() { return pNumPlayers; }
|
||||
void SetMinimumStatus(sint16 minStatus) { minimumStatus = minStatus; }
|
||||
sint16 GetMinimumStatus() { return minimumStatus; }
|
||||
@ -939,6 +941,7 @@ private:
|
||||
bool cityzone;
|
||||
bool always_loaded;
|
||||
bool duplicated_zone;
|
||||
int32 duplicated_id;
|
||||
bool isInstance;
|
||||
|
||||
std::atomic<int32> pNumPlayers;
|
||||
|
Loading…
x
Reference in New Issue
Block a user