mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 09:06:46 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1575a2af40 | |||
| 4b69df646c | |||
| 044b9c1420 | |||
| 0bbb5b90e7 | |||
| 6506ad5b51 | |||
| dcaa0ecdaa | |||
| 9b143132be | |||
| 231bf8b4ec | |||
| dee58f9a91 |
@@ -1,3 +1,72 @@
|
|||||||
|
## [23.10.1] 9/16/2025
|
||||||
|
|
||||||
|
### Hotfix
|
||||||
|
* Fixed Mail Key Bug ([#5015](https://github.com/EQEmu/Server/pull/5015)) @Kinglykrab 2025-09-16
|
||||||
|
|
||||||
|
## [23.10.0] 9/15/2025
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
* Fix Linking with GCC ([#4969](https://github.com/EQEmu/Server/pull/4969)) @solar984 2025-08-03
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Add #npcedit npc_tint_id Help Message ([#4982](https://github.com/EQEmu/Server/pull/4982)) @Kinglykrab 2025-08-17
|
||||||
|
* Cleanup #show ip_lookup Message ([#5005](https://github.com/EQEmu/Server/pull/5005)) @Kinglykrab 2025-08-30
|
||||||
|
* Fix #set race 0 Message ([#5004](https://github.com/EQEmu/Server/pull/5004)) @Kinglykrab 2025-08-30
|
||||||
|
* Fix Issues with Strings::Commify and Mob::SendStatsWindow ([#4984](https://github.com/EQEmu/Server/pull/4984)) @Kinglykrab 2025-08-17
|
||||||
|
* Remove Attributions ([#4988](https://github.com/EQEmu/Server/pull/4988)) @KimLS 2025-08-16
|
||||||
|
* Remove Unused errorname Variable ([#5001](https://github.com/EQEmu/Server/pull/5001)) @Kinglykrab 2025-08-29
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* Add #find account Subcommand ([#4981](https://github.com/EQEmu/Server/pull/4981)) @Kinglykrab 2025-08-17
|
||||||
|
* Add #show keyring Subcommand ([#4973](https://github.com/EQEmu/Server/pull/4973)) @Kinglykrab 2025-08-03
|
||||||
|
* Add #task complete Saylink to #task show ([#4985](https://github.com/EQEmu/Server/pull/4985)) @Kinglykrab 2025-08-17
|
||||||
|
|
||||||
|
### Constants
|
||||||
|
|
||||||
|
* Change Race Changes to Race Namespace ([#5000](https://github.com/EQEmu/Server/pull/5000)) @Kinglykrab 2025-08-30
|
||||||
|
* Convert SE Defines to SpellEffect Namespace ([#4999](https://github.com/EQEmu/Server/pull/4999)) @Kinglykrab 2025-08-30
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
* Add `heal_amount` to `character_stats_record` ([#4986](https://github.com/EQEmu/Server/pull/4986)) @Kinglykrab 2025-08-17
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix #show recipe uint16 Cap ([#4978](https://github.com/EQEmu/Server/pull/4978)) @Kinglykrab 2025-08-11
|
||||||
|
* Fix Race 474 for Titanium ([#4979](https://github.com/EQEmu/Server/pull/4979)) @regneq 2025-08-11
|
||||||
|
* Fix Recipe Inspect Bug ([#4994](https://github.com/EQEmu/Server/pull/4994)) @Kinglykrab 2025-08-30
|
||||||
|
* Fix Several Evolving Item Bugs ([#4992](https://github.com/EQEmu/Server/pull/4992)) @neckkola 2025-09-08
|
||||||
|
* Fix Task Reloading ([#5002](https://github.com/EQEmu/Server/pull/5002)) @Kinglykrab 2025-08-29
|
||||||
|
|
||||||
|
### Loginserver
|
||||||
|
|
||||||
|
* Fix Legacy World When Using Local DB ([#4970](https://github.com/EQEmu/Server/pull/4970)) @solar984 2025-08-03
|
||||||
|
|
||||||
|
### Pets
|
||||||
|
|
||||||
|
* Add Pet Constants and Methods ([#4987](https://github.com/EQEmu/Server/pull/4987)) @Kinglykrab 2025-08-17
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add EVENT_CHARM_START and EVENT_CHARM_END ([#5013](https://github.com/EQEmu/Server/pull/5013)) @Kinglykrab 2025-09-15
|
||||||
|
* Add GetKeyRing() to Perl/Lua ([#4980](https://github.com/EQEmu/Server/pull/4980)) @Kinglykrab 2025-08-17
|
||||||
|
* Add GetNPCTintIndex() to Perl/Lua ([#4983](https://github.com/EQEmu/Server/pull/4983)) @Kinglykrab 2025-08-17
|
||||||
|
* Add GetTimers() and GetPausedTimers() to Perl/Lua ([#4965](https://github.com/EQEmu/Server/pull/4965)) @Kinglykrab 2025-08-03
|
||||||
|
* Add Identifiers to Get/Modify NPC Stat Methods ([#5012](https://github.com/EQEmu/Server/pull/5012)) @Kinglykrab 2025-09-15
|
||||||
|
|
||||||
|
### Repositories
|
||||||
|
|
||||||
|
* Convert Character Inspect Messages to Repositories ([#4997](https://github.com/EQEmu/Server/pull/4997)) @Kinglykrab 2025-08-30
|
||||||
|
* Convert Damage Shield Types to Repositories ([#4995](https://github.com/EQEmu/Server/pull/4995)) @Kinglykrab 2025-08-30
|
||||||
|
* Convert Item Loading to Repositories ([#4998](https://github.com/EQEmu/Server/pull/4998)) @Kinglykrab 2025-08-30
|
||||||
|
* Convert Mail Key to Repositories ([#5007](https://github.com/EQEmu/Server/pull/5007)) @Kinglykrab 2025-09-15
|
||||||
|
* Convert Shared Bank Platinum to Repositories ([#5006](https://github.com/EQEmu/Server/pull/5006)) @Kinglykrab 2025-09-02
|
||||||
|
* Convert Spell Loading to Repositories ([#4996](https://github.com/EQEmu/Server/pull/4996)) @Kinglykrab 2025-08-30
|
||||||
|
* Convert Total Time Played to Repositories ([#5008](https://github.com/EQEmu/Server/pull/5008)) @Kinglykrab 2025-09-15
|
||||||
|
|
||||||
## [23.9.1] 8/2/2025
|
## [23.9.1] 8/2/2025
|
||||||
|
|
||||||
### Hotfix
|
### Hotfix
|
||||||
|
|||||||
@@ -7188,9 +7188,24 @@ CHANGE COLUMN `field221` `caster_requirement_id` int(11) NULL DEFAULT 0 AFTER `n
|
|||||||
CHANGE COLUMN `field222` `spell_class` int(11) NULL DEFAULT 0 AFTER `caster_requirement_id`,
|
CHANGE COLUMN `field222` `spell_class` int(11) NULL DEFAULT 0 AFTER `caster_requirement_id`,
|
||||||
CHANGE COLUMN `field223` `spell_subclass` int(11) NULL DEFAULT 0 AFTER `spell_class`,
|
CHANGE COLUMN `field223` `spell_subclass` int(11) NULL DEFAULT 0 AFTER `spell_class`,
|
||||||
CHANGE COLUMN `field232` `no_remove` int(11) NOT NULL DEFAULT 0 AFTER `min_range`;
|
CHANGE COLUMN `field232` `no_remove` int(11) NOT NULL DEFAULT 0 AFTER `min_range`;
|
||||||
)"
|
)",
|
||||||
}
|
.content_schema_update = true
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9329,
|
||||||
|
.description = "2025_08_22_character_parcel_updates.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `character_parcels` LIKE 'evolve_amount'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `character_parcels`
|
||||||
|
ADD COLUMN `evolve_amount` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `quantity`;
|
||||||
|
|
||||||
|
ALTER TABLE `character_parcels_containers`
|
||||||
|
ADD COLUMN `evolve_amount` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `quantity`;
|
||||||
|
)",
|
||||||
|
.content_schema_update = false
|
||||||
|
},
|
||||||
// -- template; copy/paste this when you need to create a new entry
|
// -- template; copy/paste this when you need to create a new entry
|
||||||
// ManifestEntry{
|
// ManifestEntry{
|
||||||
// .version = 9228,
|
// .version = 9228,
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ void EvolvingItemsManager::DoLootChecks(const uint32 char_id, const uint16 slot_
|
|||||||
e.item_id = inst.GetID();
|
e.item_id = inst.GetID();
|
||||||
e.equipped = inst.GetEvolveEquipped();
|
e.equipped = inst.GetEvolveEquipped();
|
||||||
e.final_item_id = EvolvingItemsManager::Instance()->GetFinalItemID(inst);
|
e.final_item_id = EvolvingItemsManager::Instance()->GetFinalItemID(inst);
|
||||||
|
if (inst.GetEvolveCurrentAmount() > 0) {
|
||||||
|
e.current_amount = inst.GetEvolveCurrentAmount();
|
||||||
|
inst.CalculateEvolveProgression();
|
||||||
|
}
|
||||||
|
|
||||||
auto r = CharacterEvolvingItemsRepository::InsertOne(*m_db, e);
|
auto r = CharacterEvolvingItemsRepository::InsertOne(*m_db, e);
|
||||||
e.id = r.id;
|
e.id = r.id;
|
||||||
|
|||||||
@@ -6481,7 +6481,7 @@ namespace RoF2
|
|||||||
hdr.scaled_value = (inst->IsScaling() ? (inst->GetExp() / 100) : 0);
|
hdr.scaled_value = (inst->IsScaling() ? (inst->GetExp() / 100) : 0);
|
||||||
hdr.instance_id = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : inst->GetSerialNumber());
|
hdr.instance_id = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : inst->GetSerialNumber());
|
||||||
hdr.parcel_item_id = packet_type == ItemPacketParcel ? inst->GetID() : 0;
|
hdr.parcel_item_id = packet_type == ItemPacketParcel ? inst->GetID() : 0;
|
||||||
if (item->EvolvingItem) {
|
if (item->EvolvingItem && packet_type != ItemPacketParcel && packet_type != ItemPacketMerchant) {
|
||||||
hdr.instance_id = inst->GetEvolveUniqueID() & 0xFFFFFFFF; //lower dword
|
hdr.instance_id = inst->GetEvolveUniqueID() & 0xFFFFFFFF; //lower dword
|
||||||
hdr.parcel_item_id = inst->GetEvolveUniqueID() >> 32; //upper dword
|
hdr.parcel_item_id = inst->GetEvolveUniqueID() >> 32; //upper dword
|
||||||
}
|
}
|
||||||
@@ -6500,6 +6500,7 @@ namespace RoF2
|
|||||||
|
|
||||||
if (item->EvolvingItem > 0) {
|
if (item->EvolvingItem > 0) {
|
||||||
RoF2::structs::EvolvingItem_Struct evotop;
|
RoF2::structs::EvolvingItem_Struct evotop;
|
||||||
|
inst->CalculateEvolveProgression();
|
||||||
|
|
||||||
evotop.final_item_id = inst->GetEvolveFinalItemID();
|
evotop.final_item_id = inst->GetEvolveFinalItemID();
|
||||||
evotop.evolve_level = item->EvolvingLevel;
|
evotop.evolve_level = item->EvolvingLevel;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public:
|
|||||||
uint32_t aug_slot_5;
|
uint32_t aug_slot_5;
|
||||||
uint32_t aug_slot_6;
|
uint32_t aug_slot_6;
|
||||||
uint32_t quantity;
|
uint32_t quantity;
|
||||||
|
uint32_t evolve_amount;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@@ -51,6 +52,7 @@ public:
|
|||||||
"aug_slot_5",
|
"aug_slot_5",
|
||||||
"aug_slot_6",
|
"aug_slot_6",
|
||||||
"quantity",
|
"quantity",
|
||||||
|
"evolve_amount",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +70,7 @@ public:
|
|||||||
"aug_slot_5",
|
"aug_slot_5",
|
||||||
"aug_slot_6",
|
"aug_slot_6",
|
||||||
"quantity",
|
"quantity",
|
||||||
|
"evolve_amount",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +122,7 @@ public:
|
|||||||
e.aug_slot_5 = 0;
|
e.aug_slot_5 = 0;
|
||||||
e.aug_slot_6 = 0;
|
e.aug_slot_6 = 0;
|
||||||
e.quantity = 0;
|
e.quantity = 0;
|
||||||
|
e.evolve_amount = 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -166,6 +170,7 @@ public:
|
|||||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
|
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -209,6 +214,7 @@ public:
|
|||||||
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_5));
|
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_5));
|
||||||
v.push_back(columns[9] + " = " + std::to_string(e.aug_slot_6));
|
v.push_back(columns[9] + " = " + std::to_string(e.aug_slot_6));
|
||||||
v.push_back(columns[10] + " = " + std::to_string(e.quantity));
|
v.push_back(columns[10] + " = " + std::to_string(e.quantity));
|
||||||
|
v.push_back(columns[11] + " = " + std::to_string(e.evolve_amount));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -241,6 +247,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_5));
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -281,6 +288,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_5));
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -325,6 +333,7 @@ public:
|
|||||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
|
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -360,6 +369,7 @@ public:
|
|||||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
|
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -445,6 +455,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_5));
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -478,6 +489,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_5));
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public:
|
|||||||
uint32_t aug_slot_6;
|
uint32_t aug_slot_6;
|
||||||
uint32_t slot_id;
|
uint32_t slot_id;
|
||||||
uint32_t quantity;
|
uint32_t quantity;
|
||||||
|
uint32_t evolve_amount;
|
||||||
std::string from_name;
|
std::string from_name;
|
||||||
std::string note;
|
std::string note;
|
||||||
time_t sent_date;
|
time_t sent_date;
|
||||||
@@ -54,6 +55,7 @@ public:
|
|||||||
"aug_slot_6",
|
"aug_slot_6",
|
||||||
"slot_id",
|
"slot_id",
|
||||||
"quantity",
|
"quantity",
|
||||||
|
"evolve_amount",
|
||||||
"from_name",
|
"from_name",
|
||||||
"note",
|
"note",
|
||||||
"sent_date",
|
"sent_date",
|
||||||
@@ -74,6 +76,7 @@ public:
|
|||||||
"aug_slot_6",
|
"aug_slot_6",
|
||||||
"slot_id",
|
"slot_id",
|
||||||
"quantity",
|
"quantity",
|
||||||
|
"evolve_amount",
|
||||||
"from_name",
|
"from_name",
|
||||||
"note",
|
"note",
|
||||||
"UNIX_TIMESTAMP(sent_date)",
|
"UNIX_TIMESTAMP(sent_date)",
|
||||||
@@ -128,6 +131,7 @@ public:
|
|||||||
e.aug_slot_6 = 0;
|
e.aug_slot_6 = 0;
|
||||||
e.slot_id = 0;
|
e.slot_id = 0;
|
||||||
e.quantity = 0;
|
e.quantity = 0;
|
||||||
|
e.evolve_amount = 0;
|
||||||
e.from_name = "";
|
e.from_name = "";
|
||||||
e.note = "";
|
e.note = "";
|
||||||
e.sent_date = 0;
|
e.sent_date = 0;
|
||||||
@@ -178,9 +182,10 @@ public:
|
|||||||
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
e.from_name = row[11] ? row[11] : "";
|
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
e.note = row[12] ? row[12] : "";
|
e.from_name = row[12] ? row[12] : "";
|
||||||
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
|
e.note = row[13] ? row[13] : "";
|
||||||
|
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -224,9 +229,10 @@ public:
|
|||||||
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_6));
|
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_6));
|
||||||
v.push_back(columns[9] + " = " + std::to_string(e.slot_id));
|
v.push_back(columns[9] + " = " + std::to_string(e.slot_id));
|
||||||
v.push_back(columns[10] + " = " + std::to_string(e.quantity));
|
v.push_back(columns[10] + " = " + std::to_string(e.quantity));
|
||||||
v.push_back(columns[11] + " = '" + Strings::Escape(e.from_name) + "'");
|
v.push_back(columns[11] + " = " + std::to_string(e.evolve_amount));
|
||||||
v.push_back(columns[12] + " = '" + Strings::Escape(e.note) + "'");
|
v.push_back(columns[12] + " = '" + Strings::Escape(e.from_name) + "'");
|
||||||
v.push_back(columns[13] + " = FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
v.push_back(columns[13] + " = '" + Strings::Escape(e.note) + "'");
|
||||||
|
v.push_back(columns[14] + " = FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -259,6 +265,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.slot_id));
|
v.push_back(std::to_string(e.slot_id));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.note) + "'");
|
v.push_back("'" + Strings::Escape(e.note) + "'");
|
||||||
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
||||||
@@ -302,6 +309,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.slot_id));
|
v.push_back(std::to_string(e.slot_id));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.note) + "'");
|
v.push_back("'" + Strings::Escape(e.note) + "'");
|
||||||
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
||||||
@@ -349,9 +357,10 @@ public:
|
|||||||
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
e.from_name = row[11] ? row[11] : "";
|
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
e.note = row[12] ? row[12] : "";
|
e.from_name = row[12] ? row[12] : "";
|
||||||
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
|
e.note = row[13] ? row[13] : "";
|
||||||
|
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -387,9 +396,10 @@ public:
|
|||||||
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
e.from_name = row[11] ? row[11] : "";
|
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
e.note = row[12] ? row[12] : "";
|
e.from_name = row[12] ? row[12] : "";
|
||||||
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
|
e.note = row[13] ? row[13] : "";
|
||||||
|
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -475,6 +485,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.slot_id));
|
v.push_back(std::to_string(e.slot_id));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.note) + "'");
|
v.push_back("'" + Strings::Escape(e.note) + "'");
|
||||||
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
||||||
@@ -511,6 +522,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.slot_id));
|
v.push_back(std::to_string(e.slot_id));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
v.push_back("'" + Strings::Escape(e.from_name) + "'");
|
||||||
v.push_back("'" + Strings::Escape(e.note) + "'");
|
v.push_back("'" + Strings::Escape(e.note) + "'");
|
||||||
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
|
||||||
|
|||||||
@@ -191,6 +191,22 @@ public:
|
|||||||
|
|
||||||
return character_ids;
|
return character_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t GetTotalTimePlayed(Database& db, uint32_t account_id)
|
||||||
|
{
|
||||||
|
auto query = fmt::format(
|
||||||
|
"SELECT SUM(time_played) FROM `character_data` WHERE `account_id` = {}",
|
||||||
|
account_id
|
||||||
|
);
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
return Strings::ToUnsignedInt(row[0]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_CHARACTER_DATA_REPOSITORY_H
|
#endif //EQEMU_CHARACTER_DATA_REPOSITORY_H
|
||||||
|
|||||||
+29
-61
@@ -122,68 +122,43 @@ bool SharedDatabase::SetGMFlymode(uint32 account_id, uint8 flymode)
|
|||||||
return a.id > 0;
|
return a.id > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
|
void SharedDatabase::SetMailKey(uint32 character_id, uint32 ip_address, uint32 mail_key)
|
||||||
uint32 EntitledTime = 0;
|
|
||||||
const std::string query = StringFormat("SELECT `time_played` FROM `character_data` WHERE `account_id` = %u", AccountID);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
|
||||||
EntitledTime += Strings::ToUnsignedInt(row[0]);
|
|
||||||
}
|
|
||||||
return EntitledTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SharedDatabase::SetMailKey(int CharID, int IPAddress, int MailKey)
|
|
||||||
{
|
{
|
||||||
char mail_key[17];
|
std::string full_mail_key;
|
||||||
|
|
||||||
if (RuleB(Chat, EnableMailKeyIPVerification) == true) {
|
if (RuleB(Chat, EnableMailKeyIPVerification)) {
|
||||||
sprintf(mail_key, "%08X%08X", IPAddress, MailKey);
|
full_mail_key = fmt::format("{:08X}{:08X}", ip_address, mail_key);
|
||||||
}
|
} else {
|
||||||
else {
|
full_mail_key = fmt::format("{:08X}", mail_key);
|
||||||
sprintf(mail_key, "%08X", MailKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string query = StringFormat(
|
auto e = CharacterDataRepository::FindOne(*this, character_id);
|
||||||
"UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
|
if (!e.id) {
|
||||||
mail_key, CharID
|
LogError("Failed to find character_id [{}] when setting mailkey", character_id);
|
||||||
);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto results = QueryDatabase(query);
|
e.mailkey = full_mail_key;
|
||||||
if (!results.Success()) {
|
|
||||||
LogError("SharedDatabase::SetMailKey({}, {}) : {}", CharID, mail_key, results.ErrorMessage().c_str());
|
if (!CharacterDataRepository::UpdateOne(*this, e)) {
|
||||||
|
LogError("Failed to set mailkey to [{}] for character_id [{}]", full_mail_key, character_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedDatabase::MailKeys SharedDatabase::GetMailKey(int character_id)
|
SharedDatabase::MailKeys SharedDatabase::GetMailKey(uint32 character_id)
|
||||||
{
|
{
|
||||||
const std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `id`='%i' LIMIT 1", character_id);
|
auto e = CharacterDataRepository::FindOne(*this, character_id);
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
if (!e.id) {
|
||||||
return MailKeys{ };
|
return MailKeys{ };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!results.RowCount()) {
|
|
||||||
Log(Logs::General,
|
|
||||||
Logs::ClientLogin,
|
|
||||||
"Error: Mailkey for character id [%i] does not exist or could not be found",
|
|
||||||
character_id
|
|
||||||
);
|
|
||||||
return MailKeys{};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &row = results.begin();
|
|
||||||
if (row != results.end()) {
|
|
||||||
std::string mail_key = row[0];
|
|
||||||
|
|
||||||
return MailKeys{
|
return MailKeys{
|
||||||
.mail_key = mail_key.substr(8),
|
.mail_key = e.mailkey.substr(8),
|
||||||
.mail_key_full = mail_key
|
.mail_key_full = e.mailkey
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return MailKeys{};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SharedDatabase::SaveCursor(
|
bool SharedDatabase::SaveCursor(
|
||||||
uint32 char_id,
|
uint32 char_id,
|
||||||
std::list<EQ::ItemInstance*>::const_iterator& start,
|
std::list<EQ::ItemInstance*>::const_iterator& start,
|
||||||
@@ -448,27 +423,20 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32 SharedDatabase::GetSharedPlatinum(uint32 account_id)
|
int32 SharedDatabase::GetSharedPlatinum(uint32 account_id)
|
||||||
{
|
{
|
||||||
const auto query = fmt::format("SELECT sharedplat FROM account WHERE id = {}", account_id);
|
const auto& e = AccountRepository::FindOne(*this, account_id);
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
if (!results.Success() || !results.RowCount()) {
|
return e.sharedplat;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
bool SharedDatabase::AddSharedPlatinum(uint32 account_id, int amount)
|
||||||
return Strings::ToInt(row[0]);
|
{
|
||||||
}
|
auto e = AccountRepository::FindOne(*this, account_id);
|
||||||
|
|
||||||
bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
|
e.sharedplat += amount;
|
||||||
const std::string query = StringFormat("UPDATE account SET sharedplat = sharedplat + %i WHERE id = %i", amount_to_add, account_id);
|
|
||||||
const auto results = QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return AccountRepository::UpdateOne(*this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SharedDatabase::SetStartingItems(
|
bool SharedDatabase::SetStartingItems(
|
||||||
|
|||||||
+3
-4
@@ -82,15 +82,14 @@ public:
|
|||||||
bool UpdateInjectedCommandSettings(const std::vector<std::pair<std::string, uint8>> &injected);
|
bool UpdateInjectedCommandSettings(const std::vector<std::pair<std::string, uint8>> &injected);
|
||||||
bool UpdateOrphanedCommandSettings(const std::vector<std::string> &orphaned);
|
bool UpdateOrphanedCommandSettings(const std::vector<std::string> &orphaned);
|
||||||
bool GetCommandSubSettings(std::vector<CommandSubsettingsRepository::CommandSubsettings> &command_subsettings);
|
bool GetCommandSubSettings(std::vector<CommandSubsettingsRepository::CommandSubsettings> &command_subsettings);
|
||||||
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
|
|
||||||
bool SetGMInvul(uint32 account_id, bool gminvul);
|
bool SetGMInvul(uint32 account_id, bool gminvul);
|
||||||
bool SetGMFlymode(uint32 account_id, uint8 flymode);
|
bool SetGMFlymode(uint32 account_id, uint8 flymode);
|
||||||
void SetMailKey(int CharID, int IPAddress, int MailKey);
|
void SetMailKey(uint32 character_id, uint32 ip_address, uint32 mail_key);
|
||||||
struct MailKeys {
|
struct MailKeys {
|
||||||
std::string mail_key;
|
std::string mail_key;
|
||||||
std::string mail_key_full;
|
std::string mail_key_full;
|
||||||
};
|
};
|
||||||
MailKeys GetMailKey(int character_id);
|
MailKeys GetMailKey(uint32 character_id);
|
||||||
bool SaveCursor(
|
bool SaveCursor(
|
||||||
uint32 char_id,
|
uint32 char_id,
|
||||||
std::list<EQ::ItemInstance *>::const_iterator &start,
|
std::list<EQ::ItemInstance *>::const_iterator &start,
|
||||||
@@ -104,7 +103,7 @@ public:
|
|||||||
bool VerifyInventory(uint32 account_id, int16 slot_id, const EQ::ItemInstance *inst);
|
bool VerifyInventory(uint32 account_id, int16 slot_id, const EQ::ItemInstance *inst);
|
||||||
bool GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is_charid);
|
bool GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is_charid);
|
||||||
int32 GetSharedPlatinum(uint32 account_id);
|
int32 GetSharedPlatinum(uint32 account_id);
|
||||||
bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add);
|
bool AddSharedPlatinum(uint32 account_id, int amount);
|
||||||
bool GetInventory(Client* c);
|
bool GetInventory(Client* c);
|
||||||
bool GetInventory(uint32 account_id, char *name, EQ::InventoryProfile *inv); // deprecated
|
bool GetInventory(uint32 account_id, char *name, EQ::InventoryProfile *inv); // deprecated
|
||||||
std::map<uint32, uint32> GetItemRecastTimestamps(uint32 char_id);
|
std::map<uint32, uint32> GetItemRecastTimestamps(uint32 char_id);
|
||||||
|
|||||||
+2
-2
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
// Build variables
|
// Build variables
|
||||||
// these get injected during the build pipeline
|
// these get injected during the build pipeline
|
||||||
#define CURRENT_VERSION "23.9.1-dev" // always append -dev to the current version for custom-builds
|
#define CURRENT_VERSION "23.10.1-dev" // always append -dev to the current version for custom-builds
|
||||||
#define LOGIN_VERSION "0.8.0"
|
#define LOGIN_VERSION "0.8.0"
|
||||||
#define COMPILE_DATE __DATE__
|
#define COMPILE_DATE __DATE__
|
||||||
#define COMPILE_TIME __TIME__
|
#define COMPILE_TIME __TIME__
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9328
|
#define CURRENT_BINARY_DATABASE_VERSION 9329
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
|
||||||
#define CUSTOM_BINARY_DATABASE_VERSION 0
|
#define CUSTOM_BINARY_DATABASE_VERSION 0
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "eqemu-server",
|
"name": "eqemu-server",
|
||||||
"version": "23.9.1",
|
"version": "23.10.1",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/EQEmu/Server.git"
|
"url": "https://github.com/EQEmu/Server.git"
|
||||||
|
|||||||
+1
-1
@@ -985,7 +985,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
// set mailkey - used for duration of character session
|
// set mailkey - used for duration of character session
|
||||||
int mail_key = EQ::Random::Instance()->Int(1, INT_MAX);
|
uint32 mail_key = EQ::Random::Instance()->Int(1, INT_MAX);
|
||||||
|
|
||||||
database.SetMailKey(charid, GetIP(), mail_key);
|
database.SetMailKey(charid, GetIP(), mail_key);
|
||||||
if (UCSServerAvailable_) {
|
if (UCSServerAvailable_) {
|
||||||
|
|||||||
@@ -1713,7 +1713,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
if (zone->IsPVPZone())
|
if (zone->IsPVPZone())
|
||||||
m_pp.pvp = 1;
|
m_pp.pvp = 1;
|
||||||
/* Time entitled on Account: Move to account */
|
/* Time entitled on Account: Move to account */
|
||||||
m_pp.timeentitledonaccount = database.GetTotalTimeEntitledOnAccount(AccountID()) / 1440;
|
m_pp.timeentitledonaccount = CharacterDataRepository::GetTotalTimePlayed(database, AccountID()) / 1440;
|
||||||
/* Reset rest timer if the durations have been lowered in the database */
|
/* Reset rest timer if the durations have been lowered in the database */
|
||||||
if ((m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate)) && (m_pp.RestTimer > RuleI(Character, RestRegenRaidTimeToActivate)))
|
if ((m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate)) && (m_pp.RestTimer > RuleI(Character, RestRegenRaidTimeToActivate)))
|
||||||
m_pp.RestTimer = 0;
|
m_pp.RestTimer = 0;
|
||||||
@@ -7988,7 +7988,7 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
if ((Admin() < RuleI(Guild, PlayerCreationRequiredStatus)) ||
|
if ((Admin() < RuleI(Guild, PlayerCreationRequiredStatus)) ||
|
||||||
(GetLevel() < RuleI(Guild, PlayerCreationRequiredLevel)) ||
|
(GetLevel() < RuleI(Guild, PlayerCreationRequiredLevel)) ||
|
||||||
(database.GetTotalTimeEntitledOnAccount(AccountID()) < (unsigned int)RuleI(Guild, PlayerCreationRequiredTime)))
|
(CharacterDataRepository::GetTotalTimePlayed(database, AccountID()) < (unsigned int)RuleI(Guild, PlayerCreationRequiredTime)))
|
||||||
{
|
{
|
||||||
Message(Chat::Red, "Your status, level or time playing on this account are insufficient to use this feature.");
|
Message(Chat::Red, "Your status, level or time playing on this account are insufficient to use this feature.");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1571,7 +1571,7 @@ void Client::OPMoveCoin(const EQApplicationPacket* app)
|
|||||||
if (from_bucket == &m_pp.platinum_shared)
|
if (from_bucket == &m_pp.platinum_shared)
|
||||||
amount_to_add = 0 - amount_to_take;
|
amount_to_add = 0 - amount_to_take;
|
||||||
|
|
||||||
database.SetSharedPlatinum(AccountID(),amount_to_add);
|
database.AddSharedPlatinum(AccountID(),amount_to_add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|||||||
@@ -208,6 +208,8 @@ const char* QuestEventSubroutines[_LargestEventID] = {
|
|||||||
"EVENT_SPELL_BLOCKED",
|
"EVENT_SPELL_BLOCKED",
|
||||||
"EVENT_READ_ITEM",
|
"EVENT_READ_ITEM",
|
||||||
"EVENT_PET_COMMAND",
|
"EVENT_PET_COMMAND",
|
||||||
|
"EVENT_CHARM_START",
|
||||||
|
"EVENT_CHARM_END",
|
||||||
|
|
||||||
// Add new events before these or Lua crashes
|
// Add new events before these or Lua crashes
|
||||||
"EVENT_SPELL_EFFECT_BOT",
|
"EVENT_SPELL_EFFECT_BOT",
|
||||||
|
|||||||
@@ -146,6 +146,8 @@ typedef enum {
|
|||||||
EVENT_SPELL_BLOCKED,
|
EVENT_SPELL_BLOCKED,
|
||||||
EVENT_READ_ITEM,
|
EVENT_READ_ITEM,
|
||||||
EVENT_PET_COMMAND,
|
EVENT_PET_COMMAND,
|
||||||
|
EVENT_CHARM_START,
|
||||||
|
EVENT_CHARM_END,
|
||||||
|
|
||||||
// Add new events before these or Lua crashes
|
// Add new events before these or Lua crashes
|
||||||
EVENT_SPELL_EFFECT_BOT,
|
EVENT_SPELL_EFFECT_BOT,
|
||||||
|
|||||||
@@ -6992,7 +6992,9 @@ luabind::scope lua_register_events() {
|
|||||||
luabind::value("entity_variable_update", static_cast<int>(EVENT_ENTITY_VARIABLE_UPDATE)),
|
luabind::value("entity_variable_update", static_cast<int>(EVENT_ENTITY_VARIABLE_UPDATE)),
|
||||||
luabind::value("aa_loss", static_cast<int>(EVENT_AA_LOSS)),
|
luabind::value("aa_loss", static_cast<int>(EVENT_AA_LOSS)),
|
||||||
luabind::value("read", static_cast<int>(EVENT_READ_ITEM)),
|
luabind::value("read", static_cast<int>(EVENT_READ_ITEM)),
|
||||||
luabind::value("pet_command", static_cast<int>(EVENT_PET_COMMAND))
|
luabind::value("pet_command", static_cast<int>(EVENT_PET_COMMAND)),
|
||||||
|
luabind::value("charm_start", static_cast<int>(EVENT_CHARM_START)),
|
||||||
|
luabind::value("charm_end", static_cast<int>(EVENT_CHARM_END))
|
||||||
)];
|
)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -189,7 +189,9 @@ const char *LuaEvents[_LargestEventID] = {
|
|||||||
"event_aa_loss",
|
"event_aa_loss",
|
||||||
"event_spell_blocked",
|
"event_spell_blocked",
|
||||||
"event_read_item",
|
"event_read_item",
|
||||||
"event_pet_command"
|
"event_pet_command",
|
||||||
|
"event_charm_start",
|
||||||
|
"event_charm_end"
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Zone *zone;
|
extern Zone *zone;
|
||||||
@@ -266,6 +268,8 @@ LuaParser::LuaParser() {
|
|||||||
NPCArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_npc_entity_variable;
|
NPCArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_npc_entity_variable;
|
||||||
NPCArgumentDispatch[EVENT_SPELL_BLOCKED] = handle_npc_spell_blocked;
|
NPCArgumentDispatch[EVENT_SPELL_BLOCKED] = handle_npc_spell_blocked;
|
||||||
NPCArgumentDispatch[EVENT_PET_COMMAND] = handle_npc_pet_command;
|
NPCArgumentDispatch[EVENT_PET_COMMAND] = handle_npc_pet_command;
|
||||||
|
NPCArgumentDispatch[EVENT_CHARM_START] = handle_npc_single_mob;
|
||||||
|
NPCArgumentDispatch[EVENT_CHARM_END] = handle_npc_single_mob;
|
||||||
|
|
||||||
PlayerArgumentDispatch[EVENT_SAY] = handle_player_say;
|
PlayerArgumentDispatch[EVENT_SAY] = handle_player_say;
|
||||||
PlayerArgumentDispatch[EVENT_ENVIRONMENTAL_DAMAGE] = handle_player_environmental_damage;
|
PlayerArgumentDispatch[EVENT_ENVIRONMENTAL_DAMAGE] = handle_player_environmental_damage;
|
||||||
|
|||||||
+180
-289
@@ -2274,9 +2274,9 @@ void NPC::SetLevel(uint8 in_level, bool command)
|
|||||||
|
|
||||||
void NPC::ModifyNPCStat(const std::string& stat, const std::string& value)
|
void NPC::ModifyNPCStat(const std::string& stat, const std::string& value)
|
||||||
{
|
{
|
||||||
auto stat_lower = Strings::ToLower(stat);
|
const std::string& stat_lower = Strings::ToLower(stat);
|
||||||
|
|
||||||
auto variable_key = fmt::format(
|
const std::string& variable_key = fmt::format(
|
||||||
"modify_stat_{}",
|
"modify_stat_{}",
|
||||||
stat_lower
|
stat_lower
|
||||||
);
|
);
|
||||||
@@ -2288,40 +2288,24 @@ void NPC::ModifyNPCStat(const std::string& stat, const std::string& value)
|
|||||||
if (stat_lower == "ac") {
|
if (stat_lower == "ac") {
|
||||||
AC = Strings::ToInt(value);
|
AC = Strings::ToInt(value);
|
||||||
CalcAC();
|
CalcAC();
|
||||||
return;
|
} else if (stat_lower == "str") {
|
||||||
}
|
|
||||||
else if (stat_lower == "str") {
|
|
||||||
STR = Strings::ToInt(value);
|
STR = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "sta") {
|
||||||
}
|
|
||||||
else if (stat_lower == "sta") {
|
|
||||||
STA = Strings::ToInt(value);
|
STA = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "agi") {
|
||||||
}
|
|
||||||
else if (stat_lower == "agi") {
|
|
||||||
AGI = Strings::ToInt(value);
|
AGI = Strings::ToInt(value);
|
||||||
CalcAC();
|
CalcAC();
|
||||||
return;
|
} else if (stat_lower == "dex") {
|
||||||
}
|
|
||||||
else if (stat_lower == "dex") {
|
|
||||||
DEX = Strings::ToInt(value);
|
DEX = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "wis") {
|
||||||
}
|
|
||||||
else if (stat_lower == "wis") {
|
|
||||||
WIS = Strings::ToInt(value);
|
WIS = Strings::ToInt(value);
|
||||||
CalcMaxMana();
|
CalcMaxMana();
|
||||||
return;
|
} else if (stat_lower == "int" || stat_lower == "_int") {
|
||||||
}
|
|
||||||
else if (stat_lower == "int" || stat_lower == "_int") {
|
|
||||||
INT = Strings::ToInt(value);
|
INT = Strings::ToInt(value);
|
||||||
CalcMaxMana();
|
CalcMaxMana();
|
||||||
return;
|
} else if (stat_lower == "cha") {
|
||||||
}
|
|
||||||
else if (stat_lower == "cha") {
|
|
||||||
CHA = Strings::ToInt(value);
|
CHA = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "max_hp") {
|
||||||
}
|
|
||||||
else if (stat_lower == "max_hp") {
|
|
||||||
base_hp = Strings::ToBigInt(value);
|
base_hp = Strings::ToBigInt(value);
|
||||||
|
|
||||||
CalcMaxHP();
|
CalcMaxHP();
|
||||||
@@ -2329,45 +2313,27 @@ void NPC::ModifyNPCStat(const std::string& stat, const std::string& value)
|
|||||||
current_hp = max_hp;
|
current_hp = max_hp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
} else if (stat_lower == "max_mana") {
|
||||||
}
|
|
||||||
else if (stat_lower == "max_mana") {
|
|
||||||
npc_mana = Strings::ToUnsignedBigInt(value);
|
npc_mana = Strings::ToUnsignedBigInt(value);
|
||||||
CalcMaxMana();
|
CalcMaxMana();
|
||||||
if (current_mana > max_mana) {
|
if (current_mana > max_mana) {
|
||||||
current_mana = max_mana;
|
current_mana = max_mana;
|
||||||
}
|
}
|
||||||
return;
|
} else if (stat_lower == "mr") {
|
||||||
}
|
|
||||||
else if (stat_lower == "mr") {
|
|
||||||
MR = Strings::ToInt(value);
|
MR = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "fr") {
|
||||||
}
|
|
||||||
else if (stat_lower == "fr") {
|
|
||||||
FR = Strings::ToInt(value);
|
FR = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "cr") {
|
||||||
}
|
|
||||||
else if (stat_lower == "cr") {
|
|
||||||
CR = Strings::ToInt(value);
|
CR = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "cor") {
|
||||||
}
|
|
||||||
else if (stat_lower == "cor") {
|
|
||||||
Corrup = Strings::ToInt(value);
|
Corrup = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "pr") {
|
||||||
}
|
|
||||||
else if (stat_lower == "pr") {
|
|
||||||
PR = Strings::ToInt(value);
|
PR = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "dr") {
|
||||||
}
|
|
||||||
else if (stat_lower == "dr") {
|
|
||||||
DR = Strings::ToInt(value);
|
DR = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "phr") {
|
||||||
}
|
|
||||||
else if (stat_lower == "phr") {
|
|
||||||
PhR = Strings::ToInt(value);
|
PhR = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "runspeed") {
|
||||||
}
|
|
||||||
else if (stat_lower == "runspeed") {
|
|
||||||
runspeed = Strings::ToFloat(value);
|
runspeed = Strings::ToFloat(value);
|
||||||
base_runspeed = (int) (runspeed * 40.0f);
|
base_runspeed = (int) (runspeed * 40.0f);
|
||||||
base_walkspeed = base_runspeed * 100 / 265;
|
base_walkspeed = base_runspeed * 100 / 265;
|
||||||
@@ -2375,297 +2341,229 @@ void NPC::ModifyNPCStat(const std::string& stat, const std::string& value)
|
|||||||
base_fearspeed = base_runspeed * 100 / 127;
|
base_fearspeed = base_runspeed * 100 / 127;
|
||||||
fearspeed = ((float) base_fearspeed) * 0.025f;
|
fearspeed = ((float) base_fearspeed) * 0.025f;
|
||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
return;
|
} else if (stat_lower == "special_attacks") {
|
||||||
}
|
|
||||||
else if (stat_lower == "special_attacks") {
|
|
||||||
NPCSpecialAttacks(value.c_str(), 0, true);
|
NPCSpecialAttacks(value.c_str(), 0, true);
|
||||||
return;
|
} else if (stat_lower == "special_abilities") {
|
||||||
}
|
|
||||||
else if (stat_lower == "special_abilities") {
|
|
||||||
ProcessSpecialAbilities(value);
|
ProcessSpecialAbilities(value);
|
||||||
return;
|
} else if (stat_lower == "attack_speed") {
|
||||||
}
|
|
||||||
else if (stat_lower == "attack_speed") {
|
|
||||||
attack_speed = Strings::ToFloat(value);
|
attack_speed = Strings::ToFloat(value);
|
||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
return;
|
} else if (stat_lower == "attack_delay") {
|
||||||
}
|
|
||||||
else if (stat_lower == "attack_delay") {
|
|
||||||
/* TODO: fix DB */
|
/* TODO: fix DB */
|
||||||
attack_delay = Strings::ToInt(value) * 100;
|
attack_delay = Strings::ToInt(value) * 100;
|
||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
return;
|
} else if (stat_lower == "atk") {
|
||||||
}
|
|
||||||
else if (stat_lower == "atk") {
|
|
||||||
ATK = Strings::ToInt(value);
|
ATK = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "accuracy") {
|
||||||
}
|
|
||||||
else if (stat_lower == "accuracy") {
|
|
||||||
accuracy_rating = Strings::ToInt(value);
|
accuracy_rating = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "avoidance") {
|
||||||
}
|
|
||||||
else if (stat_lower == "avoidance") {
|
|
||||||
avoidance_rating = Strings::ToInt(value);
|
avoidance_rating = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "trackable") {
|
||||||
}
|
|
||||||
else if (stat_lower == "trackable") {
|
|
||||||
trackable = Strings::ToInt(value);
|
trackable = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "min_hit") {
|
||||||
}
|
|
||||||
else if (stat_lower == "min_hit") {
|
|
||||||
min_dmg = Strings::ToInt(value);
|
min_dmg = Strings::ToInt(value);
|
||||||
// Clamp max_dmg to be >= min_dmg
|
// Clamp max_dmg to be >= min_dmg
|
||||||
max_dmg = std::max(min_dmg, max_dmg);
|
max_dmg = std::max(min_dmg, max_dmg);
|
||||||
base_damage = round((max_dmg - min_dmg) / 1.9);
|
base_damage = round((max_dmg - min_dmg) / 1.9);
|
||||||
min_damage = min_dmg - round(base_damage / 10.0);
|
min_damage = min_dmg - round(base_damage / 10.0);
|
||||||
return;
|
} else if (stat_lower == "max_hit") {
|
||||||
}
|
|
||||||
else if (stat_lower == "max_hit") {
|
|
||||||
max_dmg = Strings::ToInt(value);
|
max_dmg = Strings::ToInt(value);
|
||||||
// Clamp min_dmg to be <= max_dmg
|
// Clamp min_dmg to be <= max_dmg
|
||||||
min_dmg = std::min(min_dmg, max_dmg);
|
min_dmg = std::min(min_dmg, max_dmg);
|
||||||
base_damage = round((max_dmg - min_dmg) / 1.9);
|
base_damage = round((max_dmg - min_dmg) / 1.9);
|
||||||
min_damage = min_dmg - round(base_damage / 10.0);
|
min_damage = min_dmg - round(base_damage / 10.0);
|
||||||
return;
|
} else if (stat_lower == "attack_count") {
|
||||||
}
|
|
||||||
else if (stat_lower == "attack_count") {
|
|
||||||
attack_count = Strings::ToInt(value);
|
attack_count = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "see_invis") {
|
||||||
}
|
|
||||||
else if (stat_lower == "see_invis") {
|
|
||||||
see_invis = Strings::ToInt(value);
|
see_invis = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "see_invis_undead") {
|
||||||
}
|
|
||||||
else if (stat_lower == "see_invis_undead") {
|
|
||||||
see_invis_undead = Strings::ToInt(value);
|
see_invis_undead = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "see_hide") {
|
||||||
}
|
|
||||||
else if (stat_lower == "see_hide") {
|
|
||||||
see_hide = Strings::ToInt(value);
|
see_hide = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "see_improved_hide") {
|
||||||
}
|
|
||||||
else if (stat_lower == "see_improved_hide") {
|
|
||||||
see_improved_hide = Strings::ToInt(value);
|
see_improved_hide = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "hp_regen") {
|
||||||
}
|
|
||||||
else if (stat_lower == "hp_regen") {
|
|
||||||
hp_regen = Strings::ToBigInt(value);
|
hp_regen = Strings::ToBigInt(value);
|
||||||
return;
|
} else if (stat_lower == "hp_regen_per_second") {
|
||||||
}
|
|
||||||
else if (stat_lower == "hp_regen_per_second") {
|
|
||||||
hp_regen_per_second = Strings::ToBigInt(value);
|
hp_regen_per_second = Strings::ToBigInt(value);
|
||||||
return;
|
} else if (stat_lower == "mana_regen") {
|
||||||
}
|
|
||||||
else if (stat_lower == "mana_regen") {
|
|
||||||
mana_regen = Strings::ToBigInt(value);
|
mana_regen = Strings::ToBigInt(value);
|
||||||
return;
|
} else if (stat_lower == "level") {
|
||||||
}
|
|
||||||
else if (stat_lower == "level") {
|
|
||||||
SetLevel(Strings::ToInt(value));
|
SetLevel(Strings::ToInt(value));
|
||||||
return;
|
} else if (stat_lower == "aggro") {
|
||||||
}
|
|
||||||
else if (stat_lower == "aggro") {
|
|
||||||
pAggroRange = Strings::ToFloat(value);
|
pAggroRange = Strings::ToFloat(value);
|
||||||
return;
|
} else if (stat_lower == "assist") {
|
||||||
}
|
|
||||||
else if (stat_lower == "assist") {
|
|
||||||
pAssistRange = Strings::ToFloat(value);
|
pAssistRange = Strings::ToFloat(value);
|
||||||
return;
|
} else if (stat_lower == "slow_mitigation") {
|
||||||
}
|
|
||||||
else if (stat_lower == "slow_mitigation") {
|
|
||||||
slow_mitigation = Strings::ToInt(value);
|
slow_mitigation = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "loottable_id") {
|
||||||
}
|
|
||||||
else if (stat_lower == "loottable_id") {
|
|
||||||
m_loottable_id = Strings::ToFloat(value);
|
m_loottable_id = Strings::ToFloat(value);
|
||||||
return;
|
} else if (stat_lower == "healscale") {
|
||||||
}
|
|
||||||
else if (stat_lower == "healscale") {
|
|
||||||
healscale = Strings::ToFloat(value);
|
healscale = Strings::ToFloat(value);
|
||||||
return;
|
} else if (stat_lower == "spellscale") {
|
||||||
}
|
|
||||||
else if (stat_lower == "spellscale") {
|
|
||||||
spellscale = Strings::ToFloat(value);
|
spellscale = Strings::ToFloat(value);
|
||||||
return;
|
} else if (stat_lower == "npc_spells_id") {
|
||||||
}
|
|
||||||
else if (stat_lower == "npc_spells_id") {
|
|
||||||
AI_AddNPCSpells(Strings::ToInt(value));
|
AI_AddNPCSpells(Strings::ToInt(value));
|
||||||
return;
|
} else if (stat_lower == "npc_spells_effects_id") {
|
||||||
}
|
|
||||||
else if (stat_lower == "npc_spells_effects_id") {
|
|
||||||
AI_AddNPCSpellsEffects(Strings::ToInt(value));
|
AI_AddNPCSpellsEffects(Strings::ToInt(value));
|
||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
return;
|
} else if (stat_lower == "heroic_strikethrough") {
|
||||||
}
|
|
||||||
else if (stat_lower == "heroic_strikethrough") {
|
|
||||||
heroic_strikethrough = Strings::ToInt(value);
|
heroic_strikethrough = Strings::ToInt(value);
|
||||||
return;
|
} else if (stat_lower == "keeps_sold_items") {
|
||||||
}
|
|
||||||
else if (stat_lower == "keeps_sold_items") {
|
|
||||||
SetKeepsSoldItems(Strings::ToBool(value));
|
SetKeepsSoldItems(Strings::ToBool(value));
|
||||||
return;
|
} else if (stat_lower == "charm_ac") {
|
||||||
|
charm_ac = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "charm_min_dmg") {
|
||||||
|
charm_min_dmg = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "charm_max_dmg") {
|
||||||
|
charm_max_dmg = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "charm_attack_delay") {
|
||||||
|
charm_attack_delay = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "charm_accuracy_rating") {
|
||||||
|
charm_accuracy_rating = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "charm_avoidance_rating") {
|
||||||
|
charm_avoidance_rating = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "charm_atk") {
|
||||||
|
charm_atk = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "default_ac") {
|
||||||
|
default_ac = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "default_min_dmg") {
|
||||||
|
default_min_dmg = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "default_max_dmg") {
|
||||||
|
default_max_dmg = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "default_attack_delay") {
|
||||||
|
default_attack_delay = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "default_accuracy_rating") {
|
||||||
|
default_accuracy_rating = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "default_avoidance_rating") {
|
||||||
|
default_avoidance_rating = Strings::ToInt(value);
|
||||||
|
} else if (stat_lower == "default_atk") {
|
||||||
|
default_atk = Strings::ToInt(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float NPC::GetNPCStat(const std::string& stat)
|
float NPC::GetNPCStat(const std::string& stat)
|
||||||
{
|
{
|
||||||
|
const std::string& stat_lower = Strings::ToLower(stat);
|
||||||
|
|
||||||
if (auto stat_lower = Strings::ToLower(stat); stat_lower == "ac") {
|
if (stat_lower == "ac") {
|
||||||
return AC;
|
return AC;
|
||||||
}
|
} else if (stat_lower == "str") {
|
||||||
else if (stat_lower == "str") {
|
|
||||||
return STR;
|
return STR;
|
||||||
}
|
} else if (stat_lower == "sta") {
|
||||||
else if (stat_lower == "sta") {
|
|
||||||
return STA;
|
return STA;
|
||||||
}
|
} else if (stat_lower == "agi") {
|
||||||
else if (stat_lower == "agi") {
|
|
||||||
return AGI;
|
return AGI;
|
||||||
}
|
} else if (stat_lower == "dex") {
|
||||||
else if (stat_lower == "dex") {
|
|
||||||
return DEX;
|
return DEX;
|
||||||
}
|
} else if (stat_lower == "wis") {
|
||||||
else if (stat_lower == "wis") {
|
|
||||||
return WIS;
|
return WIS;
|
||||||
}
|
} else if (stat_lower == "int" || stat_lower == "_int") {
|
||||||
else if (stat_lower == "int" || stat_lower == "_int") {
|
|
||||||
return INT;
|
return INT;
|
||||||
}
|
} else if (stat_lower == "cha") {
|
||||||
else if (stat_lower == "cha") {
|
|
||||||
return CHA;
|
return CHA;
|
||||||
}
|
} else if (stat_lower == "max_hp") {
|
||||||
else if (stat_lower == "max_hp") {
|
|
||||||
return base_hp;
|
return base_hp;
|
||||||
}
|
} else if (stat_lower == "max_mana") {
|
||||||
else if (stat_lower == "max_mana") {
|
|
||||||
return npc_mana;
|
return npc_mana;
|
||||||
}
|
} else if (stat_lower == "mr") {
|
||||||
else if (stat_lower == "mr") {
|
|
||||||
return MR;
|
return MR;
|
||||||
}
|
} else if (stat_lower == "fr") {
|
||||||
else if (stat_lower == "fr") {
|
|
||||||
return FR;
|
return FR;
|
||||||
}
|
} else if (stat_lower == "cr") {
|
||||||
else if (stat_lower == "cr") {
|
|
||||||
return CR;
|
return CR;
|
||||||
}
|
} else if (stat_lower == "cor") {
|
||||||
else if (stat_lower == "cor") {
|
|
||||||
return Corrup;
|
return Corrup;
|
||||||
}
|
} else if (stat_lower == "phr") {
|
||||||
else if (stat_lower == "phr") {
|
|
||||||
return PhR;
|
return PhR;
|
||||||
}
|
} else if (stat_lower == "pr") {
|
||||||
else if (stat_lower == "pr") {
|
|
||||||
return PR;
|
return PR;
|
||||||
}
|
} else if (stat_lower == "dr") {
|
||||||
else if (stat_lower == "dr") {
|
|
||||||
return DR;
|
return DR;
|
||||||
}
|
} else if (stat_lower == "runspeed") {
|
||||||
else if (stat_lower == "runspeed") {
|
|
||||||
return runspeed;
|
return runspeed;
|
||||||
}
|
} else if (stat_lower == "attack_speed") {
|
||||||
else if (stat_lower == "attack_speed") {
|
|
||||||
return attack_speed;
|
return attack_speed;
|
||||||
}
|
} else if (stat_lower == "attack_delay") {
|
||||||
else if (stat_lower == "attack_delay") {
|
|
||||||
return attack_delay;
|
return attack_delay;
|
||||||
}
|
} else if (stat_lower == "atk") {
|
||||||
else if (stat_lower == "atk") {
|
|
||||||
return ATK;
|
return ATK;
|
||||||
}
|
} else if (stat_lower == "accuracy") {
|
||||||
else if (stat_lower == "accuracy") {
|
|
||||||
return accuracy_rating;
|
return accuracy_rating;
|
||||||
}
|
} else if (stat_lower == "avoidance") {
|
||||||
else if (stat_lower == "avoidance") {
|
|
||||||
return avoidance_rating;
|
return avoidance_rating;
|
||||||
}
|
} else if (stat_lower == "trackable") {
|
||||||
else if (stat_lower == "trackable") {
|
|
||||||
return trackable;
|
return trackable;
|
||||||
}
|
} else if (stat_lower == "min_hit") {
|
||||||
else if (stat_lower == "min_hit") {
|
|
||||||
return min_dmg;
|
return min_dmg;
|
||||||
}
|
} else if (stat_lower == "max_hit") {
|
||||||
else if (stat_lower == "max_hit") {
|
|
||||||
return max_dmg;
|
return max_dmg;
|
||||||
}
|
} else if (stat_lower == "attack_count") {
|
||||||
else if (stat_lower == "attack_count") {
|
|
||||||
return attack_count;
|
return attack_count;
|
||||||
}
|
} else if (stat_lower == "see_invis") {
|
||||||
else if (stat_lower == "see_invis") {
|
|
||||||
return see_invis;
|
return see_invis;
|
||||||
}
|
} else if (stat_lower == "see_invis_undead") {
|
||||||
else if (stat_lower == "see_invis_undead") {
|
|
||||||
return see_invis_undead;
|
return see_invis_undead;
|
||||||
}
|
} else if (stat_lower == "see_hide") {
|
||||||
else if (stat_lower == "see_hide") {
|
|
||||||
return see_hide;
|
return see_hide;
|
||||||
}
|
} else if (stat_lower == "see_improved_hide") {
|
||||||
else if (stat_lower == "see_improved_hide") {
|
|
||||||
return see_improved_hide;
|
return see_improved_hide;
|
||||||
}
|
} else if (stat_lower == "hp_regen") {
|
||||||
else if (stat_lower == "hp_regen") {
|
|
||||||
return hp_regen;
|
return hp_regen;
|
||||||
}
|
} else if (stat_lower == "hp_regen_per_second") {
|
||||||
else if (stat_lower == "hp_regen_per_second") {
|
|
||||||
return hp_regen_per_second;
|
return hp_regen_per_second;
|
||||||
}
|
} else if (stat_lower == "mana_regen") {
|
||||||
else if (stat_lower == "mana_regen") {
|
|
||||||
return mana_regen;
|
return mana_regen;
|
||||||
}
|
} else if (stat_lower == "level") {
|
||||||
else if (stat_lower == "level") {
|
|
||||||
return GetOrigLevel();
|
return GetOrigLevel();
|
||||||
}
|
} else if (stat_lower == "aggro") {
|
||||||
else if (stat_lower == "aggro") {
|
|
||||||
return pAggroRange;
|
return pAggroRange;
|
||||||
}
|
} else if (stat_lower == "assist") {
|
||||||
else if (stat_lower == "assist") {
|
|
||||||
return pAssistRange;
|
return pAssistRange;
|
||||||
}
|
} else if (stat_lower == "slow_mitigation") {
|
||||||
else if (stat_lower == "slow_mitigation") {
|
|
||||||
return slow_mitigation;
|
return slow_mitigation;
|
||||||
}
|
} else if (stat_lower == "loottable_id") {
|
||||||
else if (stat_lower == "loottable_id") {
|
|
||||||
return m_loottable_id;
|
return m_loottable_id;
|
||||||
}
|
} else if (stat_lower == "healscale") {
|
||||||
else if (stat_lower == "healscale") {
|
|
||||||
return healscale;
|
return healscale;
|
||||||
}
|
} else if (stat_lower == "spellscale") {
|
||||||
else if (stat_lower == "spellscale") {
|
|
||||||
return spellscale;
|
return spellscale;
|
||||||
}
|
} else if (stat_lower == "npc_spells_id") {
|
||||||
else if (stat_lower == "npc_spells_id") {
|
|
||||||
return npc_spells_id;
|
return npc_spells_id;
|
||||||
}
|
} else if (stat_lower == "npc_spells_effects_id") {
|
||||||
else if (stat_lower == "npc_spells_effects_id") {
|
|
||||||
return npc_spells_effects_id;
|
return npc_spells_effects_id;
|
||||||
}
|
} else if (stat_lower == "heroic_strikethrough") {
|
||||||
else if (stat_lower == "heroic_strikethrough") {
|
|
||||||
return heroic_strikethrough;
|
return heroic_strikethrough;
|
||||||
}
|
} else if (stat_lower == "keeps_sold_items") {
|
||||||
else if (stat_lower == "keeps_sold_items") {
|
|
||||||
return keeps_sold_items;
|
return keeps_sold_items;
|
||||||
}
|
} else if (stat_lower == "default_ac") {
|
||||||
//default values
|
|
||||||
else if (stat_lower == "default_ac") {
|
|
||||||
return default_ac;
|
return default_ac;
|
||||||
}
|
} else if (stat_lower == "default_min_hit") {
|
||||||
else if (stat_lower == "default_min_hit") {
|
|
||||||
return default_min_dmg;
|
return default_min_dmg;
|
||||||
}
|
} else if (stat_lower == "default_max_hit") {
|
||||||
else if (stat_lower == "default_max_hit") {
|
|
||||||
return default_max_dmg;
|
return default_max_dmg;
|
||||||
}
|
} else if (stat_lower == "default_attack_delay") {
|
||||||
else if (stat_lower == "default_attack_delay") {
|
|
||||||
return default_attack_delay;
|
return default_attack_delay;
|
||||||
}
|
} else if (stat_lower == "default_accuracy") {
|
||||||
else if (stat_lower == "default_accuracy") {
|
|
||||||
return default_accuracy_rating;
|
return default_accuracy_rating;
|
||||||
}
|
} else if (stat_lower == "default_avoidance") {
|
||||||
else if (stat_lower == "default_avoidance") {
|
|
||||||
return default_avoidance_rating;
|
return default_avoidance_rating;
|
||||||
}
|
} else if (stat_lower == "default_atk") {
|
||||||
else if (stat_lower == "default_atk") {
|
|
||||||
return default_atk;
|
return default_atk;
|
||||||
|
} else if (stat_lower == "charm_ac") {
|
||||||
|
return charm_ac;
|
||||||
|
} else if (stat_lower == "charm_min_hit") {
|
||||||
|
return charm_min_dmg;
|
||||||
|
} else if (stat_lower == "charm_max_hit") {
|
||||||
|
return charm_max_dmg;
|
||||||
|
} else if (stat_lower == "charm_attack_delay") {
|
||||||
|
return charm_attack_delay;
|
||||||
|
} else if (stat_lower == "charm_accuracy") {
|
||||||
|
return charm_accuracy_rating;
|
||||||
|
} else if (stat_lower == "charm_avoidance") {
|
||||||
|
return charm_avoidance_rating;
|
||||||
|
} else if (stat_lower == "charm_atk") {
|
||||||
|
return charm_atk;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
@@ -3387,62 +3285,55 @@ void NPC::DepopSwarmPets()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::ModifyStatsOnCharm(bool is_charm_removed)
|
void NPC::ModifyStatsOnCharm(bool remove_charm, Mob* charmer)
|
||||||
{
|
{
|
||||||
if (is_charm_removed) {
|
if (!remove_charm && parse->HasQuestSub(GetNPCTypeID(), EVENT_CHARM_START)) {
|
||||||
if (charm_ac) {
|
parse->EventNPC(EVENT_CHARM_START, this, charmer, "", 0);
|
||||||
AC = default_ac;
|
} else if (remove_charm && parse->HasQuestSub(GetNPCTypeID(), EVENT_CHARM_END)) {
|
||||||
|
parse->EventNPC(EVENT_CHARM_END, this, charmer, "", 0);
|
||||||
}
|
}
|
||||||
if (charm_attack_delay) {
|
|
||||||
attack_delay = default_attack_delay;
|
const int new_ac = remove_charm ? default_ac : charm_ac;
|
||||||
|
const int new_attack_delay = remove_charm ? default_attack_delay : charm_attack_delay;
|
||||||
|
const int new_accuracy_rating = remove_charm ? default_accuracy_rating : charm_accuracy_rating;
|
||||||
|
const int new_avoidance_rating = remove_charm ? default_avoidance_rating : charm_avoidance_rating;
|
||||||
|
const int new_atk = remove_charm ? default_atk : charm_atk;
|
||||||
|
const int new_min_dmg = remove_charm ? default_min_dmg : charm_min_dmg;
|
||||||
|
const int new_max_dmg = remove_charm ? default_max_dmg : charm_max_dmg;
|
||||||
|
|
||||||
|
if (new_ac) {
|
||||||
|
AC = new_ac;
|
||||||
}
|
}
|
||||||
if (charm_accuracy_rating) {
|
|
||||||
accuracy_rating = default_accuracy_rating;
|
if (new_attack_delay) {
|
||||||
|
attack_delay = new_attack_delay;
|
||||||
}
|
}
|
||||||
if (charm_avoidance_rating) {
|
|
||||||
avoidance_rating = default_avoidance_rating;
|
if (new_accuracy_rating) {
|
||||||
|
accuracy_rating = new_accuracy_rating;
|
||||||
}
|
}
|
||||||
if (charm_atk) {
|
|
||||||
ATK = default_atk;
|
if (new_avoidance_rating) {
|
||||||
|
avoidance_rating = new_avoidance_rating;
|
||||||
}
|
}
|
||||||
if (charm_min_dmg || charm_max_dmg) {
|
|
||||||
base_damage = round((default_max_dmg - default_min_dmg) / 1.9);
|
if (new_atk) {
|
||||||
min_damage = default_min_dmg - round(base_damage / 10.0);
|
ATK = new_atk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new_min_dmg || new_max_dmg) {
|
||||||
|
base_damage = std::round((new_max_dmg - new_min_dmg) / 1.9);
|
||||||
|
min_damage = new_min_dmg - std::round(base_damage / 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
if (RuleB(Spells, CharmDisablesSpecialAbilities)) {
|
if (RuleB(Spells, CharmDisablesSpecialAbilities)) {
|
||||||
|
if (remove_charm) {
|
||||||
ProcessSpecialAbilities(default_special_abilities);
|
ProcessSpecialAbilities(default_special_abilities);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
SetAttackTimer();
|
|
||||||
CalcAC();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (charm_ac) {
|
|
||||||
AC = charm_ac;
|
|
||||||
}
|
|
||||||
if (charm_attack_delay) {
|
|
||||||
attack_delay = charm_attack_delay;
|
|
||||||
}
|
|
||||||
if (charm_accuracy_rating) {
|
|
||||||
accuracy_rating = charm_accuracy_rating;
|
|
||||||
}
|
|
||||||
if (charm_avoidance_rating) {
|
|
||||||
avoidance_rating = charm_avoidance_rating;
|
|
||||||
}
|
|
||||||
if (charm_atk) {
|
|
||||||
ATK = charm_atk;
|
|
||||||
}
|
|
||||||
if (charm_min_dmg || charm_max_dmg) {
|
|
||||||
base_damage = round((charm_max_dmg - charm_min_dmg) / 1.9);
|
|
||||||
min_damage = charm_min_dmg - round(base_damage / 10.0);
|
|
||||||
}
|
|
||||||
if (RuleB(Spells, CharmDisablesSpecialAbilities)) {
|
|
||||||
ClearSpecialAbilities();
|
ClearSpecialAbilities();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// the rest of the stats aren't cached, so lets just do these two instead of full CalcBonuses()
|
|
||||||
SetAttackTimer();
|
SetAttackTimer();
|
||||||
CalcAC();
|
CalcAC();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -346,7 +346,7 @@ public:
|
|||||||
int64 GetNPCHPRegen() const { return hp_regen + itembonuses.HPRegen + spellbonuses.HPRegen; }
|
int64 GetNPCHPRegen() const { return hp_regen + itembonuses.HPRegen + spellbonuses.HPRegen; }
|
||||||
inline const char* GetAmmoIDfile() const { return ammo_idfile; }
|
inline const char* GetAmmoIDfile() const { return ammo_idfile; }
|
||||||
|
|
||||||
void ModifyStatsOnCharm(bool is_charm_removed);
|
void ModifyStatsOnCharm(bool remove_charm, Mob* charmer);
|
||||||
|
|
||||||
//waypoint crap
|
//waypoint crap
|
||||||
int GetMaxWp() const { return max_wp; }
|
int GetMaxWp() const { return max_wp; }
|
||||||
|
|||||||
+12
-4
@@ -61,6 +61,7 @@ void Client::SendBulkParcels()
|
|||||||
inst->SetCharges(p.second.quantity);
|
inst->SetCharges(p.second.quantity);
|
||||||
inst->SetMerchantCount(1);
|
inst->SetMerchantCount(1);
|
||||||
inst->SetMerchantSlot(p.second.slot_id);
|
inst->SetMerchantSlot(p.second.slot_id);
|
||||||
|
inst->SetEvolveCurrentAmount(p.second.evolve_amount);
|
||||||
if (inst->IsStackable()) {
|
if (inst->IsStackable()) {
|
||||||
inst->SetCharges(p.second.quantity);
|
inst->SetCharges(p.second.quantity);
|
||||||
}
|
}
|
||||||
@@ -164,6 +165,7 @@ void Client::SendParcel(Parcel_Struct &parcel_in)
|
|||||||
inst->SetCharges(p.quantity);
|
inst->SetCharges(p.quantity);
|
||||||
inst->SetMerchantCount(1);
|
inst->SetMerchantCount(1);
|
||||||
inst->SetMerchantSlot(p.slot_id);
|
inst->SetMerchantSlot(p.slot_id);
|
||||||
|
inst->SetEvolveCurrentAmount(p.evolve_amount);
|
||||||
if (inst->IsStackable()) {
|
if (inst->IsStackable()) {
|
||||||
inst->SetCharges(p.quantity);
|
inst->SetCharges(p.quantity);
|
||||||
}
|
}
|
||||||
@@ -381,12 +383,11 @@ void Client::DoParcelSend(const Parcel_Struct *parcel_in)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 quantity{};
|
uint32 quantity = 1;
|
||||||
if (inst->IsStackable()) {
|
if (inst->IsStackable()) {
|
||||||
quantity = parcel_in->quantity;
|
quantity = parcel_in->quantity;
|
||||||
}
|
} else if (inst->GetItem()->MaxCharges > 0) {
|
||||||
else {
|
quantity = inst->GetCharges();
|
||||||
quantity = inst->GetCharges() >= 0 ? inst->GetCharges() : parcel_in->quantity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CharacterParcelsRepository::CharacterParcels parcel_out{};
|
CharacterParcelsRepository::CharacterParcels parcel_out{};
|
||||||
@@ -397,6 +398,7 @@ void Client::DoParcelSend(const Parcel_Struct *parcel_in)
|
|||||||
parcel_out.item_id = inst->GetID();
|
parcel_out.item_id = inst->GetID();
|
||||||
parcel_out.char_id = send_to_client.at(0).char_id;
|
parcel_out.char_id = send_to_client.at(0).char_id;
|
||||||
parcel_out.slot_id = next_slot;
|
parcel_out.slot_id = next_slot;
|
||||||
|
parcel_out.evolve_amount = inst->GetEvolveCurrentAmount();
|
||||||
parcel_out.id = 0;
|
parcel_out.id = 0;
|
||||||
|
|
||||||
if (inst->IsAugmented()) {
|
if (inst->IsAugmented()) {
|
||||||
@@ -445,7 +447,9 @@ void Client::DoParcelSend(const Parcel_Struct *parcel_in)
|
|||||||
cpc.aug_slot_5 = augs.at(4);
|
cpc.aug_slot_5 = augs.at(4);
|
||||||
cpc.aug_slot_6 = augs.at(5);
|
cpc.aug_slot_6 = augs.at(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpc.quantity = kv.second->GetCharges() >= 0 ? kv.second->GetCharges() : 1;
|
cpc.quantity = kv.second->GetCharges() >= 0 ? kv.second->GetCharges() : 1;
|
||||||
|
cpc.evolve_amount = kv.second->GetEvolveCurrentAmount();
|
||||||
all_entries.push_back(cpc);
|
all_entries.push_back(cpc);
|
||||||
}
|
}
|
||||||
CharacterParcelsContainersRepository::InsertMany(database, all_entries);
|
CharacterParcelsContainersRepository::InsertMany(database, all_entries);
|
||||||
@@ -679,6 +683,8 @@ void Client::DoParcelRetrieve(const ParcelRetrieve_Struct &parcel_in)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inst->SetEvolveCurrentAmount(p->second.evolve_amount);
|
||||||
|
|
||||||
if (inst->IsStackable()) {
|
if (inst->IsStackable()) {
|
||||||
inst->SetCharges(item_quantity > 0 ? item_quantity : 1);
|
inst->SetCharges(item_quantity > 0 ? item_quantity : 1);
|
||||||
}
|
}
|
||||||
@@ -715,6 +721,8 @@ void Client::DoParcelRetrieve(const ParcelRetrieve_Struct &parcel_in)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item->SetEvolveCurrentAmount(i.evolve_amount);
|
||||||
|
|
||||||
if (CheckLoreConflict(item->GetItem())) {
|
if (CheckLoreConflict(item->GetItem())) {
|
||||||
if (RuleB(Parcel, DeleteOnDuplicate)) {
|
if (RuleB(Parcel, DeleteOnDuplicate)) {
|
||||||
MessageString(Chat::Yellow, PARCEL_DUPLICATE_DELETE, inst->GetItem()->Name);
|
MessageString(Chat::Yellow, PARCEL_DUPLICATE_DELETE, inst->GetItem()->Name);
|
||||||
|
|||||||
@@ -835,12 +835,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
SendAppearancePacket(AppearanceType::Pet, caster->GetID(), true, true);
|
SendAppearancePacket(AppearanceType::Pet, caster->GetID(), true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsClient())
|
if (IsClient()) {
|
||||||
{
|
|
||||||
CastToClient()->AI_Start();
|
CastToClient()->AI_Start();
|
||||||
} else if (IsNPC()) {
|
} else if (IsNPC()) {
|
||||||
CastToNPC()->SetPetSpellID(0); //not a pet spell.
|
CastToNPC()->SetPetSpellID(0); //not a pet spell.
|
||||||
CastToNPC()->ModifyStatsOnCharm(false);
|
CastToNPC()->ModifyStatsOnCharm(false, caster);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bBreak = false;
|
bool bBreak = false;
|
||||||
@@ -4418,10 +4417,9 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
|||||||
|
|
||||||
case SpellEffect::Charm:
|
case SpellEffect::Charm:
|
||||||
{
|
{
|
||||||
if(IsNPC())
|
if (IsNPC()) {
|
||||||
{
|
|
||||||
CastToNPC()->RestoreGuardSpotCharm();
|
CastToNPC()->RestoreGuardSpotCharm();
|
||||||
CastToNPC()->ModifyStatsOnCharm(true);
|
CastToNPC()->ModifyStatsOnCharm(true, GetOwner());
|
||||||
}
|
}
|
||||||
|
|
||||||
SendAppearancePacket(AppearanceType::Pet, 0, true, true);
|
SendAppearancePacket(AppearanceType::Pet, 0, true, true);
|
||||||
|
|||||||
Reference in New Issue
Block a user