mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 12:41:30 +00:00
[Factions] Remove from shared memory and simplify (#3999)
* [Factions] Remove from shared memory and simplify - Removes factions from shared memory and moves to zone based storage of repositories and changes the NPC `faction_list` to also use repositories. - This affects NPC Factions and Faction Associations. * Bug fixes. * Update client.cpp * Update client.cpp * Update client.cpp * Cleanup * Update client.cpp * Update client.cpp * Update client.cpp * Final push * Update CMakeLists.txt * Consolidate reloading. * [Cleanup] PR # 3999 (#4039) * [Fixes for PR # 3999 * [Reload actual in game factions, not just the umbrella data. * syntax * Fix typo * Foix bug where primary_faction not filled in when no hits * Fix typos * Fix splash factions for kills. * Fix typo * Fix more variable names to be accurate * Fix Loads to load new ones as they come in. * Load npc_factions without primary (tasks) and support old task faction * Rename to make way for new LoadFactionAssocition (by faction_id) * Fix some review comments * Add code to load factions for splash tasks and quests. * Fix issue with sign and RewardFaction, fix Log Message --------- Co-authored-by: Paul Coene <noudess@gmail.com>
This commit is contained in:
parent
029581772d
commit
297e358c02
@ -24,17 +24,15 @@
|
||||
#include <string>
|
||||
|
||||
enum FACTION_VALUE {
|
||||
FACTION_ALLY = 1,
|
||||
FACTION_WARMLY = 2,
|
||||
FACTION_KINDLY = 3,
|
||||
FACTION_AMIABLY = 4,
|
||||
|
||||
FACTION_INDIFFERENTLY = 5,
|
||||
|
||||
FACTION_ALLY = 1,
|
||||
FACTION_WARMLY = 2,
|
||||
FACTION_KINDLY = 3,
|
||||
FACTION_AMIABLY = 4,
|
||||
FACTION_INDIFFERENTLY = 5,
|
||||
FACTION_APPREHENSIVELY = 6,
|
||||
FACTION_DUBIOUSLY = 7,
|
||||
FACTION_THREATENINGLY = 8,
|
||||
FACTION_SCOWLS = 9
|
||||
FACTION_DUBIOUSLY = 7,
|
||||
FACTION_THREATENINGLY = 8,
|
||||
FACTION_SCOWLS = 9
|
||||
};
|
||||
|
||||
struct NPCFactionList {
|
||||
@ -75,23 +73,6 @@ struct NPCFaction
|
||||
uint8 temp;
|
||||
};
|
||||
|
||||
// Faction Associations give a much more live like faction system
|
||||
// Basically the primary faction and magnitude of a faction hit will generate the rest of them
|
||||
|
||||
// Largest faction I could find quickly was Lord Inquisitor Seru with 9 total hits (8 associations) so 8 + 2 for max for now
|
||||
#define MAX_FACTION_ASSOC 10
|
||||
|
||||
// this is the ID of a faction association and it's multiplier
|
||||
struct FactionAssociationHit {
|
||||
int id;
|
||||
float multiplier;
|
||||
};
|
||||
|
||||
struct FactionAssociations {
|
||||
// maybe there should be more data here, fine for now
|
||||
FactionAssociationHit hits[MAX_FACTION_ASSOC];
|
||||
};
|
||||
|
||||
const char *FactionValueToString(FACTION_VALUE faction_value);
|
||||
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
|
||||
#endif
|
||||
|
||||
@ -251,6 +251,7 @@
|
||||
#define ServerOP_ReloadDzTemplates 0x4123
|
||||
#define ServerOP_ReloadZoneData 0x4124
|
||||
#define ServerOP_ReloadDataBucketsCache 0x4125
|
||||
#define ServerOP_ReloadFactions 0x4126
|
||||
|
||||
#define ServerOP_CZDialogueWindow 0x4500
|
||||
#define ServerOP_CZLDoNUpdate 0x4501
|
||||
|
||||
@ -1371,186 +1371,6 @@ std::string SharedDatabase::GetBook(const char *txtfile, int16 *language)
|
||||
return txtout;
|
||||
}
|
||||
|
||||
void SharedDatabase::GetFactionListInfo(uint32 &list_count, uint32 &max_lists) {
|
||||
list_count = 0;
|
||||
max_lists = 0;
|
||||
|
||||
const std::string query = "SELECT COUNT(*), MAX(id) FROM npc_faction";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return;
|
||||
|
||||
auto& row = results.begin();
|
||||
|
||||
list_count = Strings::ToUnsignedInt(row[0]);
|
||||
max_lists = Strings::ToUnsignedInt(row[1] ? row[1] : "0");
|
||||
}
|
||||
|
||||
const NPCFactionList* SharedDatabase::GetNPCFactionEntry(uint32 id) const
|
||||
{
|
||||
if(!faction_hash) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(faction_hash->exists(id)) {
|
||||
return &(faction_hash->at(id));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_count, uint32 max_lists) {
|
||||
EQ::FixedMemoryHashSet<NPCFactionList> hash(static_cast<uint8*>(data), size, list_count, max_lists);
|
||||
NPCFactionList faction;
|
||||
|
||||
const std::string query = "SELECT npc_faction.id, npc_faction.primaryfaction, npc_faction.ignore_primary_assist, "
|
||||
"npc_faction_entries.faction_id, npc_faction_entries.value, npc_faction_entries.npc_value, "
|
||||
"npc_faction_entries.temp FROM npc_faction LEFT JOIN npc_faction_entries "
|
||||
"ON npc_faction.id = npc_faction_entries.npc_faction_id ORDER BY npc_faction.id;";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 current_id = 0;
|
||||
uint32 current_entry = 0;
|
||||
|
||||
for(auto& row = results.begin(); row != results.end(); ++row) {
|
||||
const uint32 id = Strings::ToUnsignedInt(row[0]);
|
||||
if(id != current_id) {
|
||||
if(current_id != 0) {
|
||||
hash.insert(current_id, faction);
|
||||
}
|
||||
|
||||
memset(&faction, 0, sizeof(faction));
|
||||
current_entry = 0;
|
||||
current_id = id;
|
||||
faction.id = id;
|
||||
faction.primaryfaction = Strings::ToUnsignedInt(row[1]);
|
||||
faction.assistprimaryfaction = (Strings::ToInt(row[2]) == 0);
|
||||
}
|
||||
|
||||
if(!row[3])
|
||||
continue;
|
||||
|
||||
if(current_entry >= MAX_NPC_FACTIONS)
|
||||
continue;
|
||||
|
||||
faction.factionid[current_entry] = Strings::ToUnsignedInt(row[3]);
|
||||
faction.factionvalue[current_entry] = Strings::ToInt(row[4]);
|
||||
faction.factionnpcvalue[current_entry] = static_cast<int8>(Strings::ToInt(row[5]));
|
||||
faction.factiontemp[current_entry] = static_cast<uint8>(Strings::ToUnsignedInt(row[6]));
|
||||
++current_entry;
|
||||
}
|
||||
|
||||
if(current_id != 0)
|
||||
hash.insert(current_id, faction);
|
||||
|
||||
}
|
||||
|
||||
bool SharedDatabase::LoadNPCFactionLists(const std::string &prefix) {
|
||||
faction_mmf.reset(nullptr);
|
||||
faction_hash.reset(nullptr);
|
||||
|
||||
try {
|
||||
const auto Config = EQEmuConfig::get();
|
||||
EQ::IPCMutex mutex("faction");
|
||||
mutex.Lock();
|
||||
std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("faction"));
|
||||
LogInfo("Loading [{}]", file_name);
|
||||
faction_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name);
|
||||
faction_hash = std::make_unique<EQ::FixedMemoryHashSet<NPCFactionList>>(static_cast<uint8*>(faction_mmf->Get()), faction_mmf->Size());
|
||||
mutex.Unlock();
|
||||
|
||||
LogInfo("Loaded faction lists via shared memory");
|
||||
} catch(std::exception& ex) {
|
||||
LogError("Error Loading npc factions: {}", ex.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SharedDatabase::GetFactionAssociationInfo(uint32 &list_count, uint32 &max_lists)
|
||||
{
|
||||
list_count = static_cast<uint32>(FactionAssociationRepository::Count(*this));
|
||||
max_lists = static_cast<uint32>(FactionAssociationRepository::GetMaxId(*this));
|
||||
}
|
||||
|
||||
const FactionAssociations *SharedDatabase::GetFactionAssociationHit(int id)
|
||||
{
|
||||
if (!faction_associations_hash) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (faction_associations_hash->exists(id)) {
|
||||
return &(faction_associations_hash->at(id));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SharedDatabase::LoadFactionAssociation(void *data, uint32 size, uint32 list_count, uint32 max_lists)
|
||||
{
|
||||
EQ::FixedMemoryHashSet<FactionAssociations> hash(reinterpret_cast<uint8 *>(data), size, list_count, max_lists);
|
||||
FactionAssociations faction{};
|
||||
|
||||
auto results = FactionAssociationRepository::All(*this);
|
||||
for (auto &row : results) {
|
||||
faction.hits[0].id = row.id_1;
|
||||
faction.hits[0].multiplier = row.mod_1;
|
||||
faction.hits[1].id = row.id_2;
|
||||
faction.hits[1].multiplier = row.mod_2;
|
||||
faction.hits[2].id = row.id_3;
|
||||
faction.hits[2].multiplier = row.mod_3;
|
||||
faction.hits[3].id = row.id_4;
|
||||
faction.hits[3].multiplier = row.mod_4;
|
||||
faction.hits[4].id = row.id_5;
|
||||
faction.hits[4].multiplier = row.mod_5;
|
||||
faction.hits[5].id = row.id_6;
|
||||
faction.hits[5].multiplier = row.mod_6;
|
||||
faction.hits[6].id = row.id_7;
|
||||
faction.hits[6].multiplier = row.mod_7;
|
||||
faction.hits[7].id = row.id_8;
|
||||
faction.hits[7].multiplier = row.mod_8;
|
||||
faction.hits[8].id = row.id_9;
|
||||
faction.hits[8].multiplier = row.mod_9;
|
||||
faction.hits[9].id = row.id_10;
|
||||
faction.hits[9].multiplier = row.mod_10;
|
||||
|
||||
hash.insert(row.id, faction);
|
||||
}
|
||||
}
|
||||
|
||||
bool SharedDatabase::LoadFactionAssociation(const std::string &prefix)
|
||||
{
|
||||
faction_associations_mmf.reset(nullptr);
|
||||
faction_associations_hash.reset(nullptr);
|
||||
|
||||
try {
|
||||
auto Config = EQEmuConfig::get();
|
||||
EQ::IPCMutex mutex("factionassociations");
|
||||
mutex.Lock();
|
||||
std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("factionassociations"));
|
||||
faction_associations_mmf = std::unique_ptr<EQ::MemoryMappedFile>(new EQ::MemoryMappedFile(file_name));
|
||||
faction_associations_hash = std::unique_ptr<EQ::FixedMemoryHashSet<FactionAssociations>>(
|
||||
new EQ::FixedMemoryHashSet<FactionAssociations>(reinterpret_cast<uint8 *>(faction_associations_mmf->Get()),
|
||||
faction_associations_mmf->Size()));
|
||||
mutex.Unlock();
|
||||
|
||||
LogInfo("Loaded faction associations via shared memory");
|
||||
} catch (std::exception &ex) {
|
||||
LogError("Error Loading faction associations: {}", ex.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create appropriate EQ::ItemInstance class
|
||||
EQ::ItemInstance* SharedDatabase::CreateItem(
|
||||
uint32 item_id,
|
||||
|
||||
@ -164,22 +164,6 @@ public:
|
||||
uint32 GetSharedItemsCount() { return m_shared_items_count; }
|
||||
uint32 GetItemsCount();
|
||||
|
||||
/**
|
||||
* faction
|
||||
*/
|
||||
void GetFactionListInfo(uint32 &list_count, uint32 &max_lists);
|
||||
const NPCFactionList *GetNPCFactionEntry(uint32 id) const;
|
||||
void LoadNPCFactionLists(void *data, uint32 size, uint32 list_count, uint32 max_lists);
|
||||
bool LoadNPCFactionLists(const std::string &prefix);
|
||||
|
||||
/**
|
||||
* faction associations
|
||||
*/
|
||||
void GetFactionAssociationInfo(uint32 &list_count, uint32 &max_lists);
|
||||
const FactionAssociations *GetFactionAssociationHit(int id);
|
||||
void LoadFactionAssociation(void *data, uint32 size, uint32 list_count, uint32 max_lists);
|
||||
bool LoadFactionAssociation(const std::string &prefix);
|
||||
|
||||
/**
|
||||
* loot
|
||||
*/
|
||||
|
||||
@ -2,21 +2,17 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
||||
|
||||
SET(shared_memory_sources
|
||||
base_data.cpp
|
||||
faction_association.cpp
|
||||
items.cpp
|
||||
loot.cpp
|
||||
main.cpp
|
||||
npc_faction.cpp
|
||||
spells.cpp
|
||||
skill_caps.cpp
|
||||
)
|
||||
|
||||
SET(shared_memory_headers
|
||||
base_data.h
|
||||
faction_association.h
|
||||
items.h
|
||||
loot.h
|
||||
npc_faction.h
|
||||
spells.h
|
||||
skill_caps.h
|
||||
)
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2022 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "faction_association.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/shareddb.h"
|
||||
#include "../common/ipc_mutex.h"
|
||||
#include "../common/memory_mapped_file.h"
|
||||
#include "../common/eqemu_exception.h"
|
||||
#include "../common/faction.h"
|
||||
|
||||
void LoadFactionAssociation(SharedDatabase *database, const std::string &prefix) {
|
||||
EQ::IPCMutex mutex("factionassociations");
|
||||
mutex.Lock();
|
||||
|
||||
uint32 lists = 0;
|
||||
uint32 max_list = 0;
|
||||
database->GetFactionAssociationInfo(lists, max_list);
|
||||
|
||||
uint32 size = static_cast<uint32>(EQ::FixedMemoryHashSet<FactionAssociations>::estimated_size(lists, max_list));
|
||||
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string file_name = Config->SharedMemDir + prefix + std::string("factionassociations");
|
||||
EQ::MemoryMappedFile mmf(file_name, size);
|
||||
mmf.ZeroFile();
|
||||
|
||||
void *ptr = mmf.Get();
|
||||
database->LoadFactionAssociation(ptr, size, lists, max_list);
|
||||
mutex.Unlock();
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2022 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __EQEMU_SHARED_MEMORY_FACTION_ASSOCIATION_H
|
||||
#define __EQEMU_SHARED_MEMORY_FACTION_ASSOCIATION_H
|
||||
|
||||
#include <string>
|
||||
#include "../common/eqemu_config.h"
|
||||
|
||||
class SharedDatabase;
|
||||
void LoadFactionAssociation(SharedDatabase *database, const std::string &prefix);
|
||||
|
||||
#endif
|
||||
@ -27,9 +27,7 @@
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/eqemu_exception.h"
|
||||
#include "../common/strings.h"
|
||||
#include "faction_association.h"
|
||||
#include "items.h"
|
||||
#include "npc_faction.h"
|
||||
#include "loot.h"
|
||||
#include "skill_caps.h"
|
||||
#include "spells.h"
|
||||
@ -185,8 +183,6 @@ int main(int argc, char **argv)
|
||||
|
||||
bool load_all = true;
|
||||
bool load_items = false;
|
||||
bool load_factions = false;
|
||||
bool load_faction_assoc = false;
|
||||
bool load_loot = false;
|
||||
bool load_skill_caps = false;
|
||||
bool load_spells = false;
|
||||
@ -209,13 +205,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (strcasecmp("factions", argv[i]) == 0) {
|
||||
load_factions = true;
|
||||
load_all = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if (strcasecmp("loot", argv[i]) == 0) {
|
||||
load_loot = true;
|
||||
@ -232,10 +221,6 @@ int main(int argc, char **argv)
|
||||
load_spells = true;
|
||||
load_all = false;
|
||||
}
|
||||
else if (strcasecmp("faction_assoc", argv[i]) == 0) {
|
||||
load_faction_assoc = true;
|
||||
load_all = false;
|
||||
}
|
||||
break;
|
||||
case '-': {
|
||||
auto split = Strings::Split(argv[i], '=');
|
||||
@ -267,15 +252,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (load_all || load_factions) {
|
||||
try {
|
||||
LoadFactions(&content_db, hotfix_name);
|
||||
} catch (std::exception &ex) {
|
||||
LogError("{}", ex.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (load_all || load_loot) {
|
||||
LogInfo("Loading loot");
|
||||
try {
|
||||
@ -306,16 +282,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (load_all || load_faction_assoc) {
|
||||
LogInfo("Loading faction associations");
|
||||
try {
|
||||
LoadFactionAssociation(&content_db, hotfix_name);
|
||||
} catch(std::exception &ex) {
|
||||
LogError("{}", ex.what());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (load_all || load_bd) {
|
||||
LogInfo("Loading base data");
|
||||
try {
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "npc_faction.h"
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/shareddb.h"
|
||||
#include "../common/ipc_mutex.h"
|
||||
#include "../common/memory_mapped_file.h"
|
||||
#include "../common/eqemu_exception.h"
|
||||
#include "../common/faction.h"
|
||||
|
||||
void LoadFactions(SharedDatabase *database, const std::string &prefix) {
|
||||
EQ::IPCMutex mutex("faction");
|
||||
mutex.Lock();
|
||||
|
||||
uint32 lists = 0;
|
||||
uint32 max_list = 0;
|
||||
database->GetFactionListInfo(lists, max_list);
|
||||
|
||||
uint32 size = static_cast<uint32>(EQ::FixedMemoryHashSet<NPCFactionList>::estimated_size(lists, max_list));
|
||||
|
||||
auto Config = EQEmuConfig::get();
|
||||
std::string file_name = Config->SharedMemDir + prefix + std::string("faction");
|
||||
EQ::MemoryMappedFile mmf(file_name, size);
|
||||
mmf.ZeroFile();
|
||||
|
||||
void *ptr = mmf.Get();
|
||||
database->LoadNPCFactionLists(ptr, size, lists, max_list);
|
||||
mutex.Unlock();
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __EQEMU_SHARED_MEMORY_NPC_FACTION_H
|
||||
#define __EQEMU_SHARED_MEMORY_NPC_FACTION_H
|
||||
|
||||
#include <string>
|
||||
#include "../common/eqemu_config.h"
|
||||
|
||||
class SharedDatabase;
|
||||
void LoadFactions(SharedDatabase *database, const std::string &prefix);
|
||||
|
||||
#endif
|
||||
@ -1389,6 +1389,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
case ServerOP_ReloadCommands:
|
||||
case ServerOP_ReloadDoors:
|
||||
case ServerOP_ReloadDataBucketsCache:
|
||||
case ServerOP_ReloadFactions:
|
||||
case ServerOP_ReloadGroundSpawns:
|
||||
case ServerOP_ReloadLevelEXPMods:
|
||||
case ServerOP_ReloadMerchants:
|
||||
|
||||
@ -161,6 +161,7 @@ SET(zone_sources
|
||||
zone_config.cpp
|
||||
zonedb.cpp
|
||||
zone_event_scheduler.cpp
|
||||
zone_npc_factions.cpp
|
||||
zone_reload.cpp
|
||||
zoning.cpp
|
||||
)
|
||||
|
||||
@ -285,24 +285,24 @@ void NPC::DescribeAggro(Client *to_who, Mob *mob, bool verbose) {
|
||||
auto faction_name = content_db.GetFactionName(mob_faction_id);
|
||||
bool has_entry = false;
|
||||
for (auto faction : faction_list) {
|
||||
if (static_cast<int>(faction->factionID) == mob_faction_id) {
|
||||
if (static_cast<int>(faction.faction_id) == mob_faction_id) {
|
||||
to_who->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} has {} standing with Faction {} ({}) with their Faction Level of {}",
|
||||
to_who->GetTargetDescription(mob),
|
||||
(
|
||||
faction->npc_value != 0 ?
|
||||
faction.npc_value != 0 ?
|
||||
(
|
||||
faction->npc_value > 0 ?
|
||||
faction.npc_value > 0 ?
|
||||
"positive" :
|
||||
"negative"
|
||||
) :
|
||||
"neutral"
|
||||
),
|
||||
faction_name,
|
||||
faction->factionID,
|
||||
faction->npc_value
|
||||
faction.faction_id,
|
||||
faction.npc_value
|
||||
).c_str()
|
||||
);
|
||||
has_entry = true;
|
||||
|
||||
209
zone/client.cpp
209
zone/client.cpp
@ -7385,39 +7385,42 @@ FACTION_VALUE Client::GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 p_ra
|
||||
}
|
||||
|
||||
//Sets the characters faction standing with the specified NPC.
|
||||
void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity, bool quest)
|
||||
void Client::SetFactionLevel(
|
||||
uint32 character_id,
|
||||
uint32 npc_faction_id,
|
||||
uint8 class_id,
|
||||
uint8 race_id,
|
||||
uint8 deity_id,
|
||||
bool is_quest
|
||||
)
|
||||
{
|
||||
int32 faction_id[MAX_NPC_FACTIONS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
int32 npc_value[MAX_NPC_FACTIONS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
uint8 temp[MAX_NPC_FACTIONS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
int32 current_value;
|
||||
auto l = zone->GetNPCFactionEntries(npc_faction_id);
|
||||
|
||||
// Get the npc faction list
|
||||
if (!content_db.GetNPCFactionList(npc_id, faction_id, npc_value, temp)) {
|
||||
if (l.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_NPC_FACTIONS; i++) {
|
||||
int32 faction_before_hit;
|
||||
FactionMods fm;
|
||||
int32 this_faction_max;
|
||||
int32 this_faction_min;
|
||||
int current_value;
|
||||
|
||||
if (faction_id[i] <= 0)
|
||||
for (auto& e : l) {
|
||||
if (e.faction_id <= 0 || e.value == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find out starting faction for this faction
|
||||
// It needs to be used to adj max and min personal
|
||||
// The range is still the same, 1200-3000(4200), but adjusted for base
|
||||
content_db.GetFactionData(&fm, GetClass(), GetFactionRace(), GetDeity(), faction_id[i]);
|
||||
int faction_before;
|
||||
int faction_minimum;
|
||||
int faction_maximum;
|
||||
|
||||
if (quest)
|
||||
{
|
||||
//The ole switcheroo
|
||||
if (npc_value[i] > 0)
|
||||
npc_value[i] = -std::abs(npc_value[i]);
|
||||
else if (npc_value[i] < 0)
|
||||
npc_value[i] = std::abs(npc_value[i]);
|
||||
FactionMods faction_modifiers;
|
||||
|
||||
content_db.GetFactionData(&faction_modifiers, class_id, race_id, deity_id, e.faction_id);
|
||||
|
||||
if (is_quest) {
|
||||
if (e.npc_value > 0) {
|
||||
e.npc_value = -std::abs(e.npc_value);
|
||||
} else if (e.npc_value < 0) {
|
||||
e.npc_value = std::abs(e.npc_value);
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust the amount you can go up or down so the resulting range
|
||||
@ -7425,23 +7428,36 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui
|
||||
//
|
||||
// Adjust these values for cases where starting faction is below
|
||||
// min or above max by not allowing any earn in those directions.
|
||||
this_faction_min = fm.min - fm.base;
|
||||
this_faction_min = std::min(0, this_faction_min);
|
||||
this_faction_max = fm.max - fm.base;
|
||||
this_faction_max = std::max(0, this_faction_max);
|
||||
faction_minimum = faction_modifiers.min - faction_modifiers.base;
|
||||
faction_minimum = std::min(0, faction_minimum);
|
||||
|
||||
faction_maximum = faction_modifiers.max - faction_modifiers.base;
|
||||
faction_maximum = std::max(0, faction_maximum);
|
||||
|
||||
// Get the characters current value with that faction
|
||||
current_value = GetCharacterFactionLevel(faction_id[i]);
|
||||
faction_before_hit = current_value;
|
||||
current_value = GetCharacterFactionLevel(e.faction_id);
|
||||
faction_before = current_value;
|
||||
|
||||
UpdatePersonalFaction(char_id, npc_value[i], faction_id[i], ¤t_value, temp[i], this_faction_min, this_faction_max);
|
||||
UpdatePersonalFaction(
|
||||
character_id,
|
||||
e.value,
|
||||
e.faction_id,
|
||||
¤t_value,
|
||||
e.temp,
|
||||
faction_minimum,
|
||||
faction_maximum
|
||||
);
|
||||
|
||||
//Message(Chat::Lime, "Min(%d) Max(%d) Before(%d), After(%d)\n", this_faction_min, this_faction_max, faction_before_hit, current_value);
|
||||
|
||||
SendFactionMessage(npc_value[i], faction_id[i], faction_before_hit, current_value, temp[i], this_faction_min, this_faction_max);
|
||||
SendFactionMessage(
|
||||
e.value,
|
||||
e.faction_id,
|
||||
faction_before,
|
||||
current_value,
|
||||
e.temp,
|
||||
faction_minimum,
|
||||
faction_maximum
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Client::SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp)
|
||||
@ -8213,33 +8229,92 @@ void Client::CashReward(uint32 copper, uint32 silver, uint32 gold, uint32 platin
|
||||
QueuePacket(outapp.get());
|
||||
}
|
||||
|
||||
void Client::RewardFaction(int id, int amount)
|
||||
void Client::RewardFaction(int faction_id, int amount)
|
||||
{
|
||||
// first we hit the primary faction, even without any associations
|
||||
SetFactionLevel2(CharacterID(), id, GetClass(), GetBaseRace(), GetDeity(), amount, false);
|
||||
SetFactionLevel2(CharacterID(), faction_id, GetClass(), GetBaseRace(), GetDeity(), amount, false);
|
||||
|
||||
auto faction_assoc = content_db.GetFactionAssociationHit(id);
|
||||
// We could log here, but since it's actually expected for some not to have entries, it would be noisy.
|
||||
if (!faction_assoc) {
|
||||
auto f = zone->GetFactionAssociation(faction_id);
|
||||
if (!f) {
|
||||
return;
|
||||
}
|
||||
|
||||
// now hit them in order
|
||||
for (int i = 0; i < MAX_FACTION_ASSOC; ++i) {
|
||||
if (faction_assoc->hits[i].id <= 0) // we don't allow later entries
|
||||
break;
|
||||
if (faction_assoc->hits[i].multiplier == 0.0f) {
|
||||
LogFaction("Bad association multiplier for ID {} entry {}", id, i + 1);
|
||||
continue;
|
||||
std::vector<int> faction_ids = {
|
||||
f->id_1,
|
||||
f->id_2,
|
||||
f->id_3,
|
||||
f->id_4,
|
||||
f->id_5,
|
||||
f->id_6,
|
||||
f->id_7,
|
||||
f->id_8,
|
||||
f->id_9,
|
||||
f->id_10
|
||||
};
|
||||
|
||||
std::vector<float> faction_modifiers = {
|
||||
f->mod_1,
|
||||
f->mod_2,
|
||||
f->mod_3,
|
||||
f->mod_4,
|
||||
f->mod_5,
|
||||
f->mod_6,
|
||||
f->mod_7,
|
||||
f->mod_8,
|
||||
f->mod_9,
|
||||
f->mod_10
|
||||
};
|
||||
|
||||
std::vector<float> temporary_values = {
|
||||
static_cast<float>(faction_modifiers[0] * amount),
|
||||
static_cast<float>(faction_modifiers[1] * amount),
|
||||
static_cast<float>(faction_modifiers[2] * amount),
|
||||
static_cast<float>(faction_modifiers[3] * amount),
|
||||
static_cast<float>(faction_modifiers[4] * amount),
|
||||
static_cast<float>(faction_modifiers[5] * amount),
|
||||
static_cast<float>(faction_modifiers[6] * amount),
|
||||
static_cast<float>(faction_modifiers[7] * amount),
|
||||
static_cast<float>(faction_modifiers[8] * amount),
|
||||
static_cast<float>(faction_modifiers[9] * amount)
|
||||
};
|
||||
|
||||
std::vector<int> signs = {
|
||||
temporary_values[0] < 0.0f ? -1 : 1,
|
||||
temporary_values[1] < 0.0f ? -1 : 1,
|
||||
temporary_values[2] < 0.0f ? -1 : 1,
|
||||
temporary_values[3] < 0.0f ? -1 : 1,
|
||||
temporary_values[4] < 0.0f ? -1 : 1,
|
||||
temporary_values[5] < 0.0f ? -1 : 1,
|
||||
temporary_values[6] < 0.0f ? -1 : 1,
|
||||
temporary_values[7] < 0.0f ? -1 : 1,
|
||||
temporary_values[8] < 0.0f ? -1 : 1,
|
||||
temporary_values[9] < 0.0f ? -1 : 1
|
||||
};
|
||||
|
||||
std::vector<int> new_values = {
|
||||
std::max(1, static_cast<int>(std::abs(temporary_values[0]))) * signs[0],
|
||||
std::max(1, static_cast<int>(std::abs(temporary_values[1]))) * signs[1],
|
||||
std::max(1, static_cast<int>(std::abs(temporary_values[2]))) * signs[2],
|
||||
std::max(1, static_cast<int>(std::abs(temporary_values[3]))) * signs[3],
|
||||
std::max(1, static_cast<int>(std::abs(temporary_values[4]))) * signs[4],
|
||||
std::max(1, static_cast<int>(std::abs(temporary_values[5]))) * signs[5],
|
||||
std::max(1, static_cast<int>(std::abs(temporary_values[6]))) * signs[6],
|
||||
std::max(1, static_cast<int>(std::abs(temporary_values[7]))) * signs[7],
|
||||
std::max(1, static_cast<int>(std::abs(temporary_values[8]))) * signs[8],
|
||||
std::max(1, static_cast<int>(std::abs(temporary_values[9]))) * signs[9]
|
||||
};
|
||||
|
||||
for (uint16 slot_id = 0; slot_id < faction_ids.size(); slot_id++) {
|
||||
if (faction_ids[slot_id] > 0) {
|
||||
SetFactionLevel2(
|
||||
CharacterID(),
|
||||
faction_ids[slot_id],
|
||||
GetClass(),
|
||||
GetBaseRace(),
|
||||
GetDeity(),
|
||||
new_values[slot_id],
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
// value is truncated and min clamped to 1 (or -1)
|
||||
float temp = faction_assoc->hits[i].multiplier * amount;
|
||||
int sign = temp < 0.0f ? -1 : 1;
|
||||
int32 new_amount = std::max(1, static_cast<int32>(std::abs(temp))) * sign;
|
||||
|
||||
SetFactionLevel2(CharacterID(), faction_assoc->hits[i].id, GetClass(), GetBaseRace(), GetDeity(),
|
||||
new_amount, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9019,6 +9094,7 @@ void Client::ShowDevToolsMenu()
|
||||
|
||||
menu_reload_three += Saylink::Silent("#reload data_buckets_cache", "Databuckets");
|
||||
menu_reload_three += " | " + Saylink::Silent("#reload doors", "Doors");
|
||||
menu_reload_three += " | " + Saylink::Silent("#reload factions", "Factions");
|
||||
menu_reload_three += " | " + Saylink::Silent("#reload ground_spawns", "Ground Spawns");
|
||||
|
||||
menu_reload_four += Saylink::Silent("#reload logs", "Level Based Experience Modifiers");
|
||||
@ -10993,7 +11069,24 @@ void Client::SendReloadCommandMessages() {
|
||||
);
|
||||
|
||||
auto dztemplates_link = Saylink::Silent("#reload dztemplates");
|
||||
Message(Chat::White, fmt::format("Usage: {} - Reloads Dynamic Zone Templates globally", dztemplates_link).c_str());
|
||||
|
||||
Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Usage: {} - Reloads Dynamic Zone Templates globally",
|
||||
dztemplates_link
|
||||
).c_str()
|
||||
);
|
||||
|
||||
auto factions_link = Saylink::Silent("#reload factions");
|
||||
|
||||
Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Usage: {} - Reloads Factions globally",
|
||||
factions_link
|
||||
).c_str()
|
||||
);
|
||||
|
||||
auto ground_spawns_link = Saylink::Silent("#reload ground_spawns");
|
||||
|
||||
|
||||
@ -699,7 +699,7 @@ public:
|
||||
void SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_before_hit, int32 totalvalue, uint8 temp, int32 this_faction_min, int32 this_faction_max);
|
||||
|
||||
void UpdatePersonalFaction(int32 char_id, int32 npc_value, int32 faction_id, int32 *current_value, int32 temp, int32 this_faction_min, int32 this_faction_max);
|
||||
void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity, bool quest = false);
|
||||
void SetFactionLevel(uint32 char_id, uint32 npc_faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, bool quest = false);
|
||||
void SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value, uint8 temp);
|
||||
int32 GetRawItemAC();
|
||||
|
||||
|
||||
@ -340,9 +340,9 @@ void command_npcedit(Client *c, const Seperator *sep)
|
||||
} else if (!strcasecmp(sep->arg[1], "faction")) {
|
||||
if (sep->IsNumber(2)) {
|
||||
auto npc_faction_id = Strings::ToInt(sep->arg[2]);
|
||||
const NPCFactionList* cf = content_db.GetNPCFactionEntry(npc_faction_id);
|
||||
if (cf) {
|
||||
auto faction_id = cf->primaryfaction;
|
||||
const auto f = zone->GetNPCFaction(npc_faction_id);
|
||||
if (f) {
|
||||
auto faction_id = f->primaryfaction;
|
||||
auto faction_name = content_db.GetFactionName(faction_id);
|
||||
|
||||
n.npc_faction_id = npc_faction_id;
|
||||
|
||||
@ -21,6 +21,7 @@ void command_reload(Client *c, const Seperator *sep)
|
||||
bool is_data_buckets = !strcasecmp(sep->arg[1], "data_buckets_cache");
|
||||
bool is_doors = !strcasecmp(sep->arg[1], "doors");
|
||||
bool is_dztemplates = !strcasecmp(sep->arg[1], "dztemplates");
|
||||
bool is_factions = !strcasecmp(sep->arg[1], "factions");
|
||||
bool is_ground_spawns = !strcasecmp(sep->arg[1], "ground_spawns");
|
||||
bool is_level_mods = !strcasecmp(sep->arg[1], "level_mods");
|
||||
bool is_logs = !strcasecmp(sep->arg[1], "logs") || is_logs_reload_alias;
|
||||
@ -50,6 +51,7 @@ void command_reload(Client *c, const Seperator *sep)
|
||||
!is_data_buckets &&
|
||||
!is_doors &&
|
||||
!is_dztemplates &&
|
||||
!is_factions &&
|
||||
!is_ground_spawns &&
|
||||
!is_level_mods &&
|
||||
!is_logs &&
|
||||
@ -100,6 +102,9 @@ void command_reload(Client *c, const Seperator *sep)
|
||||
} else if (is_dztemplates) {
|
||||
c->Message(Chat::White, "Attempting to reload Dynamic Zone Templates globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadDzTemplates, 0);
|
||||
} else if (is_factions) {
|
||||
c->Message(Chat::White, "Attempting to reload Factions globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadFactions, 0);
|
||||
} else if (is_ground_spawns) {
|
||||
c->Message(Chat::White, "Attempting to reload Ground Spawns globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadGroundSpawns, 0);
|
||||
|
||||
@ -390,9 +390,9 @@ int Lua_Client::GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 race, uint
|
||||
return static_cast<int>(self->GetFactionLevel(char_id, npc_id, race, class_, deity, faction, npc));
|
||||
}
|
||||
|
||||
void Lua_Client::SetFactionLevel(uint32 char_id, uint32 npc_id, int char_class, int char_race, int char_deity) {
|
||||
void Lua_Client::SetFactionLevel(uint32 char_id, uint32 npc_faction_id, int char_class, int char_race, int char_deity) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetFactionLevel(char_id, npc_id, char_class, char_race, char_deity);
|
||||
self->SetFactionLevel(char_id, npc_faction_id, char_class, char_race, char_deity);
|
||||
}
|
||||
|
||||
void Lua_Client::SetFactionLevel2(uint32 char_id, int faction_id, int char_class, int char_race, int char_deity, int value, int temp) {
|
||||
|
||||
@ -145,7 +145,7 @@ public:
|
||||
bool TeleportRaidToPlayerByName(std::string player_name);
|
||||
void ChangeLastName(std::string last_name);
|
||||
int GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 race, uint32 class_, uint32 deity, uint32 faction, Lua_NPC npc);
|
||||
void SetFactionLevel(uint32 char_id, uint32 npc_id, int char_class, int char_race, int char_deity);
|
||||
void SetFactionLevel(uint32 char_id, uint32 npc_faction_id, int char_class, int char_race, int char_deity);
|
||||
void SetFactionLevel2(uint32 char_id, int faction_id, int char_class, int char_race, int char_deity, int value, int temp);
|
||||
void RewardFaction(int id, int amount);
|
||||
int GetRawItemAC();
|
||||
|
||||
@ -372,14 +372,6 @@ int main(int argc, char **argv)
|
||||
LogError("Failed. But ignoring error and going on..");
|
||||
}
|
||||
|
||||
if (!content_db.LoadNPCFactionLists(hotfix_name)) {
|
||||
LogError("Loading npcs faction lists failed!");
|
||||
return 1;
|
||||
}
|
||||
if (!content_db.LoadFactionAssociation(hotfix_name)) {
|
||||
LogError("Loading faction association hits failed!");
|
||||
return 1;
|
||||
}
|
||||
if (!database.LoadLoot(hotfix_name)) {
|
||||
LogError("Loading loot failed!");
|
||||
return 1;
|
||||
|
||||
@ -2775,14 +2775,13 @@ void Mob::ShowStats(Client* c)
|
||||
|
||||
// Faction
|
||||
if (t->GetNPCFactionID()) {
|
||||
auto faction_id = t->GetPrimaryFaction();
|
||||
auto faction_name = content_db.GetFactionName(faction_id);
|
||||
const std::string& faction_name = content_db.GetFactionName(t->GetPrimaryFaction());
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Faction: {} ({})",
|
||||
faction_name,
|
||||
faction_id
|
||||
t->GetPrimaryFaction()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
57
zone/npc.cpp
57
zone/npc.cpp
@ -512,34 +512,19 @@ NPC::~NPC()
|
||||
{
|
||||
AI_Stop();
|
||||
|
||||
if(proximity != nullptr) {
|
||||
if (proximity) {
|
||||
entity_list.RemoveProximity(GetID());
|
||||
safe_delete(proximity);
|
||||
}
|
||||
|
||||
safe_delete(NPCTypedata_ours);
|
||||
|
||||
{
|
||||
ItemList::iterator cur,end;
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
for(; cur != end; ++cur) {
|
||||
ServerLootItem_Struct* item = *cur;
|
||||
safe_delete(item);
|
||||
}
|
||||
itemlist.clear();
|
||||
for (auto* e : itemlist) {
|
||||
safe_delete(e);
|
||||
}
|
||||
|
||||
{
|
||||
std::list<struct NPCFaction*>::iterator cur,end;
|
||||
cur = faction_list.begin();
|
||||
end = faction_list.end();
|
||||
for(; cur != end; ++cur) {
|
||||
struct NPCFaction* fac = *cur;
|
||||
safe_delete(fac);
|
||||
}
|
||||
itemlist.clear();
|
||||
faction_list.clear();
|
||||
}
|
||||
|
||||
safe_delete(reface_timer);
|
||||
safe_delete(swarmInfoPtr);
|
||||
@ -3204,19 +3189,17 @@ FACTION_VALUE NPC::GetReverseFactionCon(Mob* iOther) {
|
||||
|
||||
//Look through our faction list and return a faction con based
|
||||
//on the npc_value for the other person's primary faction in our list.
|
||||
FACTION_VALUE NPC::CheckNPCFactionAlly(int32 other_faction) {
|
||||
std::list<struct NPCFaction*>::iterator cur,end;
|
||||
cur = faction_list.begin();
|
||||
end = faction_list.end();
|
||||
for(; cur != end; ++cur) {
|
||||
struct NPCFaction* fac = *cur;
|
||||
if ((int32)fac->factionID == other_faction) {
|
||||
if (fac->npc_value > 0)
|
||||
FACTION_VALUE NPC::CheckNPCFactionAlly(int32 other_faction)
|
||||
{
|
||||
for (const auto& e : faction_list) {
|
||||
if (e.faction_id == other_faction) {
|
||||
if (e.npc_value > 0) {
|
||||
return FACTION_ALLY;
|
||||
else if (fac->npc_value < 0)
|
||||
} else if (e.npc_value < 0) {
|
||||
return FACTION_SCOWLS;
|
||||
else
|
||||
} else {
|
||||
return FACTION_INDIFFERENTLY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3225,14 +3208,16 @@ FACTION_VALUE NPC::CheckNPCFactionAlly(int32 other_faction) {
|
||||
// where an npc is on a faction but has no hits (hence no entry in
|
||||
// npc_faction_entries).
|
||||
|
||||
if (GetPrimaryFaction() == other_faction)
|
||||
if (GetPrimaryFaction() == other_faction) {
|
||||
return FACTION_ALLY;
|
||||
else
|
||||
} else {
|
||||
return FACTION_INDIFFERENTLY;
|
||||
}
|
||||
}
|
||||
|
||||
bool NPC::IsFactionListAlly(uint32 other_faction) {
|
||||
return(CheckNPCFactionAlly(other_faction) == FACTION_ALLY);
|
||||
bool NPC::IsFactionListAlly(uint32 other_faction)
|
||||
{
|
||||
return CheckNPCFactionAlly(other_faction) == FACTION_ALLY;
|
||||
}
|
||||
|
||||
int NPC::GetScore()
|
||||
@ -3673,9 +3658,9 @@ void NPC::AIYellForHelp(Mob *sender, Mob *attacker)
|
||||
*/
|
||||
if (mob->GetLevel() >= 50 || mob->AlwaysAggro() || attacker->GetLevelCon(mob->GetLevel()) != CON_GRAY) {
|
||||
if (mob->GetPrimaryFaction() == sender->CastToNPC()->GetPrimaryFaction()) {
|
||||
const NPCFactionList *cf = content_db.GetNPCFactionEntry(mob->CastToNPC()->GetNPCFactionID());
|
||||
if (cf) {
|
||||
if (cf->assistprimaryfaction == 0) {
|
||||
const auto f = zone->GetNPCFaction(mob->CastToNPC()->GetNPCFactionID());
|
||||
if (f) {
|
||||
if (f->ignore_primary_assist) {
|
||||
continue; //Same faction and ignore primary assist
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "../common/zone_store.h"
|
||||
#include "zonedump.h"
|
||||
#include "../common/loottable.h"
|
||||
#include "../common/repositories/npc_faction_entries_repository.h"
|
||||
|
||||
#include <deque>
|
||||
#include <list>
|
||||
@ -296,7 +297,7 @@ public:
|
||||
void SetNPCFactionID(int32 in)
|
||||
{
|
||||
npc_faction_id = in;
|
||||
content_db.GetFactionIdsForNPC(npc_faction_id, &faction_list, &primary_faction);
|
||||
content_db.GetFactionIDsForNPC(npc_faction_id, &faction_list, &primary_faction);
|
||||
}
|
||||
|
||||
glm::vec4 m_SpawnPoint;
|
||||
@ -564,7 +565,6 @@ protected:
|
||||
|
||||
friend class EntityList;
|
||||
friend class Aura;
|
||||
std::list<struct NPCFaction*> faction_list;
|
||||
uint32 copper;
|
||||
uint32 silver;
|
||||
uint32 gold;
|
||||
@ -573,6 +573,8 @@ protected:
|
||||
uint32 spawn_group_id;
|
||||
uint16 wp_m;
|
||||
|
||||
std::list<NpcFactionEntriesRepository::NpcFactionEntries> faction_list;
|
||||
|
||||
int32 npc_faction_id;
|
||||
int32 primary_faction;
|
||||
int32 faction_amount;
|
||||
|
||||
@ -344,9 +344,9 @@ int Perl_Client_GetFactionLevel(Client* self, uint32 char_id, uint32 npc_id, uin
|
||||
return self->GetFactionLevel(char_id, npc_id, race_id, class_id, deity_id, faction_id, tnpc);
|
||||
}
|
||||
|
||||
void Perl_Client_SetFactionLevel(Client* self, uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity) // @categories Faction
|
||||
void Perl_Client_SetFactionLevel(Client* self, uint32 char_id, uint32 npc_faction_id, uint8 char_class, uint8 char_race, uint8 char_deity) // @categories Faction
|
||||
{
|
||||
self->SetFactionLevel(char_id, npc_id, char_class, char_race, char_deity);
|
||||
self->SetFactionLevel(char_id, npc_faction_id, char_class, char_race, char_deity);
|
||||
}
|
||||
|
||||
void Perl_Client_SetFactionLevel2(Client* self, uint32 char_id, int32 faction_id, uint8 char_class, uint8 char_race, uint8 char_deity, int32 value) // @categories Faction
|
||||
|
||||
@ -1440,6 +1440,7 @@ void QuestManager::rewardfaction(int faction_id, int faction_value) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
if (initiator) {
|
||||
if (faction_id != 0 && faction_value != 0) {
|
||||
zone->LoadFactionAssociation(faction_id);
|
||||
initiator->RewardFaction(faction_id, faction_value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1057,6 +1057,7 @@ void ClientTaskState::RewardTask(Client *c, const TaskInformation *ti, ClientTas
|
||||
|
||||
// just use normal NPC faction ID stuff
|
||||
if (ti->faction_reward && ti->faction_amount == 0) {
|
||||
zone->LoadNPCFaction(ti->faction_reward);
|
||||
c->SetFactionLevel(
|
||||
c->CharacterID(),
|
||||
ti->faction_reward,
|
||||
@ -1065,6 +1066,8 @@ void ClientTaskState::RewardTask(Client *c, const TaskInformation *ti, ClientTas
|
||||
c->GetDeity()
|
||||
);
|
||||
} else if (ti->faction_reward != 0 && ti->faction_amount != 0) {
|
||||
// faction_reward is a faction ID
|
||||
zone->LoadFactionAssociation(ti->faction_reward);
|
||||
c->RewardFaction(
|
||||
ti->faction_reward,
|
||||
ti->faction_amount
|
||||
|
||||
@ -1989,6 +1989,17 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ServerOP_ReloadFactions:
|
||||
{
|
||||
if (zone && zone->IsLoaded()) {
|
||||
zone->SendReloadMessage("Factions");
|
||||
content_db.LoadFactionData();
|
||||
zone->ReloadNPCFactions();
|
||||
zone->ReloadFactionAssociations();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ServerOP_ReloadLevelEXPMods:
|
||||
{
|
||||
if (zone && zone->IsLoaded()) {
|
||||
@ -3497,16 +3508,6 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
LogError("Loading items failed!");
|
||||
}
|
||||
|
||||
LogInfo("Loading npc faction lists");
|
||||
if (!content_db.LoadNPCFactionLists(hotfix_name)) {
|
||||
LogError("Loading npcs faction lists failed!");
|
||||
}
|
||||
|
||||
LogInfo("Loading faction association hits");
|
||||
if (!content_db.LoadFactionAssociation(hotfix_name)) {
|
||||
LogError("Loading faction association hits failed!");
|
||||
}
|
||||
|
||||
LogInfo("Loading loot tables");
|
||||
if (!content_db.LoadLoot(hotfix_name)) {
|
||||
LogError("Loading loot failed!");
|
||||
|
||||
22
zone/zone.h
22
zone/zone.h
@ -38,6 +38,9 @@
|
||||
#include "queryserv.h"
|
||||
#include "../common/discord/discord.h"
|
||||
#include "../common/repositories/dynamic_zone_templates_repository.h"
|
||||
#include "../common/repositories/npc_faction_repository.h"
|
||||
#include "../common/repositories/npc_faction_entries_repository.h"
|
||||
#include "../common/repositories/faction_association_repository.h"
|
||||
|
||||
struct EXPModifier
|
||||
{
|
||||
@ -407,6 +410,21 @@ public:
|
||||
|
||||
void ReloadContentFlags();
|
||||
|
||||
void LoadNPCFaction(const uint32 npc_faction_id);
|
||||
void LoadNPCFactions(const std::vector<uint32>& npc_faction_ids);
|
||||
void ClearNPCFactions();
|
||||
void ReloadNPCFactions();
|
||||
NpcFactionRepository::NpcFaction* GetNPCFaction(const uint32 npc_faction_id);
|
||||
std::vector<NpcFactionEntriesRepository::NpcFactionEntries> GetNPCFactionEntries(const uint32 npc_faction_id) const;
|
||||
|
||||
void LoadNPCFactionAssociation(const uint32 npc_faction_id);
|
||||
void LoadNPCFactionAssociations(const std::vector<uint32>& npc_faction_ids);
|
||||
void LoadFactionAssociation(const uint32 faction_id);
|
||||
void LoadFactionAssociations(const std::vector<uint32>& faction_ids);
|
||||
void ClearFactionAssociations();
|
||||
void ReloadFactionAssociations();
|
||||
FactionAssociationRepository::FactionAssociation* GetFactionAssociation(const uint32 faction_id);
|
||||
|
||||
private:
|
||||
bool allow_mercs;
|
||||
bool can_bind;
|
||||
@ -457,6 +475,10 @@ private:
|
||||
Timer qglobal_purge_timer;
|
||||
ZoneSpellsBlocked *blocked_spells;
|
||||
|
||||
// Factions
|
||||
std::vector<NpcFactionRepository::NpcFaction> m_npc_factions = { };
|
||||
std::vector<NpcFactionEntriesRepository::NpcFactionEntries> m_npc_faction_entries = { };
|
||||
std::vector<FactionAssociationRepository::FactionAssociation> m_faction_associations = { };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
277
zone/zone_npc_factions.cpp
Normal file
277
zone/zone_npc_factions.cpp
Normal file
@ -0,0 +1,277 @@
|
||||
#include <vector>
|
||||
#include "zone.h"
|
||||
#include "../common/repositories/npc_faction_repository.h"
|
||||
#include "../common/repositories/npc_faction_entries_repository.h"
|
||||
|
||||
void Zone::LoadNPCFactions(const std::vector<uint32> &npc_faction_ids)
|
||||
{
|
||||
LogFaction(
|
||||
"Load for Faction IDs [{}]",
|
||||
Strings::Join(npc_faction_ids, ", ")
|
||||
);
|
||||
|
||||
if (npc_faction_ids.empty()) {
|
||||
LogFactionDetail("No NPC factions to load.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Narrow the list sent in, to new npc_faction_ids that are being loaded
|
||||
// as the result of a new spawn. Ignore those already loaded.
|
||||
|
||||
std::vector<uint32> new_npc_faction_ids = { };
|
||||
|
||||
for (const auto& e : npc_faction_ids) {
|
||||
bool found = false;
|
||||
|
||||
for (const auto& nf : m_npc_factions) {
|
||||
found = (nf.id == e);
|
||||
if (found) {
|
||||
LogFaction("Already loaded npc_faction [{}]", nf.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This one is new
|
||||
if (!found) {
|
||||
new_npc_faction_ids.emplace_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_npc_faction_ids.empty()) {
|
||||
LogFactionDetail("No New NPC factions to load.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto npc_factions = NpcFactionRepository::GetWhere(
|
||||
content_db,
|
||||
fmt::format(
|
||||
"`id` IN ({})",
|
||||
Strings::Join(new_npc_faction_ids, ", ")
|
||||
)
|
||||
);
|
||||
|
||||
auto npc_faction_entries = NpcFactionEntriesRepository::GetWhere(
|
||||
content_db,
|
||||
fmt::format(
|
||||
"`npc_faction_id` IN ({})",
|
||||
Strings::Join(new_npc_faction_ids, ", ")
|
||||
)
|
||||
);
|
||||
|
||||
for (const auto& e : npc_factions) {
|
||||
m_npc_factions.emplace_back(e);
|
||||
|
||||
for (const auto& f : npc_faction_entries) {
|
||||
m_npc_faction_entries.emplace_back(f);
|
||||
}
|
||||
}
|
||||
|
||||
if (npc_factions.size() > 1) {
|
||||
LogFaction("Loaded [{}] Factions", npc_factions.size());
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::LoadNPCFaction(const uint32 npc_faction_id)
|
||||
{
|
||||
if (!npc_faction_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
LogFaction("LoadNPCFaction for [{}]", npc_faction_id);
|
||||
LoadNPCFactions({ npc_faction_id });
|
||||
}
|
||||
|
||||
void Zone::ClearNPCFactions()
|
||||
{
|
||||
m_npc_factions.clear();
|
||||
m_npc_faction_entries.clear();
|
||||
}
|
||||
|
||||
void Zone::ReloadNPCFactions()
|
||||
{
|
||||
LogFaction("Reloading NPC Factions");
|
||||
|
||||
ClearNPCFactions();
|
||||
|
||||
std::vector<uint32> npc_faction_ids = { };
|
||||
|
||||
for (const auto& n : entity_list.GetNPCList()) {
|
||||
if (n.second->GetNPCFactionID() != 0) {
|
||||
if (
|
||||
std::find(
|
||||
npc_faction_ids.begin(),
|
||||
npc_faction_ids.end(),
|
||||
n.second->GetNPCFactionID()
|
||||
) == npc_faction_ids.end()
|
||||
) {
|
||||
npc_faction_ids.emplace_back(n.second->GetNPCFactionID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoadNPCFactions(npc_faction_ids);
|
||||
}
|
||||
|
||||
NpcFactionRepository::NpcFaction* Zone::GetNPCFaction(const uint32 npc_faction_id)
|
||||
{
|
||||
for (auto& e : m_npc_factions) {
|
||||
if (e.id == npc_faction_id) {
|
||||
return &e;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<NpcFactionEntriesRepository::NpcFactionEntries> Zone::GetNPCFactionEntries(const uint32 npc_faction_id) const
|
||||
{
|
||||
std::vector<NpcFactionEntriesRepository::NpcFactionEntries> npc_faction_entries = { };
|
||||
|
||||
std::vector<uint32> faction_ids;
|
||||
|
||||
for (auto e : m_npc_faction_entries) {
|
||||
if (
|
||||
e.npc_faction_id == npc_faction_id &&
|
||||
std::find(
|
||||
faction_ids.begin(),
|
||||
faction_ids.end(),
|
||||
e.faction_id
|
||||
) == faction_ids.end()
|
||||
) {
|
||||
faction_ids.emplace_back(e.faction_id);
|
||||
npc_faction_entries.emplace_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
return npc_faction_entries;
|
||||
}
|
||||
|
||||
void Zone::LoadNPCFactionAssociations(const std::vector<uint32>& npc_faction_ids)
|
||||
{
|
||||
LogFaction(
|
||||
"Load Associations for NPC Faction IDs [{}]",
|
||||
Strings::Join(npc_faction_ids, ", ")
|
||||
);
|
||||
|
||||
if (npc_faction_ids.empty()) {
|
||||
LogFactionDetail("No Faction Associations to load.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<uint32> faction_ids = { };
|
||||
|
||||
for (const auto& e : npc_faction_ids) {
|
||||
for (const auto& f : m_npc_factions) {
|
||||
bool found = false;
|
||||
if (e == f.id && f.primaryfaction > 0) {
|
||||
for (const auto& a : m_faction_associations) {
|
||||
if (a.id == f.primaryfaction) {
|
||||
found = true;
|
||||
LogFaction("Association [{}] already loaded", a.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
faction_ids.emplace_back(f.primaryfaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (faction_ids.empty()) {
|
||||
LogFactionDetail("No New Faction Associations to load.");
|
||||
}
|
||||
else {
|
||||
LoadFactionAssociations(faction_ids);
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::LoadNPCFactionAssociation(const uint32 npc_faction_id)
|
||||
{
|
||||
if (!npc_faction_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
LoadNPCFactionAssociations({ npc_faction_id });
|
||||
}
|
||||
|
||||
void Zone::LoadFactionAssociations(const std::vector<uint32>& faction_ids)
|
||||
{
|
||||
LogFaction(
|
||||
"These are the primary faction IDs [{}]",
|
||||
Strings::Join(faction_ids, ", ")
|
||||
);
|
||||
|
||||
const auto& faction_associations = FactionAssociationRepository::GetWhere(
|
||||
content_db,
|
||||
fmt::format(
|
||||
"`id` IN ({})",
|
||||
Strings::Join(faction_ids, ", ")
|
||||
)
|
||||
);
|
||||
|
||||
if (faction_associations.empty()) {
|
||||
LogFaction(
|
||||
"No Faction Association Entries to load for Faction IDs [{}]",
|
||||
Strings::Join(faction_ids, ", ")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& e : faction_associations) {
|
||||
m_faction_associations.emplace_back(e);
|
||||
}
|
||||
|
||||
LogFaction("Loaded [{}] Faction Associations.", faction_associations.size());
|
||||
}
|
||||
|
||||
void Zone::LoadFactionAssociation(const uint32 faction_id)
|
||||
{
|
||||
if (!faction_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
LoadFactionAssociations({ faction_id });
|
||||
}
|
||||
|
||||
|
||||
void Zone::ClearFactionAssociations()
|
||||
{
|
||||
m_faction_associations.clear();
|
||||
}
|
||||
|
||||
void Zone::ReloadFactionAssociations()
|
||||
{
|
||||
ClearFactionAssociations();
|
||||
|
||||
std::vector<uint32> npc_faction_ids = { };
|
||||
|
||||
for (const auto& n : entity_list.GetNPCList()) {
|
||||
if (n.second->GetNPCFactionID() != 0) {
|
||||
if (
|
||||
std::find(
|
||||
npc_faction_ids.begin(),
|
||||
npc_faction_ids.end(),
|
||||
n.second->GetNPCFactionID()
|
||||
) == npc_faction_ids.end()
|
||||
) {
|
||||
npc_faction_ids.emplace_back(n.second->GetNPCFactionID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogFaction("Reloading Faction Associations");
|
||||
LoadNPCFactionAssociations(npc_faction_ids);
|
||||
}
|
||||
|
||||
FactionAssociationRepository::FactionAssociation* Zone::GetFactionAssociation(const uint32 faction_id)
|
||||
{
|
||||
for (auto& e : m_faction_associations) {
|
||||
if (e.id == faction_id) {
|
||||
return &e;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
101
zone/zonedb.cpp
101
zone/zonedb.cpp
@ -1746,6 +1746,7 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
||||
}
|
||||
|
||||
std::vector<uint32> npc_ids;
|
||||
std::vector<uint32> npc_faction_ids;
|
||||
|
||||
for (NpcTypesRepository::NpcTypes &n : NpcTypesRepository::GetWhere((Database &) content_db, filter)) {
|
||||
NPCType *t;
|
||||
@ -1798,7 +1799,6 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
||||
t->special_abilities[0] = '\0';
|
||||
}
|
||||
|
||||
|
||||
t->npc_spells_id = n.npc_spells_id;
|
||||
t->npc_spells_effects_id = n.npc_spells_effects_id;
|
||||
t->d_melee_texture1 = n.d_melee_texture1;
|
||||
@ -1845,6 +1845,18 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
||||
t->drakkin_tattoo = n.drakkin_tattoo;
|
||||
t->drakkin_details = n.drakkin_details;
|
||||
|
||||
if (t->npc_faction_id > 0) {
|
||||
if (
|
||||
std::find(
|
||||
npc_faction_ids.begin(),
|
||||
npc_faction_ids.end(),
|
||||
t->npc_faction_id
|
||||
) == npc_faction_ids.end()
|
||||
) {
|
||||
npc_faction_ids.emplace_back(t->npc_faction_id);
|
||||
}
|
||||
}
|
||||
|
||||
// armor tint
|
||||
uint32 armor_tint_id = n.armortint_id;
|
||||
t->armor_tint.Head.Color = (n.armortint_red & 0xFF) << 16;
|
||||
@ -1967,6 +1979,11 @@ const NPCType *ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
||||
|
||||
DataBucket::BulkLoadEntities(DataBucketLoadType::NPC, npc_ids);
|
||||
|
||||
if (!npc_faction_ids.empty()) {
|
||||
zone->LoadNPCFactions(npc_faction_ids);
|
||||
zone->LoadNPCFactionAssociations(npc_faction_ids);
|
||||
}
|
||||
|
||||
return npc;
|
||||
}
|
||||
|
||||
@ -3466,30 +3483,6 @@ std::string ZoneDatabase::GetFactionName(int32 faction_id)
|
||||
return faction_name;
|
||||
}
|
||||
|
||||
//o--------------------------------------------------------------
|
||||
//| Name: GetNPCFactionList; Dec. 16, 2001
|
||||
//o--------------------------------------------------------------
|
||||
//| Purpose: Gets a list of faction_id's and values bound to the npc_id. Returns false on failure.
|
||||
//o--------------------------------------------------------------
|
||||
bool ZoneDatabase::GetNPCFactionList(uint32 npcfaction_id, int32* faction_id, int32* value, uint8* temp, int32* primary_faction) {
|
||||
if (npcfaction_id <= 0) {
|
||||
if (primary_faction)
|
||||
*primary_faction = npcfaction_id;
|
||||
return true;
|
||||
}
|
||||
const NPCFactionList* nfl = GetNPCFactionEntry(npcfaction_id);
|
||||
if (!nfl)
|
||||
return false;
|
||||
if (primary_faction)
|
||||
*primary_faction = nfl->primaryfaction;
|
||||
for (int i=0; i<MAX_NPC_FACTIONS; i++) {
|
||||
faction_id[i] = nfl->factionid[i];
|
||||
value[i] = nfl->factionvalue[i];
|
||||
temp[i] = nfl->factiontemp[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//o--------------------------------------------------------------
|
||||
//| Name: SetCharacterFactionLevel; Dec. 20, 2001
|
||||
//o--------------------------------------------------------------
|
||||
@ -3634,46 +3627,40 @@ bool ZoneDatabase::LoadFactionData()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::GetFactionIdsForNPC(uint32 nfl_id, std::list<struct NPCFaction*> *faction_list, int32* primary_faction) {
|
||||
if (nfl_id <= 0) {
|
||||
std::list<struct NPCFaction*>::iterator cur,end;
|
||||
cur = faction_list->begin();
|
||||
end = faction_list->end();
|
||||
for(; cur != end; ++cur) {
|
||||
struct NPCFaction* tmp = *cur;
|
||||
safe_delete(tmp);
|
||||
bool ZoneDatabase::GetFactionIDsForNPC(
|
||||
uint32 npc_faction_id,
|
||||
std::list<NpcFactionEntriesRepository::NpcFactionEntries> *faction_list,
|
||||
int32* primary_faction
|
||||
)
|
||||
{
|
||||
if (npc_faction_id <= 0) {
|
||||
faction_list->clear();
|
||||
|
||||
if (primary_faction) {
|
||||
*primary_faction = npc_faction_id;
|
||||
}
|
||||
|
||||
faction_list->clear();
|
||||
if (primary_faction)
|
||||
*primary_faction = nfl_id;
|
||||
return true;
|
||||
}
|
||||
const NPCFactionList* nfl = GetNPCFactionEntry(nfl_id);
|
||||
if (!nfl)
|
||||
return false;
|
||||
if (primary_faction)
|
||||
*primary_faction = nfl->primaryfaction;
|
||||
|
||||
std::list<struct NPCFaction*>::iterator cur,end;
|
||||
cur = faction_list->begin();
|
||||
end = faction_list->end();
|
||||
for(; cur != end; ++cur) {
|
||||
struct NPCFaction* tmp = *cur;
|
||||
safe_delete(tmp);
|
||||
const auto& npcf = zone->GetNPCFaction(npc_faction_id);
|
||||
if (!npcf) {
|
||||
LogError("No NPC faction entry for [{}]", npc_faction_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& l = zone->GetNPCFactionEntries(npc_faction_id);
|
||||
|
||||
if (primary_faction) {
|
||||
*primary_faction = npcf->primaryfaction;
|
||||
}
|
||||
|
||||
faction_list->clear();
|
||||
for (int i=0; i<MAX_NPC_FACTIONS; i++) {
|
||||
struct NPCFaction *pFac;
|
||||
if (nfl->factionid[i]) {
|
||||
pFac = new struct NPCFaction;
|
||||
pFac->factionID = nfl->factionid[i];
|
||||
pFac->value_mod = nfl->factionvalue[i];
|
||||
pFac->npc_value = nfl->factionnpcvalue[i];
|
||||
pFac->temp = nfl->factiontemp[i];
|
||||
faction_list->push_back(pFac);
|
||||
}
|
||||
|
||||
for (const auto& e: l) {
|
||||
faction_list->emplace_back(e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "event_codes.h"
|
||||
#include "../common/repositories/doors_repository.h"
|
||||
#include "../common/races.h"
|
||||
#include "../common/repositories/npc_faction_entries_repository.h"
|
||||
|
||||
#include "bot_database.h"
|
||||
|
||||
@ -505,11 +506,10 @@ public:
|
||||
uint32 UpdateCharacterCorpseConsent(uint32 character_id, uint32 guild_consent_id);
|
||||
|
||||
/* Faction */
|
||||
bool GetNPCFactionList(uint32 npcfaction_id, int32* faction_id, int32* value, uint8* temp, int32* primary_faction = 0);
|
||||
bool GetFactionData(FactionMods* fd, uint32 class_mod, uint32 race_mod, uint32 deity_mod, int32 faction_id); //needed for factions Dec, 16 2001
|
||||
bool GetFactionName(int faction_id, char* name, uint32 buflen); // needed for factions Dec, 16 2001
|
||||
std::string GetFactionName(int faction_id);
|
||||
bool GetFactionIdsForNPC(uint32 nfl_id, std::list<struct NPCFaction*> *faction_list, int32* primary_faction = 0); // improve faction handling
|
||||
bool GetFactionIDsForNPC(uint32 npc_faction_id, std::list<NpcFactionEntriesRepository::NpcFactionEntries>* faction_list, int32* primary_faction = 0); // improve faction handling
|
||||
bool SetCharacterFactionLevel(uint32 char_id, int32 faction_id, int32 value, uint8 temp, faction_map &val_list); // needed for factions Dec, 16 2001
|
||||
bool LoadFactionData();
|
||||
inline uint32 GetMaxFaction() { return max_faction; }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user