mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-24 05:18:40 +00:00
Implemented rule-based disenchanted bag use
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 06/07/2015 ==
|
||||||
|
Uleat: Implemented optional rule for using disenchanted bags. Action triggers at the same point that temporary items are removed.
|
||||||
|
Optional SQL: utils/sql/git/optional/2015_06_07_TransformSummonedBagsRule.sql
|
||||||
|
|
||||||
== 05/25/2015 ==
|
== 05/25/2015 ==
|
||||||
Akkadius: Implemented disjointed zone based time, this can be triggered via quest methods
|
Akkadius: Implemented disjointed zone based time, this can be triggered via quest methods
|
||||||
|
|||||||
@@ -611,6 +611,7 @@ RULE_BOOL ( Inventory, EnforceAugmentUsability, true) // Forces augmented item u
|
|||||||
RULE_BOOL ( Inventory, EnforceAugmentWear, true) // Forces augment wear slot validation
|
RULE_BOOL ( Inventory, EnforceAugmentWear, true) // Forces augment wear slot validation
|
||||||
RULE_BOOL ( Inventory, DeleteTransformationMold, true) //False if you want mold to last forever
|
RULE_BOOL ( Inventory, DeleteTransformationMold, true) //False if you want mold to last forever
|
||||||
RULE_BOOL ( Inventory, AllowAnyWeaponTransformation, false) //Weapons can use any weapon transformation
|
RULE_BOOL ( Inventory, AllowAnyWeaponTransformation, false) //Weapons can use any weapon transformation
|
||||||
|
RULE_BOOL ( Inventory, TransformSummonedBags, false) //Transforms summoned bags into disenchanted ones instead of deleting
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY( Client )
|
RULE_CATEGORY( Client )
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Inventory:EnforceAugmentRestriction', 'false', 'Forces augment slot restrictions.');
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Inventory:EnforceAugmentRestriction', 'false', 'Forces augment slot restrictions.');
|
||||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Inventory:EnforceAugmentUsability', 'false', 'Forces augmented item usability.');
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Inventory:EnforceAugmentUsability', 'false', 'Forces augmented item usability.');
|
||||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Inventory:EnforceAugmentWear', 'false', 'Forces augment wear slot validation.');
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Inventory:EnforceAugmentWear', 'false', 'Forces augment wear slot validation.');
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Inventory:TransformSummonedBags', 'true', 'Transforms summoned bags into disenchanted ones instead of deleting.');
|
||||||
@@ -906,6 +906,7 @@ public:
|
|||||||
bool DecreaseByID(uint32 type, uint8 amt);
|
bool DecreaseByID(uint32 type, uint8 amt);
|
||||||
uint8 SlotConvert2(uint8 slot); //Maybe not needed.
|
uint8 SlotConvert2(uint8 slot); //Maybe not needed.
|
||||||
void Escape(); //AA Escape
|
void Escape(); //AA Escape
|
||||||
|
void DisenchantSummonedBags(bool client_update = true);
|
||||||
void RemoveNoRent(bool client_update = true);
|
void RemoveNoRent(bool client_update = true);
|
||||||
void RemoveDuplicateLore(bool client_update = true);
|
void RemoveDuplicateLore(bool client_update = true);
|
||||||
void MoveSlotNotAllowed(bool client_update = true);
|
void MoveSlotNotAllowed(bool client_update = true);
|
||||||
|
|||||||
@@ -838,7 +838,11 @@ void Client::BulkSendInventoryItems() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool deletenorent = database.NoRentExpired(GetName());
|
bool deletenorent = database.NoRentExpired(GetName());
|
||||||
if(deletenorent){ RemoveNoRent(false); } //client was offline for more than 30 minutes, delete no rent items
|
if (deletenorent) { //client was offline for more than 30 minutes, delete no rent items
|
||||||
|
if (RuleB(Inventory, TransformSummonedBags))
|
||||||
|
DisenchantSummonedBags(false);
|
||||||
|
RemoveNoRent(false);
|
||||||
|
}
|
||||||
|
|
||||||
RemoveDuplicateLore(false);
|
RemoveDuplicateLore(false);
|
||||||
MoveSlotNotAllowed(false);
|
MoveSlotNotAllowed(false);
|
||||||
|
|||||||
@@ -2158,6 +2158,187 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool IsSummonedBagID(uint32 item_id)
|
||||||
|
{
|
||||||
|
switch (item_id) {
|
||||||
|
case 17147: // "Spiritual Prismatic Pack"
|
||||||
|
case 17303: // "Spirit Pouch"
|
||||||
|
case 17304: // "Dimensional Pocket"
|
||||||
|
case 17305: // "Dimensional Hole"
|
||||||
|
case 17306: // "Glowing Backpack"
|
||||||
|
case 17307: // "Quiver of Marr"
|
||||||
|
case 17308: // "Bandoleer of Luclin"
|
||||||
|
case 17309: // "Pouch of Quellious"
|
||||||
|
case 17310: // "Phantom Satchel"
|
||||||
|
case 17510: // "Glowing Chest"
|
||||||
|
case 17900: // "Grandmaster's Satchel"
|
||||||
|
case 57260: // "Glowing Backpack"
|
||||||
|
case 57261: // "Pouch of Quellious"
|
||||||
|
case 57262: // "Phantom Satchel"
|
||||||
|
case 60224: // "Faded-Glyph Tablet"
|
||||||
|
case 95199: // "Beginner Artisan Satchel"
|
||||||
|
case 95200: // "Apprentice Artisan Satchel"
|
||||||
|
case 95201: // "Freshman Artisan Satchel"
|
||||||
|
case 95202: // "Journeyman Artisan Satchel"
|
||||||
|
case 95203: // "Expert Artisan Satchel"
|
||||||
|
case 95204: // "Master Artisan Satchel"
|
||||||
|
//case 96960: // "Artisan Satchel" - no 12-slot disenchanted bags
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32 GetDisenchantedBagID(uint8 bag_slots)
|
||||||
|
{
|
||||||
|
switch (bag_slots) {
|
||||||
|
case 4:
|
||||||
|
return 77772; // "Small Disenchanted Backpack"
|
||||||
|
case 6:
|
||||||
|
return 77774; // "Disenchanted Backpack"
|
||||||
|
case 8:
|
||||||
|
return 77776; // "Large Disenchanted Backpack"
|
||||||
|
case 10:
|
||||||
|
return 77778; // "Huge Disenchanted Backpack"
|
||||||
|
default:
|
||||||
|
return 0; // no suitable conversions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CopyBagContents(ItemInst* new_bag, const ItemInst* old_bag)
|
||||||
|
{
|
||||||
|
if (!new_bag || !old_bag) { return false; }
|
||||||
|
if (new_bag->GetItem()->BagSlots < old_bag->GetItem()->BagSlots) { return false; }
|
||||||
|
|
||||||
|
// pre-check for size comparisons
|
||||||
|
for (auto bag_slot = 0; bag_slot < old_bag->GetItem()->BagSlots; ++bag_slot) {
|
||||||
|
if (!old_bag->GetItem(bag_slot)) { continue; }
|
||||||
|
if (old_bag->GetItem(bag_slot)->GetItem()->Size > new_bag->GetItem()->BagSize) {
|
||||||
|
Log.Out(Logs::General, Logs::Inventory, "Copy Bag Contents: Failure due to %s is larger than size capacity of %s (%i > %i)",
|
||||||
|
old_bag->GetItem(bag_slot)->GetItem()->Name, new_bag->GetItem()->Name, old_bag->GetItem(bag_slot)->GetItem()->Size, new_bag->GetItem()->BagSize);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto bag_slot = 0; bag_slot < old_bag->GetItem()->BagSlots; ++bag_slot) {
|
||||||
|
if (!old_bag->GetItem(bag_slot)) { continue; }
|
||||||
|
new_bag->PutItem(bag_slot, *(old_bag->GetItem(bag_slot)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::DisenchantSummonedBags(bool client_update)
|
||||||
|
{
|
||||||
|
for (auto slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; ++slot_id) {
|
||||||
|
auto inst = m_inv[slot_id];
|
||||||
|
if (!inst) { continue; }
|
||||||
|
if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; }
|
||||||
|
if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; }
|
||||||
|
if (inst->GetTotalItemCount() == 1) { continue; }
|
||||||
|
|
||||||
|
auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots);
|
||||||
|
if (!new_id) { continue; }
|
||||||
|
auto new_item = database.GetItem(new_id);
|
||||||
|
if (!new_item) { continue; }
|
||||||
|
auto new_inst = database.CreateBaseItem(new_item);
|
||||||
|
if (!new_inst) { continue; }
|
||||||
|
|
||||||
|
if (CopyBagContents(new_inst, inst)) {
|
||||||
|
Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id);
|
||||||
|
PutItemInInventory(slot_id, *new_inst, client_update);
|
||||||
|
}
|
||||||
|
safe_delete(new_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; ++slot_id) {
|
||||||
|
auto inst = m_inv[slot_id];
|
||||||
|
if (!inst) { continue; }
|
||||||
|
if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; }
|
||||||
|
if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; }
|
||||||
|
if (inst->GetTotalItemCount() == 1) { continue; }
|
||||||
|
|
||||||
|
auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots);
|
||||||
|
if (!new_id) { continue; }
|
||||||
|
auto new_item = database.GetItem(new_id);
|
||||||
|
if (!new_item) { continue; }
|
||||||
|
auto new_inst = database.CreateBaseItem(new_item);
|
||||||
|
if (!new_inst) { continue; }
|
||||||
|
|
||||||
|
if (CopyBagContents(new_inst, inst)) {
|
||||||
|
Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id);
|
||||||
|
PutItemInInventory(slot_id, *new_inst, client_update);
|
||||||
|
}
|
||||||
|
safe_delete(new_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_END; ++slot_id) {
|
||||||
|
auto inst = m_inv[slot_id];
|
||||||
|
if (!inst) { continue; }
|
||||||
|
if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; }
|
||||||
|
if (inst->GetItem()->ItemClass != ItemClassContainer) { continue; }
|
||||||
|
if (inst->GetTotalItemCount() == 1) { continue; }
|
||||||
|
|
||||||
|
auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots);
|
||||||
|
if (!new_id) { continue; }
|
||||||
|
auto new_item = database.GetItem(new_id);
|
||||||
|
if (!new_item) { continue; }
|
||||||
|
auto new_inst = database.CreateBaseItem(new_item);
|
||||||
|
if (!new_inst) { continue; }
|
||||||
|
|
||||||
|
if (CopyBagContents(new_inst, inst)) {
|
||||||
|
Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, slot_id);
|
||||||
|
PutItemInInventory(slot_id, *new_inst, client_update);
|
||||||
|
}
|
||||||
|
safe_delete(new_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!m_inv.CursorEmpty()) {
|
||||||
|
auto inst = m_inv[MainCursor];
|
||||||
|
if (!inst) { break; }
|
||||||
|
if (!IsSummonedBagID(inst->GetItem()->ID)) { break; }
|
||||||
|
if (inst->GetItem()->ItemClass != ItemClassContainer) { break; }
|
||||||
|
if (inst->GetTotalItemCount() == 1) { break; }
|
||||||
|
|
||||||
|
auto new_id = GetDisenchantedBagID(inst->GetItem()->BagSlots);
|
||||||
|
if (!new_id) { break; }
|
||||||
|
auto new_item = database.GetItem(new_id);
|
||||||
|
if (!new_item) { break; }
|
||||||
|
auto new_inst = database.CreateBaseItem(new_item);
|
||||||
|
if (!new_inst) { break; }
|
||||||
|
|
||||||
|
if (CopyBagContents(new_inst, inst)) {
|
||||||
|
Log.Out(Logs::General, Logs::Inventory, "Disenchant Summoned Bags: Replacing %s with %s in slot %i", inst->GetItem()->Name, new_inst->GetItem()->Name, MainCursor);
|
||||||
|
std::list<ItemInst*> local;
|
||||||
|
local.push_front(new_inst);
|
||||||
|
m_inv.PopItem(MainCursor);
|
||||||
|
safe_delete(inst);
|
||||||
|
|
||||||
|
while (!m_inv.CursorEmpty()) {
|
||||||
|
auto limbo_inst = m_inv.PopItem(MainCursor);
|
||||||
|
if (limbo_inst == nullptr) { continue; }
|
||||||
|
local.push_back(limbo_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto iter = local.begin(); iter != local.end(); ++iter) {
|
||||||
|
auto cur_inst = *iter;
|
||||||
|
if (cur_inst == nullptr) { continue; }
|
||||||
|
m_inv.PushCursor(*cur_inst);
|
||||||
|
safe_delete(cur_inst);
|
||||||
|
}
|
||||||
|
local.clear();
|
||||||
|
|
||||||
|
auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend();
|
||||||
|
database.SaveCursor(this->CharacterID(), s, e);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
safe_delete(new_inst); // deletes disenchanted bag if not used
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Client::RemoveNoRent(bool client_update)
|
void Client::RemoveNoRent(bool client_update)
|
||||||
{
|
{
|
||||||
for (auto slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; ++slot_id) {
|
for (auto slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; ++slot_id) {
|
||||||
|
|||||||
Reference in New Issue
Block a user