mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-15 17:02:26 +00:00
(RoF2) *Hopefully* Fixed looting incorrect items from NPCs. Please report any issues!
(RoF2) Now able to loot items past the 10th slot on NPC corpses. Attuned Items can now be auto-looted and will equip properly. Mercenaries and Bots will no longer take a share from /split or /autosplit.
This commit is contained in:
parent
f0d2fb796f
commit
3c6c5b9732
@ -1,5 +1,11 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 01/02/2015 ==
|
||||||
|
Trevius: (RoF2) *Hopefully* Fixed looting incorrect items from NPCs. Please report any issues!
|
||||||
|
Trevius: (RoF2) Now able to loot items past the 10th slot on NPC corpses.
|
||||||
|
Trevius: Attuned Items can now be auto-looted and will equip properly.
|
||||||
|
Trevius: Mercenaries and Bots will no longer take a share from /split or /autosplit.
|
||||||
|
|
||||||
== 12/30/2014 ==
|
== 12/30/2014 ==
|
||||||
Trevius: (RoF2) Aug Type 21 no longer shows the "Buy Now" button in the aug slot of items.
|
Trevius: (RoF2) Aug Type 21 no longer shows the "Buy Now" button in the aug slot of items.
|
||||||
Trevius: (RoF2) Identified the "Copied" item flag with the help of Uleat.
|
Trevius: (RoF2) Identified the "Copied" item flag with the help of Uleat.
|
||||||
|
|||||||
@ -1509,7 +1509,8 @@ enum ItemPacketType
|
|||||||
ItemPacketTributeItem = 0x6C,
|
ItemPacketTributeItem = 0x6C,
|
||||||
ItemPacketMerchant = 0x64,
|
ItemPacketMerchant = 0x64,
|
||||||
ItemPacketWorldContainer = 0x6B,
|
ItemPacketWorldContainer = 0x6B,
|
||||||
ItemPacketCharmUpdate = 0x6E
|
ItemPacketCharmUpdate = 0x6E,
|
||||||
|
ItemPacketInvalid = 0xFF
|
||||||
};
|
};
|
||||||
struct ItemPacket_Struct
|
struct ItemPacket_Struct
|
||||||
{
|
{
|
||||||
|
|||||||
@ -5485,7 +5485,6 @@ namespace RoF
|
|||||||
|
|
||||||
static inline uint32 ServerToRoFCorpseSlot(uint32 ServerCorpse)
|
static inline uint32 ServerToRoFCorpseSlot(uint32 ServerCorpse)
|
||||||
{
|
{
|
||||||
//uint32 RoFCorpse;
|
|
||||||
return (ServerCorpse + 1);
|
return (ServerCorpse + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5626,7 +5625,6 @@ namespace RoF
|
|||||||
|
|
||||||
static inline uint32 RoFToServerCorpseSlot(uint32 RoFCorpse)
|
static inline uint32 RoFToServerCorpseSlot(uint32 RoFCorpse)
|
||||||
{
|
{
|
||||||
//uint32 ServerCorpse;
|
|
||||||
return (RoFCorpse - 1);
|
return (RoFCorpse - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,15 +21,15 @@ namespace RoF2
|
|||||||
static OpcodeManager *opcodes = nullptr;
|
static OpcodeManager *opcodes = nullptr;
|
||||||
static Strategy struct_strategy;
|
static Strategy struct_strategy;
|
||||||
|
|
||||||
char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth);
|
char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth, ItemPacketType packet_type);
|
||||||
|
|
||||||
// server to client inventory location converters
|
// server to client inventory location converters
|
||||||
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot);
|
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot, ItemPacketType PacketType = ItemPacketInvalid);
|
||||||
static inline structs::MainInvItemSlotStruct ServerToRoF2MainInvSlot(uint32 ServerSlot);
|
static inline structs::MainInvItemSlotStruct ServerToRoF2MainInvSlot(uint32 ServerSlot);
|
||||||
static inline uint32 ServerToRoF2CorpseSlot(uint32 ServerCorpse);
|
static inline uint32 ServerToRoF2CorpseSlot(uint32 ServerCorpse);
|
||||||
|
|
||||||
// client to server inventory location converters
|
// client to server inventory location converters
|
||||||
static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot);
|
static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot, ItemPacketType PacketType = ItemPacketInvalid);
|
||||||
static inline uint32 RoF2ToServerMainInvSlot(structs::MainInvItemSlotStruct RoF2Slot);
|
static inline uint32 RoF2ToServerMainInvSlot(structs::MainInvItemSlotStruct RoF2Slot);
|
||||||
static inline uint32 RoF2ToServerCorpseSlot(uint32 RoF2Corpse);
|
static inline uint32 RoF2ToServerCorpseSlot(uint32 RoF2Corpse);
|
||||||
|
|
||||||
@ -622,7 +622,7 @@ namespace RoF2
|
|||||||
|
|
||||||
uint32 Length = 0;
|
uint32 Length = 0;
|
||||||
|
|
||||||
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0);
|
char* Serialized = SerializeItem((const ItemInst*)eq->inst, eq->slot_id, &Length, 0, ItemPacketCharInventory);
|
||||||
|
|
||||||
if (Serialized) {
|
if (Serialized) {
|
||||||
|
|
||||||
@ -1436,7 +1436,7 @@ namespace RoF2
|
|||||||
InternalSerializedItem_Struct *int_struct = (InternalSerializedItem_Struct *)(old_item_pkt->SerializedItem);
|
InternalSerializedItem_Struct *int_struct = (InternalSerializedItem_Struct *)(old_item_pkt->SerializedItem);
|
||||||
|
|
||||||
uint32 length;
|
uint32 length;
|
||||||
char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0);
|
char *serialized = SerializeItem((ItemInst *)int_struct->inst, int_struct->slot_id, &length, 0, old_item_pkt->PacketType);
|
||||||
|
|
||||||
if (!serialized) {
|
if (!serialized) {
|
||||||
_log(NET__STRUCTS, "Serialization failed on item slot %d.", int_struct->slot_id);
|
_log(NET__STRUCTS, "Serialization failed on item slot %d.", int_struct->slot_id);
|
||||||
@ -4867,7 +4867,7 @@ namespace RoF2
|
|||||||
return NextItemInstSerialNumber;
|
return NextItemInstSerialNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth)
|
char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth, ItemPacketType packet_type)
|
||||||
{
|
{
|
||||||
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||||
uint8 null_term = 0;
|
uint8 null_term = 0;
|
||||||
@ -4891,7 +4891,7 @@ namespace RoF2
|
|||||||
hdr.stacksize = stackable ? charges : 1;
|
hdr.stacksize = stackable ? charges : 1;
|
||||||
hdr.unknown004 = 0;
|
hdr.unknown004 = 0;
|
||||||
|
|
||||||
structs::ItemSlotStruct slot_id = ServerToRoF2Slot(slot_id_in);
|
structs::ItemSlotStruct slot_id = ServerToRoF2Slot(slot_id_in, packet_type);
|
||||||
|
|
||||||
hdr.slot_type = (merchant_slot == 0) ? slot_id.SlotType : 9; // 9 is merchant 20 is reclaim items?
|
hdr.slot_type = (merchant_slot == 0) ? slot_id.SlotType : 9; // 9 is merchant 20 is reclaim items?
|
||||||
hdr.main_slot = (merchant_slot == 0) ? slot_id.MainSlot : merchant_slot;
|
hdr.main_slot = (merchant_slot == 0) ? slot_id.MainSlot : merchant_slot;
|
||||||
@ -5396,7 +5396,7 @@ namespace RoF2
|
|||||||
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
|
SubSlotNumber = Inventory::CalcSlotID(slot_id_in, x);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1);
|
SubSerializations[x] = SerializeItem(subitem, SubSlotNumber, &SubLengths[x], depth + 1, packet_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5422,7 +5422,7 @@ namespace RoF2
|
|||||||
return item_serial;
|
return item_serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot)
|
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot, ItemPacketType PacketType)
|
||||||
{
|
{
|
||||||
structs::ItemSlotStruct RoF2Slot;
|
structs::ItemSlotStruct RoF2Slot;
|
||||||
RoF2Slot.SlotType = INVALID_INDEX;
|
RoF2Slot.SlotType = INVALID_INDEX;
|
||||||
@ -5435,13 +5435,21 @@ namespace RoF2
|
|||||||
uint32 TempSlot = 0;
|
uint32 TempSlot = 0;
|
||||||
|
|
||||||
if (ServerSlot < 56 || ServerSlot == MainPowerSource) { // Main Inventory and Cursor
|
if (ServerSlot < 56 || ServerSlot == MainPowerSource) { // Main Inventory and Cursor
|
||||||
RoF2Slot.SlotType = maps::MapPossessions;
|
if (PacketType == ItemPacketLoot)
|
||||||
RoF2Slot.MainSlot = ServerSlot;
|
{
|
||||||
|
RoF2Slot.SlotType = maps::MapCorpse;
|
||||||
|
RoF2Slot.MainSlot = ServerSlot - EmuConstants::CORPSE_BEGIN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RoF2Slot.SlotType = maps::MapPossessions;
|
||||||
|
RoF2Slot.MainSlot = ServerSlot;
|
||||||
|
}
|
||||||
|
|
||||||
if (ServerSlot == MainPowerSource)
|
if (ServerSlot == MainPowerSource)
|
||||||
RoF2Slot.MainSlot = slots::MainPowerSource;
|
RoF2Slot.MainSlot = slots::MainPowerSource;
|
||||||
|
|
||||||
else if (ServerSlot >= MainCursor) // Cursor and Extended Corpse Inventory
|
else if (ServerSlot >= MainCursor && PacketType != ItemPacketLoot) // Cursor and Extended Corpse Inventory
|
||||||
RoF2Slot.MainSlot += 3;
|
RoF2Slot.MainSlot += 3;
|
||||||
|
|
||||||
else if (ServerSlot >= MainAmmo) // (> 20)
|
else if (ServerSlot >= MainAmmo) // (> 20)
|
||||||
@ -5568,11 +5576,10 @@ namespace RoF2
|
|||||||
|
|
||||||
static inline uint32 ServerToRoF2CorpseSlot(uint32 ServerCorpse)
|
static inline uint32 ServerToRoF2CorpseSlot(uint32 ServerCorpse)
|
||||||
{
|
{
|
||||||
//uint32 RoF2Corpse;
|
return (ServerCorpse - EmuConstants::CORPSE_BEGIN + 1);
|
||||||
return (ServerCorpse + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot)
|
static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot, ItemPacketType PacketType)
|
||||||
{
|
{
|
||||||
uint32 ServerSlot = INVALID_INDEX;
|
uint32 ServerSlot = INVALID_INDEX;
|
||||||
uint32 TempSlot = 0;
|
uint32 TempSlot = 0;
|
||||||
@ -5667,6 +5674,10 @@ namespace RoF2
|
|||||||
ServerSlot = INVALID_INDEX;
|
ServerSlot = INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (RoF2Slot.SlotType == maps::MapCorpse) {
|
||||||
|
ServerSlot = RoF2Slot.MainSlot + EmuConstants::CORPSE_BEGIN;
|
||||||
|
}
|
||||||
|
|
||||||
_log(NET__ERROR, "Convert RoF2 Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", RoF2Slot.SlotType, RoF2Slot.Unknown02, RoF2Slot.MainSlot, RoF2Slot.SubSlot, RoF2Slot.AugSlot, RoF2Slot.Unknown01, ServerSlot);
|
_log(NET__ERROR, "Convert RoF2 Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", RoF2Slot.SlotType, RoF2Slot.Unknown02, RoF2Slot.MainSlot, RoF2Slot.SubSlot, RoF2Slot.AugSlot, RoF2Slot.Unknown01, ServerSlot);
|
||||||
|
|
||||||
return ServerSlot;
|
return ServerSlot;
|
||||||
@ -5709,8 +5720,7 @@ namespace RoF2
|
|||||||
|
|
||||||
static inline uint32 RoF2ToServerCorpseSlot(uint32 RoF2Corpse)
|
static inline uint32 RoF2ToServerCorpseSlot(uint32 RoF2Corpse)
|
||||||
{
|
{
|
||||||
//uint32 ServerCorpse;
|
return (RoF2Corpse + EmuConstants::CORPSE_BEGIN - 1);
|
||||||
return (RoF2Corpse - 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// end namespace RoF2
|
// end namespace RoF2
|
||||||
|
|||||||
@ -1843,8 +1843,8 @@ struct LootingItem_Struct {
|
|||||||
/*000*/ uint32 lootee;
|
/*000*/ uint32 lootee;
|
||||||
/*004*/ uint32 looter;
|
/*004*/ uint32 looter;
|
||||||
/*008*/ uint16 slot_id;
|
/*008*/ uint16 slot_id;
|
||||||
/*010*/ uint16 unknown10;
|
/*010*/ uint16 unknown10; // slot_id is probably uint32
|
||||||
/*012*/ uint32 auto_loot;
|
/*012*/ int32 auto_loot;
|
||||||
/*016*/ uint32 unknown16;
|
/*016*/ uint32 unknown16;
|
||||||
/*020*/
|
/*020*/
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9170,12 +9170,6 @@ void Client::Handle_OP_LootItem(const EQApplicationPacket *app)
|
|||||||
LogFile->write(EQEMuLog::Error, "Wrong size: OP_LootItem, size=%i, expected %i", app->size, sizeof(LootingItem_Struct));
|
LogFile->write(EQEMuLog::Error, "Wrong size: OP_LootItem, size=%i, expected %i", app->size, sizeof(LootingItem_Struct));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
** fixed the looting code so that it sends the correct opcodes
|
|
||||||
** and now correctly removes the looted item the player selected
|
|
||||||
** as well as gives the player the proper item.
|
|
||||||
** Also fixed a few UI lock ups that would occur.
|
|
||||||
*/
|
|
||||||
|
|
||||||
EQApplicationPacket* outapp = 0;
|
EQApplicationPacket* outapp = 0;
|
||||||
Entity* entity = entity_list.GetID(*((uint16*)app->pBuffer));
|
Entity* entity = entity_list.GetID(*((uint16*)app->pBuffer));
|
||||||
|
|||||||
@ -1207,7 +1207,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
|
|||||||
parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args);
|
parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args);
|
||||||
parse->EventItem(EVENT_LOOT, client, inst, this, buf, 0);
|
parse->EventItem(EVENT_LOOT, client, inst, this, buf, 0);
|
||||||
|
|
||||||
if ((RuleB(Character, EnableDiscoveredItems))) {
|
if (!IsPlayerCorpse() && RuleB(Character, EnableDiscoveredItems)) {
|
||||||
if (client && !client->GetGM() && !client->IsDiscovered(inst->GetItem()->ID))
|
if (client && !client->GetGM() && !client->IsDiscovered(inst->GetItem()->ID))
|
||||||
client->DiscoverItem(inst->GetItem()->ID);
|
client->DiscoverItem(inst->GetItem()->ID);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -122,7 +122,8 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu
|
|||||||
uint32 i;
|
uint32 i;
|
||||||
uint8 membercount = 0;
|
uint8 membercount = 0;
|
||||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||||
if (members[i] != nullptr) {
|
// Don't split with Mercs or Bots
|
||||||
|
if (members[i] != nullptr && members[i]->IsClient()) {
|
||||||
membercount++;
|
membercount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -926,7 +926,7 @@ bool Client::TryStacking(ItemInst* item, uint8 type, bool try_worn, bool try_cur
|
|||||||
bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_cursor, ServerLootItem_Struct** bag_item_data)
|
bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_cursor, ServerLootItem_Struct** bag_item_data)
|
||||||
{
|
{
|
||||||
// #1: Try to auto equip
|
// #1: Try to auto equip
|
||||||
if (try_worn && inst.IsEquipable(GetBaseRace(), GetClass()) && inst.GetItem()->ReqLevel<=level && !inst.GetItem()->Attuneable && inst.GetItem()->ItemType != ItemTypeAugmentation)
|
if (try_worn && inst.IsEquipable(GetBaseRace(), GetClass()) && inst.GetItem()->ReqLevel<=level && (!inst.GetItem()->Attuneable || inst.IsAttuned()) && inst.GetItem()->ItemType != ItemTypeAugmentation)
|
||||||
{
|
{
|
||||||
// too messy as-is... <watch>
|
// too messy as-is... <watch>
|
||||||
for (int16 i = EmuConstants::EQUIPMENT_BEGIN; i < MainPowerSource; i++) // originally (i < 22)
|
for (int16 i = EmuConstants::EQUIPMENT_BEGIN; i < MainPowerSource; i++) // originally (i < 22)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user