Compare commits

..

10 Commits

Author SHA1 Message Date
KimLS b894d7ee3a update base character data repo 2024-10-12 12:52:07 -07:00
KimLS eecfce6514 update allocations table base repo 2024-10-12 12:41:38 -07:00
KimLS 2d6950149a Fix for server side everything showing as MR 2024-10-12 12:12:57 -07:00
KimLS 3945a8c0c0 Add titanium support 2024-10-12 12:02:40 -07:00
KimLS f27209a812 Add sof support 2024-10-12 11:27:37 -07:00
KimLS d4982743bf Add sod support 2024-10-12 11:23:59 -07:00
KimLS e2dd8f5f60 Add support to rof 2024-10-12 11:13:24 -07:00
KimLS bfc0cceecc Basics work for rof2 2024-10-12 11:06:36 -07:00
KimLS c9902881b7 Generate repo; create will save resists to db 2024-10-12 10:47:03 -07:00
KimLS 62bb426847 working on loading resists from character create. 2024-10-11 23:33:23 -07:00
43 changed files with 1021 additions and 1224 deletions
-66
View File
@@ -1,69 +1,3 @@
## [22.57.1] 10/22/2024
### Bots
* Enable Bot Commands Only if Rule Enabled ([#4519](https://github.com/EQEmu/Server/pull/4519)) @Kinglykrab 2024-10-22
* Fix pet buffs from saving duplicates every save ([#4520](https://github.com/EQEmu/Server/pull/4520)) @nytmyr 2024-10-22
### Loginserver
* Automatic Opcode File Creation ([#4521](https://github.com/EQEmu/Server/pull/4521)) @KimLS 2024-10-22
## [22.57.0] 10/20/2024
### Bots
* Add "silent" option to ^spawn and mute raid spawn ([#4494](https://github.com/EQEmu/Server/pull/4494)) @nytmyr 2024-10-05
* Add attack flag when told to attack ([#4490](https://github.com/EQEmu/Server/pull/4490)) @nytmyr 2024-09-29
* Fix timers loading on spawn and zone ([#4516](https://github.com/EQEmu/Server/pull/4516)) @nytmyr 2024-10-20
### Code
* Fixed a typo in Zoning.cpp ([#4515](https://github.com/EQEmu/Server/pull/4515)) @carolus21rex 2024-10-20
* Optimization Code Cleanup ([#4489](https://github.com/EQEmu/Server/pull/4489)) @Akkadius 2024-09-30
* Remove Extra Skill in EQ::skills::GetExtraDamageSkills() ([#4486](https://github.com/EQEmu/Server/pull/4486)) @Kinglykrab 2024-10-03
### Crash
* Fixes a crash when the faction_list db table is empty. ([#4511](https://github.com/EQEmu/Server/pull/4511)) @KimLS 2024-10-14
### Fixes
* Add character_instance_safereturns to tables_to_zero_id ([#4485](https://github.com/EQEmu/Server/pull/4485)) @Morzain 2024-09-26
* Correctly limit max targets of PBAOE ([#4507](https://github.com/EQEmu/Server/pull/4507)) @catapultam-habeo 2024-10-11
* FindBestZ selecting false zone floor as bestz - Results in roambox failures ([#4504](https://github.com/EQEmu/Server/pull/4504)) @fryguy503 2024-10-13
* Fix #set motd Crash ([#4495](https://github.com/EQEmu/Server/pull/4495)) @Kinglykrab 2024-10-05
* Fix `character_exp_modifiers` Default Values ([#4502](https://github.com/EQEmu/Server/pull/4502)) @Kinglykrab 2024-10-09
* Fix a display error regarding a few trader/buyer query errors ([#4514](https://github.com/EQEmu/Server/pull/4514)) @neckkola 2024-10-17
* Fix Group ID 0 in Group::SaveGroupLeaderAA() ([#4487](https://github.com/EQEmu/Server/pull/4487)) @Kinglykrab 2024-10-03
* Fix Mercenary Encounter Crash ([#4509](https://github.com/EQEmu/Server/pull/4509)) @Kinglykrab 2024-10-12
* Fix NPC::CanTalk() Crash ([#4499](https://github.com/EQEmu/Server/pull/4499)) @Kinglykrab 2024-10-07
* Fix Spells:DefaultAOEMaxTargets Default Value ([#4508](https://github.com/EQEmu/Server/pull/4508)) @Kinglykrab 2024-10-12
* Fix Targeted AOE Max Targets Rule ([#4488](https://github.com/EQEmu/Server/pull/4488)) @Kinglykrab 2024-10-03
* fixed a bug where it would use npc value instead of faction value in the database. ([#4491](https://github.com/EQEmu/Server/pull/4491)) @regneq 2024-09-29
* Master of Disguise should apply to illusions casted by others. ([#4506](https://github.com/EQEmu/Server/pull/4506)) @fryguy503 2024-10-11
* Spells - Self Only (Yellow) cast when non group member is targeted ([#4503](https://github.com/EQEmu/Server/pull/4503)) @fryguy503 2024-10-11
### Loginserver
* Larion loginserver support ([#4492](https://github.com/EQEmu/Server/pull/4492)) @KimLS 2024-10-03
* Login Fatal Error Spamming ([#4476](https://github.com/EQEmu/Server/pull/4476)) @KimLS 2024-10-09
### Logs
* Add NPC Trades to Player Events ([#4505](https://github.com/EQEmu/Server/pull/4505)) @Kinglykrab 2024-10-13
### Quest API
* Add Buff Fade Methods to Perl/Lua ([#4501](https://github.com/EQEmu/Server/pull/4501)) @Kinglykrab 2024-10-09
* Add EVENT_READ_ITEM to Perl/Lua ([#4497](https://github.com/EQEmu/Server/pull/4497)) @Kinglykrab 2024-10-08
* Add NPC List Filter Methods to Perl/Lua ([#4493](https://github.com/EQEmu/Server/pull/4493)) @Kinglykrab 2024-10-04
* Add Scripting Support to Mercenaries ([#4500](https://github.com/EQEmu/Server/pull/4500)) @Kinglykrab 2024-10-11
### Rules
* Add Rule to disable PVP Regions ([#4513](https://github.com/EQEmu/Server/pull/4513)) @Kinglykrab 2024-10-17
## [22.56.3] 9/23/2024
### Fixes
+6
View File
@@ -514,6 +514,12 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
c.raid_auto_consent = pp->raidAutoconsent;
c.guild_auto_consent = pp->guildAutoconsent;
c.RestTimer = pp->RestTimer;
c.cold_resist = pp->cold_resist;
c.fire_resist = pp->fire_resist;
c.magic_resist = pp->magic_resist;
c.disease_resist = pp->disease_resist;
c.poison_resist = pp->poison_resist;
c.corruption_resist = pp->corruption_resist;
CharacterDataRepository::ReplaceOne(*this, c);
+6
View File
@@ -1121,6 +1121,12 @@ struct PlayerProfile_Struct
/*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005)
/*19564*/ uint32 RestTimer;
/*19568*/ uint32 char_id; // Found as part of bazaar revamp (5/15/2024)
/*19572*/ uint32 cold_resist;
/*19576*/ uint32 fire_resist;
/*19580*/ uint32 magic_resist;
/*19584*/ uint32 disease_resist;
/*19588*/ uint32 poison_resist;
/*19592*/ uint32 corruption_resist;
// All player profile packets are translated and this overhead is ignored in out-bound packets
PlayerProfile_Struct() : m_player_profile_version(EQ::versions::MobVersion::Unknown) { }
-1
View File
@@ -171,7 +171,6 @@ void EQEmuConfig::parse_config()
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
OpcodeDir = _root["server"]["directories"].get("opcodes", "./").asString();
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
-1
View File
@@ -95,7 +95,6 @@ class EQEmuConfig
std::string PluginDir;
std::string LuaModuleDir;
std::string PatchDir;
std::string OpcodeDir;
std::string SharedMemDir;
std::string LogDir;
@@ -789,36 +789,50 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
);
}
std::string npc_info = fmt::format(
"{} ({})\n",
e.npc_name,
e.npc_id
);
npc_info += fmt::format(
"Is Quest Handin: {}",
e.is_quest_handin ? "Yes" : "No"
);
std::vector<DiscordField> f = {};
BuildDiscordField(&f, "NPC", npc_info);
if (!handin_items_info.empty()) {
BuildDiscordField(&f, "Handin Items", handin_items_info);
BuildDiscordField(
&f,
"Handin Items",
fmt::format(
"{}",
handin_items_info
)
);
}
if (!handin_money_info.empty()) {
BuildDiscordField(&f, "Handin Money", handin_money_info);
BuildDiscordField(
&f,
"Handin Money",
fmt::format(
"{}",
handin_money_info
)
);
}
if (!return_items_info.empty()) {
BuildDiscordField(&f, "Return Items", return_items_info);
BuildDiscordField(
&f,
"Return Items",
fmt::format(
"{}",
return_items_info
)
);
}
if (!return_money_info.empty()) {
BuildDiscordField(&f, "Return Money", return_money_info);
BuildDiscordField(
&f,
"Return Money",
fmt::format(
"{}",
return_money_info
)
);
}
std::vector<DiscordEmbed> embeds = {};
+1 -7
View File
@@ -862,8 +862,6 @@ namespace PlayerEvent {
public:
uint32 item_id;
std::string item_name;
std::vector<uint32> augment_ids;
std::vector<std::string> augment_names;
uint16 charges;
bool attuned;
@@ -874,8 +872,6 @@ namespace PlayerEvent {
ar(
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(augment_ids),
CEREAL_NVP(augment_names),
CEREAL_NVP(charges),
CEREAL_NVP(attuned)
);
@@ -909,7 +905,6 @@ namespace PlayerEvent {
HandinMoney handin_money;
std::vector<HandinEntry> return_items;
HandinMoney return_money;
bool is_quest_handin;
// cereal
template<class Archive>
@@ -921,8 +916,7 @@ namespace PlayerEvent {
CEREAL_NVP(handin_items),
CEREAL_NVP(handin_money),
CEREAL_NVP(return_items),
CEREAL_NVP(return_money),
CEREAL_NVP(is_quest_handin)
CEREAL_NVP(return_money)
);
}
};
+6 -6
View File
@@ -2288,13 +2288,13 @@ namespace RoF
outapp->WriteSInt32(345); // Mana Total ?
// these are needed to fix display bugs
outapp->WriteUInt32(0x19); // base CR
outapp->WriteUInt32(0x19); // base FR
outapp->WriteUInt32(0x19); // base MR
outapp->WriteUInt32(0xf); // base DR
outapp->WriteUInt32(0xf); // base PR
outapp->WriteUInt32(emu->cold_resist); // base CR
outapp->WriteUInt32(emu->fire_resist); // base FR
outapp->WriteUInt32(emu->magic_resist); // base MR
outapp->WriteUInt32(emu->disease_resist); // base DR
outapp->WriteUInt32(emu->poison_resist); // base PR
outapp->WriteUInt32(0xf); // base PhR?
outapp->WriteUInt32(0xf); // base Corrup
outapp->WriteUInt32(emu->corruption_resist); // base Corrup
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown
+6 -6
View File
@@ -2806,13 +2806,13 @@ namespace RoF2
outapp->WriteSInt32(345); // Mana Total ?
// these are needed to fix display bugs
outapp->WriteUInt32(0x19); // base CR
outapp->WriteUInt32(0x19); // base FR
outapp->WriteUInt32(0x19); // base MR
outapp->WriteUInt32(0xf); // base DR
outapp->WriteUInt32(0xf); // base PR
outapp->WriteUInt32(emu->cold_resist); // base CR
outapp->WriteUInt32(emu->fire_resist); // base FR
outapp->WriteUInt32(emu->magic_resist); // base MR
outapp->WriteUInt32(emu->disease_resist); // base DR
outapp->WriteUInt32(emu->poison_resist); // base PR
outapp->WriteUInt32(0xf); // base PhR?
outapp->WriteUInt32(0xf); // base Corrup
outapp->WriteUInt32(emu->corruption_resist); // base Corrup
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown
+19 -7
View File
@@ -1669,15 +1669,27 @@ namespace SoD
// OUT(unknown19584[4]);
// OUT(unknown19588);
const uint8 bytes[] = {
0xa3, 0x02, 0x00, 0x00, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F,
0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
const uint8 unknown12864_bytes[] = {
0xa3, 0x02, 0x00, 0x00, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
memcpy(eq->unknown12864, bytes, sizeof(bytes));
memcpy(eq->unknown12864, unknown12864_bytes, sizeof(unknown12864_bytes));
eq->cold_resist = emu->cold_resist;
eq->fire_resist = emu->fire_resist;
eq->magic_resist = emu->magic_resist;
eq->disease_resist = emu->disease_resist;
eq->poison_resist = emu->poison_resist;
eq->physical_resist = 15;
eq->corruption_resist = emu->corruption_resist;
const uint8 unknown15112_bytes[] = {
0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
memcpy(eq->unknown15112, unknown15112_bytes, sizeof(unknown15112_bytes));
//set the checksum...
CRC32::SetEQChecksum(__packet->pBuffer, sizeof(structs::PlayerProfile_Struct) - 4);
+9 -1
View File
@@ -944,7 +944,15 @@ struct PlayerProfile_Struct
/*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
/*15060*/ uint8 unknown12852[8];
/*15068*/ uint32 available_slots;
/*15072*/ uint8 unknown12864[80]; //#### uint8 uint8 unknown12864[76]; in Titanium ####[80]
/*15072*/ uint8 unknown12864[12]; //#### uint8 uint8 unknown12864[76]; in Titanium ####[80]
/*15084*/ uint32 cold_resist;
/*15088*/ uint32 fire_resist;
/*15092*/ uint32 magic_resist;
/*15096*/ uint32 disease_resist;
/*15100*/ uint32 poison_resist;
/*15104*/ uint32 physical_resist;
/*15108*/ uint32 corruption_resist;
/*15112*/ uint8 unknown15112[40];
//END SUB-STRUCT used for shrouding.
/*15152*/ char name[64]; // Name of player
/*15216*/ char last_name[32]; // Last name of player
+19 -7
View File
@@ -1339,15 +1339,27 @@ namespace SoF
// OUT(unknown19584[4]);
// OUT(unknown19588);
const uint8 bytes[] = {
0xa3, 0x02, 0x00, 0x00, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F,
0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
const uint8 unknown12864_bytes[] = {
0xa3, 0x02, 0x00, 0x00, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
memcpy(eq->unknown12864, bytes, sizeof(bytes));
memcpy(eq->unknown12864, unknown12864_bytes, sizeof(unknown12864_bytes));
eq->cold_resist = emu->cold_resist;
eq->fire_resist = emu->fire_resist;
eq->magic_resist = emu->magic_resist;
eq->disease_resist = emu->disease_resist;
eq->poison_resist = emu->poison_resist;
eq->physical_resist = 15;
eq->corruption_resist = emu->corruption_resist;
const uint8 unknown15112_bytes[] = {
0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
memcpy(eq->unknown15112, unknown15112_bytes, sizeof(unknown15112_bytes));
//set the checksum...
CRC32::SetEQChecksum(__packet->pBuffer, sizeof(structs::PlayerProfile_Struct) - 4);
+10 -1
View File
@@ -944,7 +944,16 @@ struct PlayerProfile_Struct //23576 Octets
/*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
/*15060*/ uint8 unknown12852[8];
/*15068*/ uint32 available_slots;
/*15072*/ uint8 unknown12864[80]; //#### uint8 uint8 unknown12864[76]; in Titanium ####[80]
/*15072*/ uint8 unknown12864[12]; //#### uint8 uint8 unknown12864[76]; in Titanium ####[80]
/*15084*/ uint32 cold_resist;
/*15088*/ uint32 fire_resist;
/*15092*/ uint32 magic_resist;
/*15096*/ uint32 disease_resist;
/*15100*/ uint32 poison_resist;
/*15104*/ uint32 physical_resist;
/*15108*/ uint32 corruption_resist;
/*15112*/ uint8 unknown15112[40];
//END SUB-STRUCT used for shrouding.
/*15120*/ char name[64]; // Name of player
/*15184*/ char last_name[32]; // Last name of player
+16 -5
View File
@@ -1600,14 +1600,25 @@ namespace Titanium
// OUT(unknown19584[4]);
// OUT(unknown19588);
const uint8 unknown12864_bytes[] = {
0x78, 0x03, 0x00, 0x00, 0x1A, 0x04, 0x00, 0x00, 0x1A, 0x04, 0x00, 0x00
};
const uint8 bytes[] = {
0x78, 0x03, 0x00, 0x00, 0x1A, 0x04, 0x00, 0x00, 0x1A, 0x04, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F, 0x09, 0x00, 0x00, 0x00,
memcpy(eq->unknown12864, unknown12864_bytes, sizeof(unknown12864_bytes));
eq->cold_resist = emu->cold_resist;
eq->fire_resist = emu->fire_resist;
eq->magic_resist = emu->magic_resist;
eq->disease_resist = emu->disease_resist;
eq->poison_resist = emu->poison_resist;
eq->physical_resist = 15;
const uint8 unknown12900_bytes[] = {
0x1F, 0x85, 0xEB, 0x3E, 0x33, 0x33, 0x33, 0x3F, 0x09, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14
};
memcpy(eq->unknown12864, bytes, sizeof(bytes));
memcpy(eq->unknown12900, unknown12900_bytes, sizeof(unknown12900_bytes));
//set the checksum...
CRC32::SetEQChecksum(__packet->pBuffer, sizeof(structs::PlayerProfile_Struct) - 4);
+8 -1
View File
@@ -879,7 +879,14 @@ struct PlayerProfile_Struct
/*12564*/ PotionBelt_Struct potionbelt; // potion belt
/*12852*/ uint8 unknown12852[8];
/*12860*/ uint32 available_slots;
/*12864*/ uint8 unknown12864[76];
/*12864*/ uint8 unknown12864[12];
/*12876*/ uint32 cold_resist;
/*12880*/ uint32 fire_resist;
/*12884*/ uint32 magic_resist;
/*12888*/ uint32 disease_resist;
/*12892*/ uint32 poison_resist;
/*12896*/ uint32 physical_resist;
/*12900*/ uint8 unknown12900[40];
/*12940*/ char name[64]; // Name of player
/*13004*/ char last_name[32]; // Last name of player
/*13036*/ uint32 guild_id; // guildid
-11
View File
@@ -74,11 +74,6 @@ void PathManager::LoadPaths()
m_patch_path = fs::relative(fs::path{m_server_path + "/" + c->PatchDir}).string();
}
// patches
if (File::Exists(fs::path{ m_server_path + "/" + c->OpcodeDir }.string())) {
m_opcode_path = fs::relative(fs::path{ m_server_path + "/" + c->OpcodeDir }).string();
}
// shared_memory_path
if (File::Exists(fs::path{m_server_path + "/" + c->SharedMemDir}.string())) {
m_shared_memory_path = fs::relative(fs::path{ m_server_path + "/" + c->SharedMemDir }).string();
@@ -94,7 +89,6 @@ void PathManager::LoadPaths()
LogInfo("lua_modules path [{}]", m_lua_modules_path);
LogInfo("maps path [{}]", m_maps_path);
LogInfo("patches path [{}]", m_patch_path);
LogInfo("opcode path [{}]", m_opcode_path);
LogInfo("plugins path [{}]", m_plugins_path);
LogInfo("quests path [{}]", m_quests_path);
LogInfo("shared_memory path [{}]", m_shared_memory_path);
@@ -135,11 +129,6 @@ const std::string &PathManager::GetPatchPath() const
return m_patch_path;
}
const std::string &PathManager::GetOpcodePath() const
{
return m_opcode_path;
}
const std::string &PathManager::GetLuaModulesPath() const
{
return m_lua_modules_path;
-2
View File
@@ -13,7 +13,6 @@ public:
[[nodiscard]] const std::string &GetLuaModulesPath() const;
[[nodiscard]] const std::string &GetMapsPath() const;
[[nodiscard]] const std::string &GetPatchPath() const;
[[nodiscard]] const std::string &GetOpcodePath() const;
[[nodiscard]] const std::string &GetPluginsPath() const;
[[nodiscard]] const std::string &GetQuestsPath() const;
[[nodiscard]] const std::string &GetServerPath() const;
@@ -25,7 +24,6 @@ private:
std::string m_lua_modules_path;
std::string m_maps_path;
std::string m_patch_path;
std::string m_opcode_path;
std::string m_plugins_path;
std::string m_quests_path;
std::string m_server_path;
@@ -34,6 +34,12 @@ public:
uint32_t alloc_int;
uint32_t alloc_wis;
uint32_t alloc_cha;
uint32_t base_cr;
uint32_t base_fr;
uint32_t base_mr;
uint32_t base_dr;
uint32_t base_pr;
uint32_t base_corrup;
};
static std::string PrimaryKey()
@@ -59,6 +65,12 @@ public:
"alloc_int",
"alloc_wis",
"alloc_cha",
"base_cr",
"base_fr",
"base_mr",
"base_dr",
"base_pr",
"base_corrup",
};
}
@@ -80,6 +92,12 @@ public:
"alloc_int",
"alloc_wis",
"alloc_cha",
"base_cr",
"base_fr",
"base_mr",
"base_dr",
"base_pr",
"base_corrup",
};
}
@@ -135,6 +153,12 @@ public:
e.alloc_int = 0;
e.alloc_wis = 0;
e.alloc_cha = 0;
e.base_cr = 0;
e.base_fr = 0;
e.base_mr = 0;
e.base_dr = 0;
e.base_pr = 0;
e.base_corrup = 0;
return e;
}
@@ -186,6 +210,12 @@ public:
e.alloc_int = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.alloc_wis = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.alloc_cha = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.base_cr = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
e.base_fr = row[16] ? static_cast<uint32_t>(strtoul(row[16], nullptr, 10)) : 0;
e.base_mr = row[17] ? static_cast<uint32_t>(strtoul(row[17], nullptr, 10)) : 0;
e.base_dr = row[18] ? static_cast<uint32_t>(strtoul(row[18], nullptr, 10)) : 0;
e.base_pr = row[19] ? static_cast<uint32_t>(strtoul(row[19], nullptr, 10)) : 0;
e.base_corrup = row[20] ? static_cast<uint32_t>(strtoul(row[20], nullptr, 10)) : 0;
return e;
}
@@ -234,6 +264,12 @@ public:
v.push_back(columns[12] + " = " + std::to_string(e.alloc_int));
v.push_back(columns[13] + " = " + std::to_string(e.alloc_wis));
v.push_back(columns[14] + " = " + std::to_string(e.alloc_cha));
v.push_back(columns[15] + " = " + std::to_string(e.base_cr));
v.push_back(columns[16] + " = " + std::to_string(e.base_fr));
v.push_back(columns[17] + " = " + std::to_string(e.base_mr));
v.push_back(columns[18] + " = " + std::to_string(e.base_dr));
v.push_back(columns[19] + " = " + std::to_string(e.base_pr));
v.push_back(columns[20] + " = " + std::to_string(e.base_corrup));
auto results = db.QueryDatabase(
fmt::format(
@@ -270,6 +306,12 @@ public:
v.push_back(std::to_string(e.alloc_int));
v.push_back(std::to_string(e.alloc_wis));
v.push_back(std::to_string(e.alloc_cha));
v.push_back(std::to_string(e.base_cr));
v.push_back(std::to_string(e.base_fr));
v.push_back(std::to_string(e.base_mr));
v.push_back(std::to_string(e.base_dr));
v.push_back(std::to_string(e.base_pr));
v.push_back(std::to_string(e.base_corrup));
auto results = db.QueryDatabase(
fmt::format(
@@ -314,6 +356,12 @@ public:
v.push_back(std::to_string(e.alloc_int));
v.push_back(std::to_string(e.alloc_wis));
v.push_back(std::to_string(e.alloc_cha));
v.push_back(std::to_string(e.base_cr));
v.push_back(std::to_string(e.base_fr));
v.push_back(std::to_string(e.base_mr));
v.push_back(std::to_string(e.base_dr));
v.push_back(std::to_string(e.base_pr));
v.push_back(std::to_string(e.base_corrup));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -362,6 +410,12 @@ public:
e.alloc_int = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.alloc_wis = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.alloc_cha = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.base_cr = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
e.base_fr = row[16] ? static_cast<uint32_t>(strtoul(row[16], nullptr, 10)) : 0;
e.base_mr = row[17] ? static_cast<uint32_t>(strtoul(row[17], nullptr, 10)) : 0;
e.base_dr = row[18] ? static_cast<uint32_t>(strtoul(row[18], nullptr, 10)) : 0;
e.base_pr = row[19] ? static_cast<uint32_t>(strtoul(row[19], nullptr, 10)) : 0;
e.base_corrup = row[20] ? static_cast<uint32_t>(strtoul(row[20], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -401,6 +455,12 @@ public:
e.alloc_int = row[12] ? static_cast<uint32_t>(strtoul(row[12], nullptr, 10)) : 0;
e.alloc_wis = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.alloc_cha = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.base_cr = row[15] ? static_cast<uint32_t>(strtoul(row[15], nullptr, 10)) : 0;
e.base_fr = row[16] ? static_cast<uint32_t>(strtoul(row[16], nullptr, 10)) : 0;
e.base_mr = row[17] ? static_cast<uint32_t>(strtoul(row[17], nullptr, 10)) : 0;
e.base_dr = row[18] ? static_cast<uint32_t>(strtoul(row[18], nullptr, 10)) : 0;
e.base_pr = row[19] ? static_cast<uint32_t>(strtoul(row[19], nullptr, 10)) : 0;
e.base_corrup = row[20] ? static_cast<uint32_t>(strtoul(row[20], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -490,6 +550,12 @@ public:
v.push_back(std::to_string(e.alloc_int));
v.push_back(std::to_string(e.alloc_wis));
v.push_back(std::to_string(e.alloc_cha));
v.push_back(std::to_string(e.base_cr));
v.push_back(std::to_string(e.base_fr));
v.push_back(std::to_string(e.base_mr));
v.push_back(std::to_string(e.base_dr));
v.push_back(std::to_string(e.base_pr));
v.push_back(std::to_string(e.base_corrup));
auto results = db.QueryDatabase(
fmt::format(
@@ -527,6 +593,12 @@ public:
v.push_back(std::to_string(e.alloc_int));
v.push_back(std::to_string(e.alloc_wis));
v.push_back(std::to_string(e.alloc_cha));
v.push_back(std::to_string(e.base_cr));
v.push_back(std::to_string(e.base_fr));
v.push_back(std::to_string(e.base_mr));
v.push_back(std::to_string(e.base_dr));
v.push_back(std::to_string(e.base_pr));
v.push_back(std::to_string(e.base_corrup));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -123,6 +123,12 @@ public:
uint32_t aa_points_old;
uint32_t e_last_invsnapshot;
time_t deleted_at;
uint32_t cold_resist;
uint32_t fire_resist;
uint32_t magic_resist;
uint32_t disease_resist;
uint32_t poison_resist;
uint32_t corruption_resist;
};
static std::string PrimaryKey()
@@ -237,6 +243,12 @@ public:
"aa_points_old",
"e_last_invsnapshot",
"deleted_at",
"cold_resist",
"fire_resist",
"magic_resist",
"disease_resist",
"poison_resist",
"corruption_resist",
};
}
@@ -347,6 +359,12 @@ public:
"aa_points_old",
"e_last_invsnapshot",
"UNIX_TIMESTAMP(deleted_at)",
"cold_resist",
"fire_resist",
"magic_resist",
"disease_resist",
"poison_resist",
"corruption_resist",
};
}
@@ -491,6 +509,12 @@ public:
e.aa_points_old = 0;
e.e_last_invsnapshot = 0;
e.deleted_at = 0;
e.cold_resist = 0;
e.fire_resist = 0;
e.magic_resist = 0;
e.disease_resist = 0;
e.poison_resist = 0;
e.corruption_resist = 0;
return e;
}
@@ -631,6 +655,12 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.cold_resist = row[104] ? static_cast<uint32_t>(strtoul(row[104], nullptr, 10)) : 0;
e.fire_resist = row[105] ? static_cast<uint32_t>(strtoul(row[105], nullptr, 10)) : 0;
e.magic_resist = row[106] ? static_cast<uint32_t>(strtoul(row[106], nullptr, 10)) : 0;
e.disease_resist = row[107] ? static_cast<uint32_t>(strtoul(row[107], nullptr, 10)) : 0;
e.poison_resist = row[108] ? static_cast<uint32_t>(strtoul(row[108], nullptr, 10)) : 0;
e.corruption_resist = row[109] ? static_cast<uint32_t>(strtoul(row[109], nullptr, 10)) : 0;
return e;
}
@@ -767,6 +797,12 @@ public:
v.push_back(columns[101] + " = " + std::to_string(e.aa_points_old));
v.push_back(columns[102] + " = " + std::to_string(e.e_last_invsnapshot));
v.push_back(columns[103] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(columns[104] + " = " + std::to_string(e.cold_resist));
v.push_back(columns[105] + " = " + std::to_string(e.fire_resist));
v.push_back(columns[106] + " = " + std::to_string(e.magic_resist));
v.push_back(columns[107] + " = " + std::to_string(e.disease_resist));
v.push_back(columns[108] + " = " + std::to_string(e.poison_resist));
v.push_back(columns[109] + " = " + std::to_string(e.corruption_resist));
auto results = db.QueryDatabase(
fmt::format(
@@ -892,6 +928,12 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.cold_resist));
v.push_back(std::to_string(e.fire_resist));
v.push_back(std::to_string(e.magic_resist));
v.push_back(std::to_string(e.disease_resist));
v.push_back(std::to_string(e.poison_resist));
v.push_back(std::to_string(e.corruption_resist));
auto results = db.QueryDatabase(
fmt::format(
@@ -1025,6 +1067,12 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.cold_resist));
v.push_back(std::to_string(e.fire_resist));
v.push_back(std::to_string(e.magic_resist));
v.push_back(std::to_string(e.disease_resist));
v.push_back(std::to_string(e.poison_resist));
v.push_back(std::to_string(e.corruption_resist));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -1162,6 +1210,12 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.cold_resist = row[104] ? static_cast<uint32_t>(strtoul(row[104], nullptr, 10)) : 0;
e.fire_resist = row[105] ? static_cast<uint32_t>(strtoul(row[105], nullptr, 10)) : 0;
e.magic_resist = row[106] ? static_cast<uint32_t>(strtoul(row[106], nullptr, 10)) : 0;
e.disease_resist = row[107] ? static_cast<uint32_t>(strtoul(row[107], nullptr, 10)) : 0;
e.poison_resist = row[108] ? static_cast<uint32_t>(strtoul(row[108], nullptr, 10)) : 0;
e.corruption_resist = row[109] ? static_cast<uint32_t>(strtoul(row[109], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -1290,6 +1344,12 @@ public:
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.cold_resist = row[104] ? static_cast<uint32_t>(strtoul(row[104], nullptr, 10)) : 0;
e.fire_resist = row[105] ? static_cast<uint32_t>(strtoul(row[105], nullptr, 10)) : 0;
e.magic_resist = row[106] ? static_cast<uint32_t>(strtoul(row[106], nullptr, 10)) : 0;
e.disease_resist = row[107] ? static_cast<uint32_t>(strtoul(row[107], nullptr, 10)) : 0;
e.poison_resist = row[108] ? static_cast<uint32_t>(strtoul(row[108], nullptr, 10)) : 0;
e.corruption_resist = row[109] ? static_cast<uint32_t>(strtoul(row[109], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@@ -1468,6 +1528,12 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.cold_resist));
v.push_back(std::to_string(e.fire_resist));
v.push_back(std::to_string(e.magic_resist));
v.push_back(std::to_string(e.disease_resist));
v.push_back(std::to_string(e.poison_resist));
v.push_back(std::to_string(e.corruption_resist));
auto results = db.QueryDatabase(
fmt::format(
@@ -1594,6 +1660,12 @@ public:
v.push_back(std::to_string(e.aa_points_old));
v.push_back(std::to_string(e.e_last_invsnapshot));
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(std::to_string(e.cold_resist));
v.push_back(std::to_string(e.fire_resist));
v.push_back(std::to_string(e.magic_resist));
v.push_back(std::to_string(e.disease_resist));
v.push_back(std::to_string(e.poison_resist));
v.push_back(std::to_string(e.corruption_resist));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -236,10 +236,6 @@ public:
)
);
if (buyers.empty()) {
return all_entries;
}
std::vector<std::string> char_ids{};
for (auto const &bl : buyers) {
char_ids.push_back((std::to_string(bl.char_id)));
-4
View File
@@ -120,10 +120,6 @@ public:
}
DeleteWhere(db, fmt::format("`char_id` = '{}';", char_id));
if (buy_line_ids.empty()) {
return false;
}
BaseBuyerBuyLinesRepository::DeleteWhere(
db,
fmt::format("`id` IN({})", Strings::Implode(", ", buy_line_ids))
-4
View File
@@ -217,10 +217,6 @@ public:
delete_ids.push_back(std::to_string(e.id));
}
if (delete_ids.empty()) {
return 0;
}
return DeleteWhere(db, fmt::format("`id` IN({})", Strings::Implode(",", delete_ids)));
}
};
+1 -2
View File
@@ -338,7 +338,6 @@ RULE_STRING(World, IPExemptionZones, "", "Comma-delimited list of zones to exclu
RULE_STRING(World, MOTD, "", "Server MOTD sent on login, change from empty to have this be used instead of variables table 'motd' value")
RULE_STRING(World, Rules, "", "Server Rules, change from empty to have this be used instead of variables table 'rules' value, lines are pipe (|) separated, example: A|B|C")
RULE_BOOL(World, EnableAutoLogin, false, "Enables or disables auto login of characters, allowing people to log characters in directly from loginserver to ingame")
RULE_BOOL(World, EnablePVPRegions, true, "Enables or disables PVP Regions automatically setting your PVP flag")
RULE_CATEGORY_END()
RULE_CATEGORY(Zone)
@@ -517,7 +516,7 @@ RULE_INT(Spells, HealAmountMessageFilterThreshold, 100, "Lifetaps below this thr
RULE_BOOL(Spells, SnareOverridesSpeedBonuses, false, "Enabling will allow snares to override any speed bonuses the entity may have. Default: False")
RULE_INT(Spells, TargetedAOEMaxTargets, 4, "Max number of targets a Targeted AOE spell can cast on. Set to 0 for no limit.")
RULE_INT(Spells, PointBlankAOEMaxTargets, 0, "Max number of targets a Point-Blank AOE spell can cast on. Set to 0 for no limit.")
RULE_INT(Spells, DefaultAOEMaxTargets, 0, "Max number of targets that an AOE spell which does not meet other descriptions can cast on. Set to 0 for no limit.")
RULE_INT(Spells, DefaultAOEMaxTargets, 4, "Max number of targets that an AOE spell which does not meet other descriptions can cast on. Set to 0 for no limit.")
RULE_CATEGORY_END()
RULE_CATEGORY(Combat)
+1 -1
View File
@@ -25,7 +25,7 @@
// Build variables
// these get injected during the build pipeline
#define CURRENT_VERSION "22.57.1-dev" // always append -dev to the current version for custom-builds
#define CURRENT_VERSION "22.56.3-dev" // always append -dev to the current version for custom-builds
#define LOGIN_VERSION "0.8.0"
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
+17 -84
View File
@@ -7,79 +7,6 @@ extern bool run_server;
#include "../common/eqemu_logsys.h"
#include "../common/misc.h"
#include "../common/path_manager.h"
#include "../common/file.h"
void CheckTitaniumOpcodeFile(const std::string &path) {
if (File::Exists(path)) {
return;
}
auto f = fopen(path.c_str(), "w");
if (f) {
fprintf(f, "#EQEmu Public Login Server OPCodes\n");
fprintf(f, "OP_SessionReady=0x0001\n");
fprintf(f, "OP_Login=0x0002\n");
fprintf(f, "OP_ServerListRequest=0x0004\n");
fprintf(f, "OP_PlayEverquestRequest=0x000d\n");
fprintf(f, "OP_PlayEverquestResponse=0x0021\n");
fprintf(f, "OP_ChatMessage=0x0016\n");
fprintf(f, "OP_LoginAccepted=0x0017\n");
fprintf(f, "OP_ServerListResponse=0x0018\n");
fprintf(f, "OP_Poll=0x0029\n");
fprintf(f, "OP_EnterChat=0x000f\n");
fprintf(f, "OP_PollResponse=0x0011\n");
fclose(f);
}
}
void CheckSoDOpcodeFile(const std::string& path) {
if (File::Exists(path)) {
return;
}
auto f = fopen(path.c_str(), "w");
if (f) {
fprintf(f, "#EQEmu Public Login Server OPCodes\n");
fprintf(f, "OP_SessionReady=0x0001\n");
fprintf(f, "OP_Login=0x0002\n");
fprintf(f, "OP_ServerListRequest=0x0004\n");
fprintf(f, "OP_PlayEverquestRequest=0x000d\n");
fprintf(f, "OP_PlayEverquestResponse=0x0022\n");
fprintf(f, "OP_ChatMessage=0x0017\n");
fprintf(f, "OP_LoginAccepted=0x0018\n");
fprintf(f, "OP_ServerListResponse=0x0019\n");
fprintf(f, "OP_Poll=0x0029\n");
fprintf(f, "OP_LoginExpansionPacketData=0x0031\n");
fprintf(f, "OP_EnterChat=0x000f\n");
fprintf(f, "OP_PollResponse=0x0011\n");
fclose(f);
}
}
void CheckLarionOpcodeFile(const std::string& path) {
if (File::Exists(path)) {
return;
}
auto f = fopen(path.c_str(), "w");
if (f) {
fprintf(f, "#EQEmu Public Login Server OPCodes\n");
fprintf(f, "OP_SessionReady=0x0001\n");
fprintf(f, "OP_Login=0x0002\n");
fprintf(f, "OP_ServerListRequest=0x0004\n");
fprintf(f, "OP_PlayEverquestRequest=0x000d\n");
fprintf(f, "OP_PlayEverquestResponse=0x0022\n");
fprintf(f, "OP_ChatMessage=0x0017\n");
fprintf(f, "OP_LoginAccepted=0x0018\n");
fprintf(f, "OP_ServerListResponse=0x0019\n");
fprintf(f, "OP_Poll=0x0029\n");
fprintf(f, "OP_EnterChat=0x000f\n");
fprintf(f, "OP_PollResponse=0x0011\n");
fprintf(f, "OP_SystemFingerprint=0x0016\n");
fprintf(f, "OP_ExpansionList=0x0030\n");
fclose(f);
}
}
ClientManager::ClientManager()
{
@@ -92,12 +19,14 @@ ClientManager::ClientManager()
std::string opcodes_path = fmt::format(
"{}/{}",
path.GetOpcodePath(),
path.GetServerPath(),
server.config.GetVariableString(
"client_configuration",
"titanium_opcodes",
"login_opcodes.conf"
)
);
CheckTitaniumOpcodeFile(opcodes_path);
if (!titanium_ops->LoadOpcodes(opcodes_path.c_str())) {
LogError(
"ClientManager fatal error: couldn't load opcodes for Titanium file [{0}]",
@@ -129,12 +58,14 @@ ClientManager::ClientManager()
opcodes_path = fmt::format(
"{}/{}",
path.GetOpcodePath(),
"login_opcodes_sod.conf"
path.GetServerPath(),
server.config.GetVariableString(
"client_configuration",
"sod_opcodes",
"login_opcodes.conf"
)
);
CheckSoDOpcodeFile(opcodes_path);
if (!sod_ops->LoadOpcodes(opcodes_path.c_str())) {
LogError(
"ClientManager fatal error: couldn't load opcodes for SoD file {0}",
@@ -167,12 +98,14 @@ ClientManager::ClientManager()
opcodes_path = fmt::format(
"{}/{}",
path.GetOpcodePath(),
"login_opcodes_larion.conf"
path.GetServerPath(),
server.config.GetVariableString(
"client_configuration",
"larion_opcodes",
"login_opcodes.conf"
)
);
CheckLarionOpcodeFile(opcodes_path);
if (!larion_ops->LoadOpcodes(opcodes_path.c_str())) {
LogError(
"ClientManager fatal error: couldn't load opcodes for Larion file [{0}]",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "eqemu-server",
"version": "22.57.1",
"version": "22.56.3",
"repository": {
"type": "git",
"url": "https://github.com/EQEmu/Server.git"
+1
View File
@@ -56,6 +56,7 @@ SET(world_headers
login_server.h
login_server_list.h
queryserv.h
race_combos.h
shared_task_manager.h
shared_task_world_messaging.h
sof_char_create_data.h
+312 -227
View File
@@ -47,6 +47,7 @@
#include "clientlist.h"
#include "wguild_mgr.h"
#include "sof_char_create_data.h"
#include "race_combos.h"
#include "../common/zone_store.h"
#include "../common/repositories/account_repository.h"
#include "../common/repositories/player_event_logs_repository.h"
@@ -85,8 +86,8 @@
#include <unistd.h>
#endif
std::vector<RaceClassAllocation> character_create_allocations;
std::vector<RaceClassCombos> character_create_race_class_combos;
std::vector<CharCreatePointAllocation> character_create_allocations;
std::vector<CharCreateCombination> character_create_race_class_combos;
extern ZSList zoneserver_list;
extern LoginServerList loginserverlist;
@@ -1642,229 +1643,6 @@ void Client::SendApproveWorld()
safe_delete(outapp);
}
bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
{
PlayerProfile_Struct pp;
EQ::InventoryProfile inv;
pp.SetPlayerProfileVersion(EQ::versions::ConvertClientVersionToMobVersion(EQ::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit)));
inv.SetInventoryVersion(EQ::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit));
inv.SetGMInventory(false); // character cannot have gm flag at this point
time_t bday = time(nullptr);
in_addr in;
const uint32 stats_sum = (
cc->AGI +
cc->CHA +
cc->DEX +
cc->INT +
cc->STA +
cc->STR +
cc->WIS
);
in.s_addr = GetIP();
LogInfo(
"Character creation request from [{}] LS [{}] [{}] [{}]",
GetCLE()->LSName(),
GetCLE()->LSID(),
inet_ntoa(in),
GetPort()
);
LogInfo("Name [{}]", name);
LogInfo(
"race [{}] class [{}] gender [{}] deity [{}] start_zone [{}] tutorial [{}]",
cc->race,
cc->class_,
cc->gender,
cc->deity,
cc->start_zone,
cc->tutorial ? "true" : "false"
);
LogInfo(
"AGI [{}] CHA [{}] DEX [{}] INT [{}] STA [{}] STR [{}] WIS [{}] Total [{}]",
cc->AGI,
cc->CHA,
cc->DEX,
cc->INT,
cc->STA,
cc->STR,
cc->WIS,
stats_sum
);
LogInfo("Face [{}] Eye Colors [{}] [{}]", cc->face, cc->eyecolor1, cc->eyecolor2);
LogInfo("Hair [{}] Hair Color [{}]", cc->hairstyle, cc->haircolor);
LogInfo("Beard [{}] Beard Color [{}]", cc->beard, cc->beardcolor);
/* Validate the char creation struct */
if (m_ClientVersionBit & EQ::versions::maskSoFAndLater) {
if (!CheckCharCreateInfoSoF(cc)) {
LogInfo("CheckCharCreateInfo did not validate the request (bad race/class/stats)");
return false;
}
} else {
if (!CheckCharCreateInfoTitanium(cc)) {
LogInfo("CheckCharCreateInfo did not validate the request (bad race/class/stats)");
return false;
}
}
/* Convert incoming cc_s to the new PlayerProfile_Struct */
memset(&pp, 0, sizeof(PlayerProfile_Struct)); // start building the profile
strn0cpy(pp.name, name, sizeof(pp.name));
pp.race = cc->race;
pp.class_ = cc->class_;
pp.gender = cc->gender;
pp.deity = cc->deity;
pp.STR = cc->STR;
pp.STA = cc->STA;
pp.AGI = cc->AGI;
pp.DEX = cc->DEX;
pp.WIS = cc->WIS;
pp.INT = cc->INT;
pp.CHA = cc->CHA;
pp.face = cc->face;
pp.eyecolor1 = cc->eyecolor1;
pp.eyecolor2 = cc->eyecolor2;
pp.hairstyle = cc->hairstyle;
pp.haircolor = cc->haircolor;
pp.beard = cc->beard;
pp.beardcolor = cc->beardcolor;
pp.drakkin_heritage = cc->drakkin_heritage;
pp.drakkin_tattoo = cc->drakkin_tattoo;
pp.drakkin_details = cc->drakkin_details;
pp.birthday = bday;
pp.lastlogin = bday;
pp.level = 1;
pp.points = 5;
pp.cur_hp = 1000;
pp.hunger_level = 6000;
pp.thirst_level = 6000;
/* Set default skills for everybody */
pp.skills[EQ::skills::SkillSwimming] = RuleI(Skills, SwimmingStartValue);
pp.skills[EQ::skills::SkillSenseHeading] = RuleI(Skills, SenseHeadingStartValue);
/* Set Racial and Class specific language and skills */
SetRacialLanguages(&pp);
SetRaceStartingSkills(&pp);
SetClassStartingSkills(&pp);
SetClassLanguages(&pp);
memset(pp.spell_book, std::numeric_limits<uint8>::max(), (sizeof(uint32) * EQ::spells::SPELLBOOK_SIZE));
memset(pp.mem_spells, std::numeric_limits<uint8>::max(), (sizeof(uint32) * EQ::spells::SPELL_GEM_COUNT));
for (auto& b : pp.buffs) {
b.spellid = std::numeric_limits<uint16>::max();
}
/* If server is PVP by default, make all character set to it. */
pp.pvp = database.GetServerType() == 1 ? 1 : 0;
/* If it is an SoF Client and the SoF Start Zone rule is set, send new chars there */
if (m_ClientVersionBit & EQ::versions::maskSoFAndLater) {
LogInfo("Found [SoFStartZoneID] rule setting [{}]", RuleI(World, SoFStartZoneID));
if (RuleI(World, SoFStartZoneID) > 0) {
pp.zone_id = RuleI(World, SoFStartZoneID);
cc->start_zone = pp.zone_id;
}
} else {
LogInfo("Found [TitaniumStartZoneID] rule setting [{}]", RuleI(World, TitaniumStartZoneID));
if (RuleI(World, TitaniumStartZoneID) > 0) { /* if there's a startzone variable put them in there */
pp.zone_id = RuleI(World, TitaniumStartZoneID);
cc->start_zone = pp.zone_id;
}
}
/* use normal starting zone logic to either get defaults, or if startzone was set, load that from the db table.*/
const bool is_valid_start_zone = content_db.GetStartZone(&pp, cc, m_ClientVersionBit & EQ::versions::maskTitaniumAndEarlier);
if (!is_valid_start_zone){
return false;
}
if (!pp.zone_id) {
pp.zone_id = Zones::QEYNOS;
pp.x = pp.y = pp.z = -1;
}
for (uint8 slot_id = 1; slot_id < 5; slot_id++) {
pp.binds[slot_id].zone_id = pp.zone_id;
pp.binds[slot_id].x = pp.x;
pp.binds[slot_id].y = pp.y;
pp.binds[slot_id].z = pp.z;
pp.binds[slot_id].heading = pp.heading;
}
/* Overrides if we have the tutorial flag set! */
if (cc->tutorial && RuleB(World, EnableTutorialButton)) {
pp.zone_id = RuleI(World, TutorialZoneID);
auto z = GetZone(pp.zone_id);
if (z) {
pp.x = z->safe_x;
pp.y = z->safe_y;
pp.z = z->safe_z;
}
}
/* Will either be the same as home or tutorial if enabled. */
if (RuleB(World, StartZoneSameAsBindOnCreation)) {
pp.binds[0].zone_id = pp.zone_id;
pp.binds[0].x = pp.x;
pp.binds[0].y = pp.y;
pp.binds[0].z = pp.z;
pp.binds[0].heading = pp.heading;
}
if (GetZone(pp.zone_id)) {
LogInfo(
"Current location zone_short_name [{}] zone_id [{}] x [{:.2f}] y [{:.2f}] z [{:.2f}] heading [{:.2f}]",
ZoneName(pp.zone_id),
pp.zone_id,
pp.x,
pp.y,
pp.z,
pp.heading
);
}
if (GetZone(pp.binds[0].zone_id)) {
LogInfo(
"Bind location zone_short_name [{}] zone_id [{}] x [{:.2f}] y [{:.2f}] z [{:.2f}] heading [{:.2f}]",
ZoneName(pp.binds[0].zone_id),
pp.binds[0].zone_id,
pp.binds[0].x,
pp.binds[0].y,
pp.binds[0].z,
pp.binds[4].heading
);
}
if (GetZone(pp.binds[4].zone_id)) {
LogInfo(
"Home location zone_short_name [{}] zone_id [{}] x [{:.2f}] y [{:.2f}] z [{:.2f}] heading [{:.2f}]",
ZoneName(pp.binds[4].zone_id),
pp.binds[4].zone_id,
pp.binds[4].x,
pp.binds[4].y,
pp.binds[4].z,
pp.binds[4].heading
);
}
content_db.SetStartingItems(&pp, &inv, pp.race, pp.class_, pp.deity, pp.zone_id, pp.name, GetAdmin());
const bool success = StoreCharacter(GetAccountID(), &pp, &inv);
LogInfo("Character creation {} for [{}]", success ? "succeeded" : "failed", pp.name);
return success;
}
// returns true if the request is ok, false if there's an error
bool CheckCharCreateInfoSoF(CharCreate_Struct* cc)
{
@@ -1873,7 +1651,7 @@ bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
LogInfo("Validating char creation info");
RaceClassCombos class_combo;
CharCreateCombination class_combo;
bool found = false;
int combos = character_create_race_class_combos.size();
for (int i = 0; i < combos; ++i) {
@@ -1893,7 +1671,7 @@ bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
}
uint32 allocs = character_create_allocations.size();
RaceClassAllocation allocation = {0};
CharCreatePointAllocation allocation = { 0 };
found = false;
for (int i = 0; i < allocs; ++i) {
if (character_create_allocations[i].Index == class_combo.AllocationIndex) {
@@ -2132,6 +1910,313 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
return Charerrors == 0;
}
//TODO: these hard coded values should be settable somewhere somehow.
//Also they're not 100% accurate so if I don't make them settable somehow
//we need to go back and match them to the logic that was ripped out of zone
void GetResistsForCharacterCreate(CharCreate_Struct* cc,
bool sofAndLater,
uint32 &cold_resist,
uint32& fire_resist,
uint32& magic_resist,
uint32& disease_resist,
uint32& poison_resist,
uint32& corruption_resist)
{
if (!sofAndLater) {
cold_resist = 25;
fire_resist = 25;
magic_resist = 25;
disease_resist = 15;
poison_resist = 15;
corruption_resist = 15;
return;
}
CharCreateCombination class_combo;
bool found = false;
int combos = character_create_race_class_combos.size();
for (int i = 0; i < combos; ++i) {
if (character_create_race_class_combos[i].Class == cc->class_ &&
character_create_race_class_combos[i].Race == cc->race &&
character_create_race_class_combos[i].Deity == cc->deity &&
character_create_race_class_combos[i].Zone == cc->start_zone) {
class_combo = character_create_race_class_combos[i];
found = true;
break;
}
}
if (!found) {
cold_resist = 25;
fire_resist = 25;
magic_resist = 25;
disease_resist = 15;
poison_resist = 15;
corruption_resist = 15;
return;
}
CharCreatePointAllocation allocation;
found = false;
combos = character_create_allocations.size();
for (int i = 0; i < combos; ++i) {
if (character_create_allocations[i].Index == class_combo.AllocationIndex) {
allocation = character_create_allocations[i];
found = true;
break;
}
}
if (!found) {
cold_resist = 25;
fire_resist = 25;
magic_resist = 25;
disease_resist = 15;
poison_resist = 15;
corruption_resist = 15;
return;
}
cold_resist = allocation.BaseResists[0];
fire_resist = allocation.BaseResists[1];
magic_resist = allocation.BaseResists[2];
disease_resist = allocation.BaseResists[3];
poison_resist = allocation.BaseResists[4];
corruption_resist = allocation.BaseResists[5];
}
bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
{
PlayerProfile_Struct pp;
EQ::InventoryProfile inv;
pp.SetPlayerProfileVersion(EQ::versions::ConvertClientVersionToMobVersion(EQ::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit)));
inv.SetInventoryVersion(EQ::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit));
inv.SetGMInventory(false); // character cannot have gm flag at this point
time_t bday = time(nullptr);
in_addr in;
const uint32 stats_sum = (
cc->AGI +
cc->CHA +
cc->DEX +
cc->INT +
cc->STA +
cc->STR +
cc->WIS
);
in.s_addr = GetIP();
LogInfo(
"Character creation request from [{}] LS [{}] [{}] [{}]",
GetCLE()->LSName(),
GetCLE()->LSID(),
inet_ntoa(in),
GetPort()
);
LogInfo("Name [{}]", name);
LogInfo(
"race [{}] class [{}] gender [{}] deity [{}] start_zone [{}] tutorial [{}]",
cc->race,
cc->class_,
cc->gender,
cc->deity,
cc->start_zone,
cc->tutorial ? "true" : "false"
);
LogInfo(
"AGI [{}] CHA [{}] DEX [{}] INT [{}] STA [{}] STR [{}] WIS [{}] Total [{}]",
cc->AGI,
cc->CHA,
cc->DEX,
cc->INT,
cc->STA,
cc->STR,
cc->WIS,
stats_sum
);
LogInfo("Face [{}] Eye Colors [{}] [{}]", cc->face, cc->eyecolor1, cc->eyecolor2);
LogInfo("Hair [{}] Hair Color [{}]", cc->hairstyle, cc->haircolor);
LogInfo("Beard [{}] Beard Color [{}]", cc->beard, cc->beardcolor);
/* Validate the char creation struct */
if (m_ClientVersionBit & EQ::versions::maskSoFAndLater) {
if (!CheckCharCreateInfoSoF(cc)) {
LogInfo("CheckCharCreateInfo did not validate the request (bad race/class/stats)");
return false;
}
} else {
if (!CheckCharCreateInfoTitanium(cc)) {
LogInfo("CheckCharCreateInfo did not validate the request (bad race/class/stats)");
return false;
}
}
/* Convert incoming cc_s to the new PlayerProfile_Struct */
memset(&pp, 0, sizeof(PlayerProfile_Struct)); // start building the profile
strn0cpy(pp.name, name, sizeof(pp.name));
pp.race = cc->race;
pp.class_ = cc->class_;
pp.gender = cc->gender;
pp.deity = cc->deity;
pp.STR = cc->STR;
pp.STA = cc->STA;
pp.AGI = cc->AGI;
pp.DEX = cc->DEX;
pp.WIS = cc->WIS;
pp.INT = cc->INT;
pp.CHA = cc->CHA;
pp.face = cc->face;
pp.eyecolor1 = cc->eyecolor1;
pp.eyecolor2 = cc->eyecolor2;
pp.hairstyle = cc->hairstyle;
pp.haircolor = cc->haircolor;
pp.beard = cc->beard;
pp.beardcolor = cc->beardcolor;
pp.drakkin_heritage = cc->drakkin_heritage;
pp.drakkin_tattoo = cc->drakkin_tattoo;
pp.drakkin_details = cc->drakkin_details;
pp.birthday = bday;
pp.lastlogin = bday;
pp.level = 1;
pp.points = 5;
pp.cur_hp = 1000;
pp.hunger_level = 6000;
pp.thirst_level = 6000;
GetResistsForCharacterCreate(cc,
m_ClientVersionBit & EQ::versions::maskSoFAndLater,
pp.cold_resist,
pp.fire_resist,
pp.magic_resist,
pp.disease_resist,
pp.poison_resist,
pp.corruption_resist);
/* Set default skills for everybody */
pp.skills[EQ::skills::SkillSwimming] = RuleI(Skills, SwimmingStartValue);
pp.skills[EQ::skills::SkillSenseHeading] = RuleI(Skills, SenseHeadingStartValue);
/* Set Racial and Class specific language and skills */
SetRacialLanguages(&pp);
SetRaceStartingSkills(&pp);
SetClassStartingSkills(&pp);
SetClassLanguages(&pp);
memset(pp.spell_book, std::numeric_limits<uint8>::max(), (sizeof(uint32) * EQ::spells::SPELLBOOK_SIZE));
memset(pp.mem_spells, std::numeric_limits<uint8>::max(), (sizeof(uint32) * EQ::spells::SPELL_GEM_COUNT));
for (auto& b : pp.buffs) {
b.spellid = std::numeric_limits<uint16>::max();
}
/* If server is PVP by default, make all character set to it. */
pp.pvp = database.GetServerType() == 1 ? 1 : 0;
/* If it is an SoF Client and the SoF Start Zone rule is set, send new chars there */
if (m_ClientVersionBit & EQ::versions::maskSoFAndLater) {
LogInfo("Found [SoFStartZoneID] rule setting [{}]", RuleI(World, SoFStartZoneID));
if (RuleI(World, SoFStartZoneID) > 0) {
pp.zone_id = RuleI(World, SoFStartZoneID);
cc->start_zone = pp.zone_id;
}
} else {
LogInfo("Found [TitaniumStartZoneID] rule setting [{}]", RuleI(World, TitaniumStartZoneID));
if (RuleI(World, TitaniumStartZoneID) > 0) { /* if there's a startzone variable put them in there */
pp.zone_id = RuleI(World, TitaniumStartZoneID);
cc->start_zone = pp.zone_id;
}
}
/* use normal starting zone logic to either get defaults, or if startzone was set, load that from the db table.*/
const bool is_valid_start_zone = content_db.GetStartZone(&pp, cc, m_ClientVersionBit & EQ::versions::maskTitaniumAndEarlier);
if (!is_valid_start_zone){
return false;
}
if (!pp.zone_id) {
pp.zone_id = Zones::QEYNOS;
pp.x = pp.y = pp.z = -1;
}
for (uint8 slot_id = 1; slot_id < 5; slot_id++) {
pp.binds[slot_id].zone_id = pp.zone_id;
pp.binds[slot_id].x = pp.x;
pp.binds[slot_id].y = pp.y;
pp.binds[slot_id].z = pp.z;
pp.binds[slot_id].heading = pp.heading;
}
/* Overrides if we have the tutorial flag set! */
if (cc->tutorial && RuleB(World, EnableTutorialButton)) {
pp.zone_id = RuleI(World, TutorialZoneID);
auto z = GetZone(pp.zone_id);
if (z) {
pp.x = z->safe_x;
pp.y = z->safe_y;
pp.z = z->safe_z;
}
}
/* Will either be the same as home or tutorial if enabled. */
if (RuleB(World, StartZoneSameAsBindOnCreation)) {
pp.binds[0].zone_id = pp.zone_id;
pp.binds[0].x = pp.x;
pp.binds[0].y = pp.y;
pp.binds[0].z = pp.z;
pp.binds[0].heading = pp.heading;
}
if (GetZone(pp.zone_id)) {
LogInfo(
"Current location zone_short_name [{}] zone_id [{}] x [{:.2f}] y [{:.2f}] z [{:.2f}] heading [{:.2f}]",
ZoneName(pp.zone_id),
pp.zone_id,
pp.x,
pp.y,
pp.z,
pp.heading
);
}
if (GetZone(pp.binds[0].zone_id)) {
LogInfo(
"Bind location zone_short_name [{}] zone_id [{}] x [{:.2f}] y [{:.2f}] z [{:.2f}] heading [{:.2f}]",
ZoneName(pp.binds[0].zone_id),
pp.binds[0].zone_id,
pp.binds[0].x,
pp.binds[0].y,
pp.binds[0].z,
pp.binds[4].heading
);
}
if (GetZone(pp.binds[4].zone_id)) {
LogInfo(
"Home location zone_short_name [{}] zone_id [{}] x [{:.2f}] y [{:.2f}] z [{:.2f}] heading [{:.2f}]",
ZoneName(pp.binds[4].zone_id),
pp.binds[4].zone_id,
pp.binds[4].x,
pp.binds[4].y,
pp.binds[4].z,
pp.binds[4].heading
);
}
content_db.SetStartingItems(&pp, &inv, pp.race, pp.class_, pp.deity, pp.zone_id, pp.name, GetAdmin());
const bool success = StoreCharacter(GetAccountID(), &pp, &inv);
LogInfo("Character creation {} for [{}]", success ? "succeeded" : "failed", pp.name);
return success;
}
void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
{
for (uint32 i = 0; i <= EQ::skills::HIGHEST_SKILL; ++i) {
-3
View File
@@ -122,7 +122,4 @@ private:
void RecordPossibleHack(const std::string& message);
};
bool CheckCharCreateInfoSoF(CharCreate_Struct *cc);
bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc);
#endif
+18
View File
@@ -0,0 +1,18 @@
#pragma once
struct CharCreatePointAllocation
{
unsigned int Index;
unsigned int BaseStats[7];
unsigned int DefaultPointAllocation[7];
unsigned int BaseResists[7];
};
struct CharCreateCombination {
unsigned int ExpansionRequired;
unsigned int Race;
unsigned int Class;
unsigned int Deity;
unsigned int AllocationIndex;
unsigned int Zone;
};
-7
View File
@@ -294,13 +294,6 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
database.ClearBuyerDetails();
LogInfo("Clearing buyer table details");
if (RuleB(Bots, Enabled)) {
LogInfo("Clearing [bot_pet_buffs] table of stale entries");
database.QueryDatabase(
"DELETE FROM bot_pet_buffs WHERE NOT EXISTS (SELECT * FROM bot_pets WHERE bot_pets.pets_index = bot_pet_buffs.pets_index)"
);
}
if (!content_db.LoadItems(hotfix_name)) {
LogError("Error: Could not load item data. But ignoring");
}
+11 -4
View File
@@ -25,14 +25,15 @@
#include <cstdlib>
#include <vector>
#include "sof_char_create_data.h"
#include "race_combos.h"
#include "../common/repositories/character_instance_safereturns_repository.h"
#include "../common/repositories/criteria/content_filter_criteria.h"
#include "../common/zone_store.h"
WorldDatabase database;
WorldDatabase content_db;
extern std::vector<RaceClassAllocation> character_create_allocations;
extern std::vector<RaceClassCombos> character_create_race_class_combos;
extern std::vector<CharCreatePointAllocation> character_create_allocations;
extern std::vector<CharCreateCombination> character_create_race_class_combos;
/**
@@ -807,7 +808,7 @@ bool WorldDatabase::LoadCharacterCreateAllocations()
return false;
for (auto row = results.begin(); row != results.end(); ++row) {
RaceClassAllocation allocate;
CharCreatePointAllocation allocate;
allocate.Index = Strings::ToInt(row[0]);
allocate.BaseStats[0] = Strings::ToInt(row[1]);
allocate.BaseStats[3] = Strings::ToInt(row[2]);
@@ -823,6 +824,12 @@ bool WorldDatabase::LoadCharacterCreateAllocations()
allocate.DefaultPointAllocation[4] = Strings::ToInt(row[12]);
allocate.DefaultPointAllocation[5] = Strings::ToInt(row[13]);
allocate.DefaultPointAllocation[6] = Strings::ToInt(row[14]);
allocate.BaseResists[0] = Strings::ToInt(row[15]);
allocate.BaseResists[1] = Strings::ToInt(row[16]);
allocate.BaseResists[2] = Strings::ToInt(row[17]);
allocate.BaseResists[3] = Strings::ToInt(row[18]);
allocate.BaseResists[4] = Strings::ToInt(row[19]);
allocate.BaseResists[5] = Strings::ToInt(row[20]);
character_create_allocations.push_back(allocate);
}
@@ -840,7 +847,7 @@ bool WorldDatabase::LoadCharacterCreateCombos()
return false;
for (auto row = results.begin(); row != results.end(); ++row) {
RaceClassCombos combo;
CharCreateCombination combo;
combo.AllocationIndex = Strings::ToInt(row[0]);
combo.Race = Strings::ToInt(row[1]);
combo.Class = Strings::ToInt(row[2]);
+2 -2
View File
@@ -828,7 +828,7 @@ bool BotDatabase::LoadTimers(Bot* b)
BotTimer_Struct t{ };
for (const auto& e : l) {
if (e.timer_value < (Timer::GetCurrentTime() + e.recast_time)) {
if (t.timer_value < (Timer::GetCurrentTime() + t.recast_time)) {
t.timer_id = e.timer_id;
t.timer_value = e.timer_value;
t.recast_time = e.recast_time;
@@ -1451,7 +1451,7 @@ bool BotDatabase::DeletePetBuffs(const uint32 bot_id)
return true;
}
BotPetBuffsRepository::DeleteWhere(database, fmt::format("pets_index = {}", saved_pet_index));
BotPetBuffsRepository::DeleteOne(database, saved_pet_index);
return true;
}
+5 -251
View File
@@ -8677,16 +8677,14 @@ int Client::GetAccountAge() {
void Client::CheckRegionTypeChanges()
{
if (!zone->HasWaterMap()) {
if (!zone->HasWaterMap())
return;
}
auto new_region = zone->watermap->ReturnRegionType(glm::vec3(m_Position));
// still same region, do nothing
if (last_region_type == new_region) {
if (last_region_type == new_region)
return;
}
// If we got out of water clear any water aggro for water only npcs
if (last_region_type == RegionTypeWater) {
@@ -8697,16 +8695,14 @@ void Client::CheckRegionTypeChanges()
last_region_type = new_region;
// PVP is the only state we need to keep track of, so we can just return now for PVP servers
if (RuleI(World, PVPSettings) > 0) {
if (RuleI(World, PVPSettings) > 0)
return;
}
if (last_region_type == RegionTypePVP && RuleB(World, EnablePVPRegions)) {
if (last_region_type == RegionTypePVP)
temp_pvp = true;
} else if (temp_pvp) {
else if (temp_pvp)
temp_pvp = false;
}
}
void Client::ProcessAggroMeter()
{
@@ -12320,248 +12316,6 @@ void Client::PlayerTradeEventLog(Trade *t, Trade *t2)
RecordPlayerEventLogWithClient(trader2, PlayerEvent::TRADE, e);
}
void Client::NPCHandinEventLog(Trade* t, NPC* n)
{
Client* c = t->GetOwner()->CastToClient();
std::vector<PlayerEvent::HandinEntry> hi = {};
std::vector<PlayerEvent::HandinEntry> ri = {};
PlayerEvent::HandinMoney hm{};
PlayerEvent::HandinMoney rm{};
if (
c->EntityVariableExists("HANDIN_ITEMS") &&
c->EntityVariableExists("HANDIN_MONEY") &&
c->EntityVariableExists("RETURN_ITEMS") &&
c->EntityVariableExists("RETURN_MONEY")
) {
const std::string& handin_items = c->GetEntityVariable("HANDIN_ITEMS");
const std::string& return_items = c->GetEntityVariable("RETURN_ITEMS");
const std::string& handin_money = c->GetEntityVariable("HANDIN_MONEY");
const std::string& return_money = c->GetEntityVariable("RETURN_MONEY");
// Handin Items
if (!handin_items.empty()) {
if (Strings::Contains(handin_items, ",")) {
const auto handin_data = Strings::Split(handin_items, ",");
for (const auto& h : handin_data) {
const auto item_data = Strings::Split(h, "|");
if (
item_data.size() == 3 &&
Strings::IsNumber(item_data[0]) &&
Strings::IsNumber(item_data[1]) &&
Strings::IsNumber(item_data[2])
) {
const uint32 item_id = Strings::ToUnsignedInt(item_data[0]);
if (item_id != 0) {
const auto* item = database.GetItem(item_id);
if (item) {
hi.emplace_back(
PlayerEvent::HandinEntry{
.item_id = item_id,
.item_name = item->Name,
.charges = static_cast<uint16>(Strings::ToUnsignedInt(item_data[1])),
.attuned = Strings::ToInt(item_data[2]) ? true : false
}
);
}
}
}
}
} else if (Strings::Contains(handin_items, "|")) {
const auto item_data = Strings::Split(handin_items, "|");
if (
item_data.size() == 3 &&
Strings::IsNumber(item_data[0]) &&
Strings::IsNumber(item_data[1]) &&
Strings::IsNumber(item_data[2])
) {
const uint32 item_id = Strings::ToUnsignedInt(item_data[0]);
const auto* item = database.GetItem(item_id);
if (item) {
hi.emplace_back(
PlayerEvent::HandinEntry{
.item_id = item_id,
.item_name = item->Name,
.charges = static_cast<uint16>(Strings::ToUnsignedInt(item_data[1])),
.attuned = Strings::ToInt(item_data[2]) ? true : false
}
);
}
}
}
}
// Handin Money
if (!handin_money.empty()) {
const auto hms = Strings::Split(handin_money, "|");
hm.copper = Strings::ToUnsignedInt(hms[0]);
hm.silver = Strings::ToUnsignedInt(hms[1]);
hm.gold = Strings::ToUnsignedInt(hms[2]);
hm.platinum = Strings::ToUnsignedInt(hms[3]);
}
// Return Items
if (!return_items.empty()) {
if (Strings::Contains(return_items, ",")) {
const auto return_data = Strings::Split(return_items, ",");
for (const auto& r : return_data) {
const auto item_data = Strings::Split(r, "|");
if (
item_data.size() == 3 &&
Strings::IsNumber(item_data[0]) &&
Strings::IsNumber(item_data[1]) &&
Strings::IsNumber(item_data[2])
) {
const uint32 item_id = Strings::ToUnsignedInt(item_data[0]);
const auto* item = database.GetItem(item_id);
if (item) {
ri.emplace_back(
PlayerEvent::HandinEntry{
.item_id = item_id,
.item_name = item->Name,
.charges = static_cast<uint16>(Strings::ToUnsignedInt(item_data[1])),
.attuned = Strings::ToInt(item_data[2]) ? true : false
}
);
}
}
}
} else if (Strings::Contains(return_items, "|")) {
const auto item_data = Strings::Split(return_items, "|");
if (
item_data.size() == 3 &&
Strings::IsNumber(item_data[0]) &&
Strings::IsNumber(item_data[1]) &&
Strings::IsNumber(item_data[2])
) {
const uint32 item_id = Strings::ToUnsignedInt(item_data[0]);
const auto* item = database.GetItem(item_id);
if (item) {
ri.emplace_back(
PlayerEvent::HandinEntry{
.item_id = item_id,
.item_name = item->Name,
.charges = static_cast<uint16>(Strings::ToUnsignedInt(item_data[1])),
.attuned = Strings::ToInt(item_data[2]) ? true : false
}
);
}
}
}
}
// Return Money
if (!return_money.empty()) {
const auto rms = Strings::Split(return_money, "|");
rm.copper = static_cast<uint32>(Strings::ToUnsignedInt(rms[0]));
rm.silver = static_cast<uint32>(Strings::ToUnsignedInt(rms[1]));
rm.gold = static_cast<uint32>(Strings::ToUnsignedInt(rms[2]));
rm.platinum = static_cast<uint32>(Strings::ToUnsignedInt(rms[3]));
}
c->DeleteEntityVariable("HANDIN_ITEMS");
c->DeleteEntityVariable("HANDIN_MONEY");
c->DeleteEntityVariable("RETURN_ITEMS");
c->DeleteEntityVariable("RETURN_MONEY");
const bool handed_in_money = hm.platinum > 0 || hm.gold > 0 || hm.silver > 0 || hm.copper > 0;
const bool event_has_data_to_record = (
!hi.empty() || handed_in_money
);
if (player_event_logs.IsEventEnabled(PlayerEvent::NPC_HANDIN) && event_has_data_to_record) {
auto e = PlayerEvent::HandinEvent{
.npc_id = n->GetNPCTypeID(),
.npc_name = n->GetCleanName(),
.handin_items = hi,
.handin_money = hm,
.return_items = ri,
.return_money = rm,
.is_quest_handin = true
};
RecordPlayerEventLogWithClient(c, PlayerEvent::NPC_HANDIN, e);
}
return;
}
uint8 item_count = 0;
hm.platinum = t->pp;
hm.gold = t->gp;
hm.silver = t->sp;
hm.copper = t->cp;
for (uint16 i = EQ::invslot::TRADE_BEGIN; i <= EQ::invslot::TRADE_NPC_END; i++) {
if (c->GetInv().GetItem(i)) {
item_count++;
}
}
hi.reserve(item_count);
if (item_count > 0) {
for (uint16 i = EQ::invslot::TRADE_BEGIN; i <= EQ::invslot::TRADE_NPC_END; i++) {
const EQ::ItemInstance* inst = c->GetInv().GetItem(i);
if (inst) {
hi.emplace_back(
PlayerEvent::HandinEntry{
.item_id = inst->GetItem()->ID,
.item_name = inst->GetItem()->Name,
.charges = static_cast<uint16>(inst->GetCharges()),
.attuned = inst->IsAttuned()
}
);
if (inst->IsClassBag()) {
for (uint8 j = EQ::invbag::SLOT_BEGIN; j <= EQ::invbag::SLOT_END; j++) {
inst = c->GetInv().GetItem(i, j);
if (inst) {
hi.emplace_back(
PlayerEvent::HandinEntry{
.item_id = inst->GetItem()->ID,
.item_name = inst->GetItem()->Name,
.charges = static_cast<uint16>(inst->GetCharges()),
.attuned = inst->IsAttuned()
}
);
}
}
}
}
}
}
const bool handed_in_money = hm.platinum > 0 || hm.gold > 0 || hm.silver > 0 || hm.copper > 0;
ri = hi;
rm = hm;
const bool event_has_data_to_record = !hi.empty() || handed_in_money;
if (player_event_logs.IsEventEnabled(PlayerEvent::NPC_HANDIN) && event_has_data_to_record) {
auto e = PlayerEvent::HandinEvent{
.npc_id = n->GetNPCTypeID(),
.npc_name = n->GetCleanName(),
.handin_items = hi,
.handin_money = hm,
.return_items = ri,
.return_money = rm,
.is_quest_handin = false
};
RecordPlayerEventLogWithClient(c, PlayerEvent::NPC_HANDIN, e);
}
}
void Client::ShowSpells(Client* c, ShowSpellType show_spell_type)
{
std::string spell_string;
+1 -2
View File
@@ -597,7 +597,7 @@ public:
inline uint8 GetBaseINT() const { return m_pp.INT; }
inline uint8 GetBaseAGI() const { return m_pp.AGI; }
inline uint8 GetBaseWIS() const { return m_pp.WIS; }
inline uint8 GetBaseCorrup() const { return 15; } // Same for all
inline uint8 GetBaseCorrup() const { return m_pp.corruption_resist; }
inline uint8 GetBasePhR() const { return 0; } // Guessing at 0 as base
inline virtual int32 GetHeroicSTR() const { return itembonuses.HeroicSTR; }
@@ -2227,7 +2227,6 @@ private:
bool CanTradeFVNoDropItem();
void SendMobPositions();
void PlayerTradeEventLog(Trade *t, Trade *t2);
void NPCHandinEventLog(Trade* t, NPC* n);
// full and partial mail key cache
std::string m_mail_key_full;
+5 -295
View File
@@ -1009,65 +1009,7 @@ int Client::CalcHaste()
//in Mob::ResistSpell
int32 Client::CalcMR()
{
//racial bases
switch (GetBaseRace()) {
case HUMAN:
MR = 25;
break;
case BARBARIAN:
MR = 25;
break;
case ERUDITE:
MR = 30;
break;
case WOOD_ELF:
MR = 25;
break;
case HIGH_ELF:
MR = 25;
break;
case DARK_ELF:
MR = 25;
break;
case HALF_ELF:
MR = 25;
break;
case DWARF:
MR = 30;
break;
case TROLL:
MR = 25;
break;
case OGRE:
MR = 25;
break;
case HALFLING:
MR = 25;
break;
case GNOME:
MR = 25;
break;
case IKSAR:
MR = 25;
break;
case VAHSHIR:
MR = 25;
break;
case FROGLOK:
MR = 30;
break;
case DRAKKIN:
{
MR = 25;
if (GetDrakkinHeritage() == 2)
MR += 10;
else if (GetDrakkinHeritage() == 5)
MR += 2;
break;
}
default:
MR = 20;
}
MR = m_pp.magic_resist;
MR += itembonuses.MR + spellbonuses.MR + aabonuses.MR;
if (GetClass() == Class::Warrior || GetClass() == Class::Berserker) {
MR += GetLevel() / 2;
@@ -1083,65 +1025,7 @@ int32 Client::CalcMR()
int32 Client::CalcFR()
{
//racial bases
switch (GetBaseRace()) {
case HUMAN:
FR = 25;
break;
case BARBARIAN:
FR = 25;
break;
case ERUDITE:
FR = 25;
break;
case WOOD_ELF:
FR = 25;
break;
case HIGH_ELF:
FR = 25;
break;
case DARK_ELF:
FR = 25;
break;
case HALF_ELF:
FR = 25;
break;
case DWARF:
FR = 25;
break;
case TROLL:
FR = 5;
break;
case OGRE:
FR = 25;
break;
case HALFLING:
FR = 25;
break;
case GNOME:
FR = 25;
break;
case IKSAR:
FR = 30;
break;
case VAHSHIR:
FR = 25;
break;
case FROGLOK:
FR = 25;
break;
case DRAKKIN:
{
FR = 25;
if (GetDrakkinHeritage() == 0)
FR += 10;
else if (GetDrakkinHeritage() == 5)
FR += 2;
break;
}
default:
FR = 20;
}
FR = m_pp.fire_resist;
int c = GetClass();
if (c == Class::Ranger) {
FR += 4;
@@ -1169,65 +1053,7 @@ int32 Client::CalcFR()
int32 Client::CalcDR()
{
//racial bases
switch (GetBaseRace()) {
case HUMAN:
DR = 15;
break;
case BARBARIAN:
DR = 15;
break;
case ERUDITE:
DR = 10;
break;
case WOOD_ELF:
DR = 15;
break;
case HIGH_ELF:
DR = 15;
break;
case DARK_ELF:
DR = 15;
break;
case HALF_ELF:
DR = 15;
break;
case DWARF:
DR = 15;
break;
case TROLL:
DR = 15;
break;
case OGRE:
DR = 15;
break;
case HALFLING:
DR = 20;
break;
case GNOME:
DR = 15;
break;
case IKSAR:
DR = 15;
break;
case VAHSHIR:
DR = 15;
break;
case FROGLOK:
DR = 15;
break;
case DRAKKIN:
{
DR = 15;
if (GetDrakkinHeritage() == 1)
DR += 10;
else if (GetDrakkinHeritage() == 5)
DR += 2;
break;
}
default:
DR = 15;
}
DR = m_pp.disease_resist;
int c = GetClass();
// the monk one is part of base resist
if (c == Class::Monk) {
@@ -1261,65 +1087,7 @@ int32 Client::CalcDR()
int32 Client::CalcPR()
{
//racial bases
switch (GetBaseRace()) {
case HUMAN:
PR = 15;
break;
case BARBARIAN:
PR = 15;
break;
case ERUDITE:
PR = 15;
break;
case WOOD_ELF:
PR = 15;
break;
case HIGH_ELF:
PR = 15;
break;
case DARK_ELF:
PR = 15;
break;
case HALF_ELF:
PR = 15;
break;
case DWARF:
PR = 20;
break;
case TROLL:
PR = 15;
break;
case OGRE:
PR = 15;
break;
case HALFLING:
PR = 20;
break;
case GNOME:
PR = 15;
break;
case IKSAR:
PR = 15;
break;
case VAHSHIR:
PR = 15;
break;
case FROGLOK:
PR = 30;
break;
case DRAKKIN:
{
PR = 15;
if (GetDrakkinHeritage() == 3)
PR += 10;
else if (GetDrakkinHeritage() == 5)
PR += 2;
break;
}
default:
PR = 15;
}
PR = m_pp.poison_resist;
int c = GetClass();
// this monk bonus is part of the base
if (c == Class::Monk) {
@@ -1353,65 +1121,7 @@ int32 Client::CalcPR()
int32 Client::CalcCR()
{
//racial bases
switch (GetBaseRace()) {
case HUMAN:
CR = 25;
break;
case BARBARIAN:
CR = 35;
break;
case ERUDITE:
CR = 25;
break;
case WOOD_ELF:
CR = 25;
break;
case HIGH_ELF:
CR = 25;
break;
case DARK_ELF:
CR = 25;
break;
case HALF_ELF:
CR = 25;
break;
case DWARF:
CR = 25;
break;
case TROLL:
CR = 25;
break;
case OGRE:
CR = 25;
break;
case HALFLING:
CR = 25;
break;
case GNOME:
CR = 25;
break;
case IKSAR:
CR = 15;
break;
case VAHSHIR:
CR = 25;
break;
case FROGLOK:
CR = 25;
break;
case DRAKKIN:
{
CR = 25;
if (GetDrakkinHeritage() == 4)
CR += 10;
else if (GetDrakkinHeritage() == 5)
CR += 2;
break;
}
default:
CR = 25;
}
CR = m_pp.cold_resist;
int c = GetClass();
if (c == Class::Ranger || c == Class::Beastlord) {
CR += 4;
+1 -1
View File
@@ -96,7 +96,7 @@ int command_init(void)
command_add("augmentitem", "Force augments an item. Must have the augment item window open.", AccountStatus::GMImpossible, command_augmentitem) ||
command_add("ban", "[Character Name] [Reason] - Ban by character name", AccountStatus::GMLeadAdmin, command_ban) ||
command_add("bugs", "[Close|Delete|Review|Search|View] - Handles player bug reports", AccountStatus::QuestTroupe, command_bugs) ||
(RuleB(Bots, Enabled) && command_add("bot", "Type \"#bot help\" or \"^help\" to the see the list of available commands for bots.", AccountStatus::Player, command_bot)) ||
command_add("bot", "Type \"#bot help\" or \"^help\" to the see the list of available commands for bots.", AccountStatus::Player, command_bot) ||
command_add("camerashake", "[Duration (Milliseconds)] [Intensity (1-10)] - Shakes the camera on everyone's screen globally.", AccountStatus::QuestTroupe, command_camerashake) ||
command_add("castspell", "[Spell ID] [Instant (0 = False, 1 = True, Default is 1 if Unused)] - Cast a spell", AccountStatus::Guide, command_castspell) ||
command_add("chat", "[Channel ID] [Message] - Send a channel message to all zones", AccountStatus::GMMgmt, command_chat) ||
+5 -13
View File
@@ -31,14 +31,12 @@ Map::~Map() {
}
float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const {
if (!imp) {
if (!imp)
return BEST_Z_INVALID;
}
glm::vec3 tmp;
if (!result) {
if(!result)
result = &tmp;
}
start.z += RuleI(Map, FindBestZHeightAdjust);
glm::vec3 from(start.x, start.y, start.z);
@@ -47,22 +45,16 @@ float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const {
bool hit = false;
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
if (hit && zone->newzone_data.underworld != 0.0f && result->z < zone->newzone_data.underworld) {
hit = false;
}
if(hit) {
return result->z;
}
// Find nearest Z above us
to.z = -BEST_Z_INVALID;
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
if (zone->newzone_data.max_z != 0.0f && result->z > zone->newzone_data.max_z) {
hit = false;
}
if (hit) {
if (hit)
{
return result->z;
}
+172
View File
@@ -4611,9 +4611,181 @@ int8 QuestManager::DoesAugmentFit(EQ::ItemInstance* inst, uint32 augment_id, uin
}
void QuestManager::SendPlayerHandinEvent() {
QuestManagerCurrentQuestVars();
if (!owner || !owner->IsNPC() || !initiator) {
return;
}
if (
!initiator->EntityVariableExists("HANDIN_ITEMS") &&
!initiator->EntityVariableExists("HANDIN_MONEY") &&
!initiator->EntityVariableExists("RETURN_ITEMS") &&
!initiator->EntityVariableExists("RETURN_MONEY")
) {
return;
}
auto handin_items = initiator->GetEntityVariable("HANDIN_ITEMS");
auto return_items = initiator->GetEntityVariable("RETURN_ITEMS");
auto handin_money = initiator->GetEntityVariable("HANDIN_MONEY");
auto return_money = initiator->GetEntityVariable("RETURN_MONEY");
std::vector<PlayerEvent::HandinEntry> hi = {};
std::vector<PlayerEvent::HandinEntry> ri = {};
PlayerEvent::HandinMoney hm{};
PlayerEvent::HandinMoney rm{};
// Handin Items
if (!handin_items.empty()) {
if (Strings::Contains(handin_items, ",")) {
const auto handin_data = Strings::Split(handin_items, ",");
for (const auto &h: handin_data) {
const auto item_data = Strings::Split(h, "|");
if (
item_data.size() == 3 &&
Strings::IsNumber(item_data[0]) &&
Strings::IsNumber(item_data[1]) &&
Strings::IsNumber(item_data[2])
) {
const auto item_id = static_cast<uint32>(Strings::ToUnsignedInt(item_data[0]));
if (item_id != 0) {
const auto *item = database.GetItem(item_id);
if (item) {
hi.emplace_back(
PlayerEvent::HandinEntry{
.item_id = item_id,
.item_name = item->Name,
.charges = static_cast<uint16>(Strings::ToUnsignedInt(item_data[1])),
.attuned = Strings::ToInt(item_data[2]) ? true : false
}
);
}
}
}
}
}
else if (Strings::Contains(handin_items, "|")) {
const auto item_data = Strings::Split(handin_items, "|");
if (
item_data.size() == 3 &&
Strings::IsNumber(item_data[0]) &&
Strings::IsNumber(item_data[1]) &&
Strings::IsNumber(item_data[2])
) {
const auto item_id = static_cast<uint32>(Strings::ToUnsignedInt(item_data[0]));
const auto *item = database.GetItem(item_id);
if (item) {
hi.emplace_back(
PlayerEvent::HandinEntry{
.item_id = item_id,
.item_name = item->Name,
.charges = static_cast<uint16>(Strings::ToUnsignedInt(item_data[1])),
.attuned = Strings::ToInt(item_data[2]) ? true : false
}
);
}
}
}
}
// Handin Money
if (!handin_money.empty()) {
const auto hms = Strings::Split(handin_money, "|");
hm.copper = static_cast<uint32>(Strings::ToUnsignedInt(hms[0]));
hm.silver = static_cast<uint32>(Strings::ToUnsignedInt(hms[1]));
hm.gold = static_cast<uint32>(Strings::ToUnsignedInt(hms[2]));
hm.platinum = static_cast<uint32>(Strings::ToUnsignedInt(hms[3]));
}
// Return Items
if (!return_items.empty()) {
if (Strings::Contains(return_items, ",")) {
const auto return_data = Strings::Split(return_items, ",");
for (const auto &r: return_data) {
const auto item_data = Strings::Split(r, "|");
if (
item_data.size() == 3 &&
Strings::IsNumber(item_data[0]) &&
Strings::IsNumber(item_data[1]) &&
Strings::IsNumber(item_data[2])
) {
const auto item_id = static_cast<uint32>(Strings::ToUnsignedInt(item_data[0]));
const auto *item = database.GetItem(item_id);
if (item) {
ri.emplace_back(
PlayerEvent::HandinEntry{
.item_id = item_id,
.item_name = item->Name,
.charges = static_cast<uint16>(Strings::ToUnsignedInt(item_data[1])),
.attuned = Strings::ToInt(item_data[2]) ? true : false
}
);
}
}
}
}
else if (Strings::Contains(return_items, "|")) {
const auto item_data = Strings::Split(return_items, "|");
if (
item_data.size() == 3 &&
Strings::IsNumber(item_data[0]) &&
Strings::IsNumber(item_data[1]) &&
Strings::IsNumber(item_data[2])
) {
const auto item_id = static_cast<uint32>(Strings::ToUnsignedInt(item_data[0]));
const auto *item = database.GetItem(item_id);
if (item) {
ri.emplace_back(
PlayerEvent::HandinEntry{
.item_id = item_id,
.item_name = item->Name,
.charges = static_cast<uint16>(Strings::ToUnsignedInt(item_data[1])),
.attuned = Strings::ToInt(item_data[2]) ? true : false
}
);
}
}
}
}
// Return Money
if (!return_money.empty()) {
const auto rms = Strings::Split(return_money, "|");
rm.copper = static_cast<uint32>(Strings::ToUnsignedInt(rms[0]));
rm.silver = static_cast<uint32>(Strings::ToUnsignedInt(rms[1]));
rm.gold = static_cast<uint32>(Strings::ToUnsignedInt(rms[2]));
rm.platinum = static_cast<uint32>(Strings::ToUnsignedInt(rms[3]));
}
initiator->DeleteEntityVariable("HANDIN_ITEMS");
initiator->DeleteEntityVariable("HANDIN_MONEY");
initiator->DeleteEntityVariable("RETURN_ITEMS");
initiator->DeleteEntityVariable("RETURN_MONEY");
bool handed_in_money = hm.platinum > 0 || hm.gold > 0 || hm.silver > 0 || hm.copper > 0;
bool event_has_data_to_record = (
!hi.empty() || handed_in_money
);
if (player_event_logs.IsEventEnabled(PlayerEvent::NPC_HANDIN) && event_has_data_to_record) {
auto e = PlayerEvent::HandinEvent{
.npc_id = owner->CastToNPC()->GetNPCTypeID(),
.npc_name = owner->GetCleanName(),
.handin_items = hi,
.handin_money = hm,
.return_items = ri,
.return_money = rm
};
RecordPlayerEventLogWithClient(initiator, PlayerEvent::NPC_HANDIN, e);
}
}
std::string QuestManager::GetAutoLoginCharacterNameByAccountID(uint32 account_id)
{
return AccountRepository::GetAutoLoginCharacterNameByAccountID(database, account_id);
+10 -12
View File
@@ -664,8 +664,6 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st
}
}
else if(tradingWith && tradingWith->IsNPC()) {
NPCHandinEventLog(trade, tradingWith->CastToNPC());
QSPlayerLogHandin_Struct* qs_audit = nullptr;
bool qs_log = false;
@@ -834,13 +832,13 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st
);
}
auto lde = LootdropEntriesRepository::NewNpcEntity();
lde.equip_item = 1;
lde.item_charges = static_cast<int8>(baginst->GetCharges());
auto loot_drop_entry = LootdropEntriesRepository::NewNpcEntity();
loot_drop_entry.equip_item = 1;
loot_drop_entry.item_charges = static_cast<int8>(baginst->GetCharges());
tradingWith->CastToNPC()->AddLootDrop(
bagitem,
lde,
loot_drop_entry,
true
);
// Return quest items being traded to non-quest NPC when the rule is true
@@ -859,18 +857,18 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st
}
}
}
} else {
auto lde = LootdropEntriesRepository::NewNpcEntity();
lde.equip_item = 1;
lde.item_charges = static_cast<int8>(inst->GetCharges());
}
auto new_loot_drop_entry = LootdropEntriesRepository::NewNpcEntity();
new_loot_drop_entry.equip_item = 1;
new_loot_drop_entry.item_charges = static_cast<int8>(inst->GetCharges());
tradingWith->CastToNPC()->AddLootDrop(
item,
lde,
new_loot_drop_entry,
true
);
}
}
// Return quest items being traded to non-quest NPC when the rule is true
else if (restrict_quest_items_to_quest_npc && (!is_quest_npc && item->IsQuestItem())) {
tradingWith->SayString(TRADE_BACK, GetCleanName());
+12 -3
View File
@@ -561,6 +561,12 @@ bool ZoneDatabase::LoadCharacterData(uint32 character_id, PlayerProfile_Struct*
m_epp->expended_aa = e.e_expended_aa_spent;
m_epp->last_invsnapshot_time = e.e_last_invsnapshot;
m_epp->next_invsnapshot_time = m_epp->last_invsnapshot_time + (RuleI(Character, InvSnapshotMinIntervalM) * 60);
pp->cold_resist = e.cold_resist;
pp->fire_resist = e.fire_resist;
pp->magic_resist = e.magic_resist;
pp->disease_resist = e.disease_resist;
pp->poison_resist = e.poison_resist;
pp->corruption_resist = e.corruption_resist;
return true;
}
@@ -1158,6 +1164,12 @@ bool ZoneDatabase::SaveCharacterData(
e.e_expended_aa_spent = m_epp->expended_aa;
e.e_last_invsnapshot = m_epp->last_invsnapshot_time;
e.mailkey = c->GetMailKeyFull();
e.cold_resist = pp->cold_resist;
e.fire_resist = pp->fire_resist;
e.magic_resist = pp->magic_resist;
e.disease_resist = pp->disease_resist;
e.poison_resist = pp->poison_resist;
e.corruption_resist = pp->corruption_resist;
const int replaced = CharacterDataRepository::ReplaceOne(database, e);
@@ -3472,9 +3484,6 @@ bool ZoneDatabase::LoadFactionData()
}
auto& fmr_row = faction_max_results.begin();
if (fmr_row[0] == nullptr) {
return false;
}
max_faction = Strings::ToUnsignedInt(fmr_row[0]);
faction_array = new Faction *[max_faction + 1];
+1 -1
View File
@@ -737,7 +737,7 @@ void Client::ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y,
ZonePC(zoneID, instance_id, x, y, z, heading, ignorerestrictions, zm);
break;
default:
LogError("Received a request to perform an unsupported client zone operation");
LogError("Client::ProcessMovePC received a reguest to perform an unsupported client zone operation");
break;
}
}