mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Feature] Evolving items Additions (#4725)
* Implement multi-value for evolving sub_types - Added ability for evolving sub_types to contain multiple values - Implemented EvolvingItems::Types::NUMBER_OF_KILLS with level for sub_type * Repair a timer issue preventing proper evolution of items * Simplify * Remove extra level of nesting * Update client_evolving_items.cpp --------- Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
parent
511d8a8bb3
commit
3611b49f68
@ -6912,6 +6912,18 @@ CREATE TABLE `zone_state_spawns` (
|
||||
)",
|
||||
.content_schema_update = false
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9308,
|
||||
.description = "2025_add_multivalue_support_to_evolving_subtype.sql",
|
||||
.check = "SHOW COLUMNS FROM `items_evolving_details` LIKE 'sub_type'",
|
||||
.condition = "missing",
|
||||
.match = "varchar(200)",
|
||||
.sql = R"(
|
||||
ALTER TABLE `items_evolving_details`
|
||||
CHANGE COLUMN `sub_type` `sub_type` VARCHAR(200) NULL DEFAULT '0' AFTER `type`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
// -- template; copy/paste this when you need to create a new entry
|
||||
// ManifestEntry{
|
||||
// .version = 9228,
|
||||
|
||||
@ -19,13 +19,13 @@
|
||||
class BaseItemsEvolvingDetailsRepository {
|
||||
public:
|
||||
struct ItemsEvolvingDetails {
|
||||
uint32_t id;
|
||||
uint32_t item_evo_id;
|
||||
uint32_t item_evolve_level;
|
||||
uint32_t item_id;
|
||||
uint32_t type;
|
||||
uint32_t sub_type;
|
||||
int64_t required_amount;
|
||||
uint32_t id;
|
||||
uint32_t item_evo_id;
|
||||
uint32_t item_evolve_level;
|
||||
uint32_t item_id;
|
||||
uint32_t type;
|
||||
std::string sub_type;
|
||||
int64_t required_amount;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@ -101,7 +101,7 @@ public:
|
||||
e.item_evolve_level = 0;
|
||||
e.item_id = 0;
|
||||
e.type = 0;
|
||||
e.sub_type = 0;
|
||||
e.sub_type = "0";
|
||||
e.required_amount = 0;
|
||||
|
||||
return e;
|
||||
@ -144,7 +144,7 @@ public:
|
||||
e.item_evolve_level = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.sub_type = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.sub_type = row[5] ? row[5] : "0";
|
||||
e.required_amount = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
||||
|
||||
return e;
|
||||
@ -183,7 +183,7 @@ public:
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.item_evolve_level));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.item_id));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.type));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.sub_type));
|
||||
v.push_back(columns[5] + " = '" + Strings::Escape(e.sub_type) + "'");
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.required_amount));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
@ -211,7 +211,7 @@ public:
|
||||
v.push_back(std::to_string(e.item_evolve_level));
|
||||
v.push_back(std::to_string(e.item_id));
|
||||
v.push_back(std::to_string(e.type));
|
||||
v.push_back(std::to_string(e.sub_type));
|
||||
v.push_back("'" + Strings::Escape(e.sub_type) + "'");
|
||||
v.push_back(std::to_string(e.required_amount));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
@ -247,7 +247,7 @@ public:
|
||||
v.push_back(std::to_string(e.item_evolve_level));
|
||||
v.push_back(std::to_string(e.item_id));
|
||||
v.push_back(std::to_string(e.type));
|
||||
v.push_back(std::to_string(e.sub_type));
|
||||
v.push_back("'" + Strings::Escape(e.sub_type) + "'");
|
||||
v.push_back(std::to_string(e.required_amount));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
@ -287,7 +287,7 @@ public:
|
||||
e.item_evolve_level = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.sub_type = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.sub_type = row[5] ? row[5] : "0";
|
||||
e.required_amount = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
||||
|
||||
all_entries.push_back(e);
|
||||
@ -318,7 +318,7 @@ public:
|
||||
e.item_evolve_level = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||
e.type = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||
e.sub_type = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||
e.sub_type = row[5] ? row[5] : "0";
|
||||
e.required_amount = row[6] ? strtoll(row[6], nullptr, 10) : 0;
|
||||
|
||||
all_entries.push_back(e);
|
||||
@ -399,7 +399,7 @@ public:
|
||||
v.push_back(std::to_string(e.item_evolve_level));
|
||||
v.push_back(std::to_string(e.item_id));
|
||||
v.push_back(std::to_string(e.type));
|
||||
v.push_back(std::to_string(e.sub_type));
|
||||
v.push_back("'" + Strings::Escape(e.sub_type) + "'");
|
||||
v.push_back(std::to_string(e.required_amount));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
@ -428,7 +428,7 @@ public:
|
||||
v.push_back(std::to_string(e.item_evolve_level));
|
||||
v.push_back(std::to_string(e.item_id));
|
||||
v.push_back(std::to_string(e.type));
|
||||
v.push_back(std::to_string(e.sub_type));
|
||||
v.push_back("'" + Strings::Escape(e.sub_type) + "'");
|
||||
v.push_back(std::to_string(e.required_amount));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9307
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9308
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
|
||||
|
||||
#endif
|
||||
|
||||
@ -8,7 +8,8 @@
|
||||
#include "worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
extern QueryServ* QServ;
|
||||
extern QueryServ* QServ;
|
||||
const std::string SUB_TYPE_DELIMITER = ".";
|
||||
|
||||
void Client::DoEvolveItemToggle(const EQApplicationPacket *app)
|
||||
{
|
||||
@ -77,11 +78,12 @@ void Client::ProcessEvolvingItem(const uint64 exp, const Mob *mob)
|
||||
"CharacterID <green>[{}] found equipped item ID <yellow>[{}]", CharacterID(), inst->GetID());
|
||||
if (!inst->IsEvolving() || !inst->GetEvolveActivated()) {
|
||||
LogEvolveItemDetail(
|
||||
"CharacterID <green>[{}], item ID <yellow>[{}] not an evolving item.", CharacterID(), inst->GetID());
|
||||
"CharacterID <green>[{}], item ID <yellow>[{}] not an evolving item.", CharacterID(), inst->GetID()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inst->GetTimers().contains("evolve") && !inst->GetTimers().at("evolve").Check()) {
|
||||
if (inst->GetTimers().contains("evolve") && !inst->GetTimers().at("evolve").Check(false)) {
|
||||
LogEvolveItemDetail(
|
||||
"CharacterID <green>[{}], item ID <yellow>[{}] timer not yet expired. <red>[{}] secs remaining.",
|
||||
CharacterID(),
|
||||
@ -98,32 +100,39 @@ void Client::ProcessEvolvingItem(const uint64 exp, const Mob *mob)
|
||||
CharacterID(),
|
||||
inst->GetID(),
|
||||
type,
|
||||
sub_type);
|
||||
sub_type
|
||||
);
|
||||
|
||||
auto sub_types = Strings::Split(sub_type, SUB_TYPE_DELIMITER);
|
||||
auto has_sub_type = [&](uint32_t type) {
|
||||
return Strings::Contains(sub_types, std::to_string(type));
|
||||
};
|
||||
|
||||
switch (type) {
|
||||
case EvolvingItems::Types::AMOUNT_OF_EXP: {
|
||||
LogEvolveItemDetail("Type <green>[{}] Processing sub_type", type);
|
||||
if (sub_type == EvolvingItems::SubTypes::ALL_EXP ||
|
||||
(sub_type == EvolvingItems::SubTypes::GROUP_EXP && IsGrouped())) {
|
||||
LogEvolveItemDetail("Sub_Type <green>[{}] Processing Item", sub_type);
|
||||
inst->SetEvolveAddToCurrentAmount(exp * RuleR(EvolvingItems, PercentOfGroupExperience) / 100);
|
||||
|
||||
// Determine the evolve amount based on sub_type conditions
|
||||
int evolve_amount = 0;
|
||||
|
||||
if (has_sub_type(EvolvingItems::SubTypes::ALL_EXP) ||
|
||||
(has_sub_type(EvolvingItems::SubTypes::GROUP_EXP) && IsGrouped())) {
|
||||
evolve_amount = exp * RuleR(EvolvingItems, PercentOfGroupExperience) / 100;
|
||||
}
|
||||
else if (
|
||||
sub_type == EvolvingItems::SubTypes::ALL_EXP ||
|
||||
(sub_type == EvolvingItems::SubTypes::RAID_EXP && IsRaidGrouped())) {
|
||||
LogEvolveItemDetail("Sub_Type <green>[{}] Processing Item", sub_type);
|
||||
inst->SetEvolveAddToCurrentAmount(exp * RuleR(EvolvingItems, PercentOfRaidExperience) / 100);
|
||||
else if (has_sub_type(EvolvingItems::SubTypes::ALL_EXP) ||
|
||||
(has_sub_type(EvolvingItems::SubTypes::RAID_EXP) && IsRaidGrouped())) {
|
||||
evolve_amount = exp * RuleR(EvolvingItems, PercentOfRaidExperience) / 100;
|
||||
}
|
||||
else if (
|
||||
sub_type == EvolvingItems::SubTypes::ALL_EXP || sub_type == EvolvingItems::SubTypes::SOLO_EXP) {
|
||||
LogEvolveItemDetail("Sub_Type <green>[{}] Processing Item", sub_type);
|
||||
inst->SetEvolveAddToCurrentAmount(exp * RuleR(EvolvingItems, PercentOfSoloExperience) / 100);
|
||||
else if (has_sub_type(EvolvingItems::SubTypes::ALL_EXP) ||
|
||||
has_sub_type(EvolvingItems::SubTypes::SOLO_EXP)) {
|
||||
evolve_amount = exp * RuleR(EvolvingItems, PercentOfSoloExperience) / 100;
|
||||
}
|
||||
|
||||
inst->CalculateEvolveProgression();
|
||||
|
||||
auto e = CharacterEvolvingItemsRepository::SetCurrentAmountAndProgression(
|
||||
database, inst->GetEvolveUniqueID(), inst->GetEvolveCurrentAmount(), inst->GetEvolveProgression());
|
||||
database, inst->GetEvolveUniqueID(), inst->GetEvolveCurrentAmount(), inst->GetEvolveProgression()
|
||||
);
|
||||
if (!e.id) {
|
||||
break;
|
||||
}
|
||||
@ -146,7 +155,7 @@ void Client::ProcessEvolvingItem(const uint64 exp, const Mob *mob)
|
||||
}
|
||||
case EvolvingItems::Types::SPECIFIC_MOB_RACE: {
|
||||
LogEvolveItemDetail("Type <green>[{}] Processing sub type", type);
|
||||
if (mob && mob->GetRace() == sub_type) {
|
||||
if (mob && has_sub_type(mob->GetRace())) {
|
||||
LogEvolveItemDetail("Sub_Type <green>[{}] Processing Item", sub_type);
|
||||
inst->SetEvolveAddToCurrentAmount(1);
|
||||
inst->CalculateEvolveProgression();
|
||||
@ -155,7 +164,8 @@ void Client::ProcessEvolvingItem(const uint64 exp, const Mob *mob)
|
||||
database,
|
||||
inst->GetEvolveUniqueID(),
|
||||
inst->GetEvolveCurrentAmount(),
|
||||
inst->GetEvolveProgression());
|
||||
inst->GetEvolveProgression()
|
||||
);
|
||||
if (!e.id) {
|
||||
break;
|
||||
}
|
||||
@ -163,7 +173,8 @@ void Client::ProcessEvolvingItem(const uint64 exp, const Mob *mob)
|
||||
SendEvolvingPacket(EvolvingItems::Actions::UPDATE_ITEMS, e);
|
||||
|
||||
LogEvolveItem(
|
||||
"Processing Complete for item id <green>[{1}] Type 3 Specific Mob Race - SubType <yellow>[{0}] "
|
||||
"Processing Complete for item id <green>[{1}] Type 3 Specific Mob Race - SubType "
|
||||
"<yellow>[{0}] "
|
||||
"- Increased count by 1 for <green>[{1}]",
|
||||
sub_type,
|
||||
inst->GetID()
|
||||
@ -178,7 +189,7 @@ void Client::ProcessEvolvingItem(const uint64 exp, const Mob *mob)
|
||||
}
|
||||
case EvolvingItems::Types::SPECIFIC_ZONE_ID: {
|
||||
LogEvolveItemDetail("Type <green>[{}] Processing sub type", type);
|
||||
if (mob && mob->GetZoneID() == sub_type) {
|
||||
if (mob && has_sub_type(mob->GetZoneID())) {
|
||||
LogEvolveItemDetail("Sub_Type <green>[{}] Processing Item", sub_type);
|
||||
inst->SetEvolveAddToCurrentAmount(1);
|
||||
inst->CalculateEvolveProgression();
|
||||
@ -187,7 +198,8 @@ void Client::ProcessEvolvingItem(const uint64 exp, const Mob *mob)
|
||||
database,
|
||||
inst->GetEvolveUniqueID(),
|
||||
inst->GetEvolveCurrentAmount(),
|
||||
inst->GetEvolveProgression());
|
||||
inst->GetEvolveProgression()
|
||||
);
|
||||
if (!e.id) {
|
||||
break;
|
||||
}
|
||||
@ -195,7 +207,8 @@ void Client::ProcessEvolvingItem(const uint64 exp, const Mob *mob)
|
||||
SendEvolvingPacket(EvolvingItems::Actions::UPDATE_ITEMS, e);
|
||||
|
||||
LogEvolveItem(
|
||||
"Processing Complete for item id <green>[{1}] Type 4 Specific Zone ID - SubType <yellow>[{0}] "
|
||||
"Processing Complete for item id <green>[{1}] Type 4 Specific Zone ID - SubType "
|
||||
"<yellow>[{0}] "
|
||||
"- Increased count by 1 for <green>[{1}]",
|
||||
sub_type,
|
||||
inst->GetID()
|
||||
@ -208,6 +221,44 @@ void Client::ProcessEvolvingItem(const uint64 exp, const Mob *mob)
|
||||
|
||||
break;
|
||||
}
|
||||
case EvolvingItems::Types::NUMBER_OF_KILLS: {
|
||||
LogEvolveItemDetail("Type <green>[{}] Processing sub type", type);
|
||||
if (mob) {
|
||||
if (mob->GetLevel() >= Strings::ToUnsignedInt(sub_types.front()) ||
|
||||
Strings::ToUnsignedInt(sub_types.front()) == 0
|
||||
) {
|
||||
LogEvolveItemDetail("Sub_Type <green>[{}] Processing Item", sub_type);
|
||||
inst->SetEvolveAddToCurrentAmount(1);
|
||||
inst->CalculateEvolveProgression();
|
||||
|
||||
auto e = CharacterEvolvingItemsRepository::SetCurrentAmountAndProgression(
|
||||
database,
|
||||
inst->GetEvolveUniqueID(),
|
||||
inst->GetEvolveCurrentAmount(),
|
||||
inst->GetEvolveProgression()
|
||||
);
|
||||
if (!e.id) {
|
||||
break;
|
||||
}
|
||||
|
||||
SendEvolvingPacket(EvolvingItems::Actions::UPDATE_ITEMS, e);
|
||||
|
||||
LogEvolveItem(
|
||||
"Processing Complete for item id <green>[{1}] Type 4 Specific Zone ID - SubType "
|
||||
"<yellow>[{0}] "
|
||||
"- Increased count by 1 for <green>[{1}]",
|
||||
sub_type,
|
||||
inst->GetID()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (inst->GetEvolveProgression() >= 100) {
|
||||
queue.push_back(inst);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user