** Fix for RoF clients not displaying Augment Restrictions in the Item Info window.

** Change to Client::SummonItem() to enforce valid item/augment combinations. (Run the optional sql file first, before posting any
SummonItem() failure issues in the forums.)
This commit is contained in:
Uleat
2014-03-17 04:53:47 -04:00
parent 65e8c2ffde
commit 4170434b96
8 changed files with 460 additions and 107 deletions
+357 -104
View File
@@ -200,124 +200,377 @@ bool Client::CheckLoreConflict(const Item_Struct* item) {
return (m_inv.HasItemByLoreGroup(item->LoreGroup, ~invWhereSharedBank) != SLOT_INVALID);
}
void Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned, uint16 to_slot) {
bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned, uint16 to_slot) {
// I have 'over-logged' failure messages to aid in any troubleshooting of issues that arise from this change.
// The 'LogFile' code may be taken out once after a period of time with no script/recipe issues.
//
// I have also incorporated a bool return type..but, have not updated any calling methods to process failures.
// Once the APIs are updated, scripts may also be updated.
const Item_Struct* item = database.GetItem(item_id);
if (item == nullptr) {
Message(0, "No such item: %i", item_id);
return;
} else {
if(item == nullptr) {
Message(13, "Item %u does not exist.", item_id);
LogFile->write(EQEMuLog::Error, "Player %s on account %s attempted to create an item with an invalid id.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
account_name, GetName(), item->ID, aug1, aug2, aug3, aug4, aug5);
return false;
}
else {
// if the item is stackable and the charge amount is -1 or 0 then set to 1 charge.
// removed && item->MaxCharges == 0 if -1 or 0 was passed max charges is irrelevant
if (charges <= 0 && item->Stackable) {
if(charges <= 0 && item->Stackable)
charges = 1;
// if the charges is -1, then no charge value was passed in set to max charges
} else if(charges == -1) {
charges = item->MaxCharges;
// in any other situation just use charges as passed
}
}
// Checking to see if the Item is lore or not.
bool foundlore = CheckLoreConflict(item);
//TODO: check for lore conflict on augments
// if the charges is -1, then no charge value was passed in set to max charges
else if(charges == -1)
charges = item->MaxCharges;
// in any other situation just use charges as passed
}
// Base item is lore..so, cancel summon
if(CheckLoreConflict(item)) {
// this is the 'you can not pickup another...' message. I don't feel this is appropriate
// for a summoning failure response
// DuplicateLoreMessage(item_id);
Message(13, "You already have a lore %s (%i) in your inventory.", item->Name, item_id);
return false;
}
// Checking to see if it is a GM only Item or not.
//bool foundgm = (item->gm && (this->Admin() < 100));
bool foundgm = false;
/*
if(item->gm && (this->Admin() < 100))
Message(0, "You are not a GM and can not summon this item!");
if (!foundlore && !foundgm) { // Okay, It isn't LORE, or if it is, it is not in player's inventory.
ItemInst* inst = database.CreateItem(item, charges);
if (inst) {
// Corrected the augment references to reflect augment name/id instead of base item name/id
if (aug1) {
const Item_Struct* augitem1 = database.GetItem(aug1);
if (augitem1) {
if (!CheckLoreConflict(augitem1)) {
inst->PutAugment(&database, 0, aug1);
}
else {
Message(0, "You already have a %s (%u) in your inventory - Augment not added!", augitem1->Name, aug1);
}
}
}
if (aug2) {
const Item_Struct* augitem2 = database.GetItem(aug2);
if (augitem2) {
if (!CheckLoreConflict(augitem2)) {
inst->PutAugment(&database, 1, aug2);
}
else {
Message(0, "You already have a %s (%u) in your inventory - Augment not added!", augitem2->Name, aug2);
}
}
}
if (aug3) {
const Item_Struct* augitem3 = database.GetItem(aug3);
if (augitem3) {
if (!CheckLoreConflict(augitem3)) {
inst->PutAugment(&database, 2, aug3);
}
else {
Message(0, "You already have a %s (%u) in your inventory - Augment not added!", augitem3->Name, aug3);
}
}
}
if (aug4) {
const Item_Struct* augitem4 = database.GetItem(aug4);
if (augitem4) {
if (!CheckLoreConflict(augitem4)) {
inst->PutAugment(&database, 3, aug4);
}
else {
Message(0, "You already have a %s (%u) in your inventory - Augment not added!", augitem4->Name, aug4);
}
}
}
if (aug5) {
const Item_Struct* augitem5 = database.GetItem(aug5);
if (augitem5) {
if (!CheckLoreConflict(augitem5)) {
inst->PutAugment(&database, 4, aug5);
}
else {
Message(0, "You already have a %s (%u) in your inventory - Augment not added!", augitem5->Name, aug5);
}
}
}
if (attuned) {
if (inst->GetItem()->Attuneable) {
inst->SetInstNoDrop(true);
}
}
if (to_slot == SLOT_CURSOR)
{
//inst->SetCharges(
PushItemOnCursor(*inst);
// Send item packet to user
SendItemPacket(SLOT_CURSOR, inst, ItemPacketSummonItem);
}
else
{
PutItemInInventory(to_slot, *inst, true);
}
safe_delete(inst);
return false;
*/
if ((RuleB(Character, EnableDiscoveredItems)))
{
if(!GetGM() && !IsDiscovered(item_id))
DiscoverItem(item_id);
if(((item->ItemClass != ItemClassCommon) || (item->AugType > 0)) && (aug1 | aug2 | aug3 | aug4 | aug5)) {
Message(13, "You can not augment an augment or a non-common class item.");
LogFile->write(EQEMuLog::Error, "Player %s on account %s attempted to augment an augment or a non-common class item.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
account_name, GetName(), item->ID, aug1, aug2, aug3, aug4, aug5);
return false;
}
uint32 augments[MAX_AUGMENT_SLOTS] = { aug1, aug2, aug3, aug4, aug5 };
for(int iter = 0; iter < MAX_AUGMENT_SLOTS; ++iter) {
if(augments[iter] && (database.GetItem(augments[iter]) == nullptr)) {
Message(13, "Augment %u (Aug%i) does not exist.", augments[iter], iter + 1);
LogFile->write(EQEMuLog::Error, "Player %s on account %s attempted to create an augment (Aug%i) with an invalid id.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
account_name, GetName(), iter + 1, item->ID, aug1, aug2, aug3, aug4, aug5);
return false;
}
}
uint32 classes = item->Classes;
uint32 races = item->Races;
uint32 slots = item->Slots;
bool enforcewear = RuleB(Inventory, EnforceAugmentWear);
bool enforcerestr = RuleB(Inventory, EnforceAugmentRestriction);
bool enforceusable = RuleB(Inventory, EnforceAugmentUsability);
for(int iter = 0; iter < MAX_AUGMENT_SLOTS; ++iter) {
const Item_Struct* augtest = database.GetItem(augments[iter]);
if(augtest) {
if(CheckLoreConflict(augtest)) {
// ditto
// DuplicateLoreMessage(augtest->ID);
Message(13, "You already have a lore %s (%u) in your inventory.", augtest->Name, augtest->ID);
return false;
}
/*
if(augtest->gm && (this->Admin() < 100)) {
Message(0, "You are not a GM and can not summon this augment!");
return false;
}
*/
if(augtest->AugType == 0) {
Message(13, "%s (%u) (Aug%i) is not an actual augment.", augtest->Name, augtest->ID, iter + 1);
LogFile->write(EQEMuLog::Error, "Player %s on account %s attempted to use a non-augment item (Aug%i) as an augment.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
account_name, GetName(), item->ID, iter + 1, aug1, aug2, aug3, aug4, aug5);
return false;
}
if(enforcewear) {
if((item->AugSlotType[iter] == AugTypeNone) || !(((uint32)1 << (item->AugSlotType[iter] - 1)) & augtest->AugType)) {
Message(13, "Augment %u (Aug%i) is not allowed wear on Item %u.", augments[iter], iter + 1, item->ID);
LogFile->write(EQEMuLog::Error, "Player %s on account %s attempted to augment an item with a disallowed augment type (Aug%i).\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
account_name, GetName(), iter + 1, item->ID, aug1, aug2, aug3, aug4, aug5);
return false;
}
}
if(enforcerestr) {
bool restrictfail = false;
uint8 it = item->ItemType;
switch(augtest->AugRestrict) {
case AugRestrAny:
break;
case AugRestrArmor:
switch(it) {
case ItemTypeArmor:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestrWeapons:
switch(it) {
case ItemType1HSlash:
case ItemType1HBlunt:
case ItemType1HPiercing:
case ItemTypeMartial:
case ItemType2HSlash:
case ItemType2HBlunt:
case ItemType2HPiercing:
case ItemTypeBow:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestr1HWeapons:
switch(it) {
case ItemType1HSlash:
case ItemType1HBlunt:
case ItemType1HPiercing:
case ItemTypeMartial:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestr2HWeapons:
switch(it) {
case ItemType2HSlash:
case ItemType2HBlunt:
case ItemType2HPiercing:
case ItemTypeBow:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestr1HSlash:
switch(it) {
case ItemType1HSlash:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestr1HBlunt:
switch(it) {
case ItemType1HBlunt:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestrPiercing:
switch(it) {
case ItemType1HPiercing:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestrHandToHand:
switch(it) {
case ItemTypeMartial:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestr2HSlash:
switch(it) {
case ItemType2HSlash:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestr2HBlunt:
switch(it) {
case ItemType2HBlunt:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestr2HPierce:
switch(it) {
case ItemType2HPiercing:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestrBows:
switch(it) {
case ItemTypeBow:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestrShields:
switch(it) {
case ItemTypeShield:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestr1HSlash1HBluntOrHandToHand:
switch(it) {
case ItemType1HSlash:
case ItemType1HBlunt:
case ItemTypeMartial:
break;
default:
restrictfail = true;
break;
}
break;
case AugRestr1HBluntOrHandToHand:
switch(it) {
case ItemType1HBlunt:
case ItemTypeMartial:
break;
default:
restrictfail = true;
break;
}
break;
// These 3 are in-work
case AugRestrUnknown1:
case AugRestrUnknown2:
case AugRestrUnknown3:
default:
restrictfail = true;
break;
}
if(restrictfail) {
Message(13, "Augment %u (Aug%i) is restricted from wear on Item %u.", augments[iter], iter + 1, item->ID);
LogFile->write(EQEMuLog::Error, "Player %s on account %s attempted to augment an item with a restricted augment (Aug%i).\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
account_name, GetName(), iter + 1, item->ID, aug1, aug2, aug3, aug4, aug5);
return false;
}
}
if(enforceusable) {
classes &= augtest->Classes;
if(item->Classes && !classes) {
Message(13, "Augment %u (Aug%i) will result in an item not usable by any class.", augments[iter], iter + 1);
LogFile->write(EQEMuLog::Error, "Player %s on account %s attempted to create an item unusable by any class.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
account_name, GetName(), item->ID, aug1, aug2, aug3, aug4, aug5);
return false;
}
races &= augtest->Races;
if(item->Races && !races) {
Message(13, "Augment %u (Aug%i) will result in an item not usable by any race.", augments[iter], iter + 1);
LogFile->write(EQEMuLog::Error, "Player %s on account %s attempted to create an item unusable by any race.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
account_name, GetName(), item->ID, aug1, aug2, aug3, aug4, aug5);
return false;
}
slots &= augtest->Slots;
if(item->Slots && !slots) {
Message(13, "Augment %u (Aug%i) will result in an item not usable in any slot.", augments[iter], iter + 1);
LogFile->write(EQEMuLog::Error, "Player %s on account %s attempted to create an item unusable in any slot.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
account_name, GetName(), item->ID, aug1, aug2, aug3, aug4, aug5);
return false;
}
}
}
}
else { // Item was already in inventory & is a LORE item or was a GM only item. Give them a message about it.
if (foundlore){
DuplicateLoreMessage(item_id);
//Message(0, "You already have a %s (%i) in your inventory!", item->Name, item_id);
}
else if (foundgm)
Message(0, "You are not a GM to summon this item");
// Item is not lore..
// Item is not GM-Only..
// Augments are valid and match allowed slots..
// ..or Augments are valid and do not match allowed slots and..
// ..EnforceAugmentWear=false and EnforceAugmentRestriction=false and EnforceAugmentUsability=false
ItemInst* inst = database.CreateItem(item, charges);
if(inst == nullptr) {
Message(13, "An unknown server error has occurred and your item was not created.");
LogFile->write(EQEMuLog::Error, "Player %s on account %s encountered an unknown item creation error.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
account_name, GetName(), item->ID, aug1, aug2, aug3, aug4, aug5);
return false;
}
for(int iter = 0; iter < MAX_AUGMENT_SLOTS; ++iter) {
if(augments[iter])
inst->PutAugment(&database, iter, augments[iter]);
}
// This may need augment checks as well..left out for now
if(attuned && inst->GetItem()->Attuneable)
inst->SetInstNoDrop(true);
if(to_slot == SLOT_CURSOR) {
//inst->SetCharges(
PushItemOnCursor(*inst);
// Send item packet to user
SendItemPacket(SLOT_CURSOR, inst, ItemPacketSummonItem);
}
else {
PutItemInInventory(to_slot, *inst, true);
}
safe_delete(inst);
if((RuleB(Character, EnableDiscoveredItems)) && !GetGM()) {
if(!IsDiscovered(item_id))
DiscoverItem(item_id);
for(int iter = 0; iter < MAX_AUGMENT_SLOTS; ++iter) {
if(augments[iter] && !IsDiscovered(augments[iter]))
DiscoverItem(augments[iter]);
}
}
return true;
}
// Drop item from inventory to ground (generally only dropped from SLOT_CURSOR)