mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-15 08:42: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)
|
||||
-------------------------------------------------------
|
||||
== 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 ==
|
||||
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.
|
||||
|
||||
@ -1509,7 +1509,8 @@ enum ItemPacketType
|
||||
ItemPacketTributeItem = 0x6C,
|
||||
ItemPacketMerchant = 0x64,
|
||||
ItemPacketWorldContainer = 0x6B,
|
||||
ItemPacketCharmUpdate = 0x6E
|
||||
ItemPacketCharmUpdate = 0x6E,
|
||||
ItemPacketInvalid = 0xFF
|
||||
};
|
||||
struct ItemPacket_Struct
|
||||
{
|
||||
|
||||
@ -5485,7 +5485,6 @@ namespace RoF
|
||||
|
||||
static inline uint32 ServerToRoFCorpseSlot(uint32 ServerCorpse)
|
||||
{
|
||||
//uint32 RoFCorpse;
|
||||
return (ServerCorpse + 1);
|
||||
}
|
||||
|
||||
@ -5626,7 +5625,6 @@ namespace RoF
|
||||
|
||||
static inline uint32 RoFToServerCorpseSlot(uint32 RoFCorpse)
|
||||
{
|
||||
//uint32 ServerCorpse;
|
||||
return (RoFCorpse - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,15 +21,15 @@ namespace RoF2
|
||||
static OpcodeManager *opcodes = nullptr;
|
||||
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
|
||||
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 uint32 ServerToRoF2CorpseSlot(uint32 ServerCorpse);
|
||||
|
||||
// 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 RoF2ToServerCorpseSlot(uint32 RoF2Corpse);
|
||||
|
||||
@ -622,7 +622,7 @@ namespace RoF2
|
||||
|
||||
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) {
|
||||
|
||||
@ -1436,7 +1436,7 @@ namespace RoF2
|
||||
InternalSerializedItem_Struct *int_struct = (InternalSerializedItem_Struct *)(old_item_pkt->SerializedItem);
|
||||
|
||||
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) {
|
||||
_log(NET__STRUCTS, "Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
@ -4867,7 +4867,7 @@ namespace RoF2
|
||||
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);
|
||||
uint8 null_term = 0;
|
||||
@ -4891,7 +4891,7 @@ namespace RoF2
|
||||
hdr.stacksize = stackable ? charges : 1;
|
||||
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.main_slot = (merchant_slot == 0) ? slot_id.MainSlot : merchant_slot;
|
||||
@ -5396,7 +5396,7 @@ namespace RoF2
|
||||
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;
|
||||
}
|
||||
|
||||
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot)
|
||||
static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot, ItemPacketType PacketType)
|
||||
{
|
||||
structs::ItemSlotStruct RoF2Slot;
|
||||
RoF2Slot.SlotType = INVALID_INDEX;
|
||||
@ -5435,13 +5435,21 @@ namespace RoF2
|
||||
uint32 TempSlot = 0;
|
||||
|
||||
if (ServerSlot < 56 || ServerSlot == MainPowerSource) { // Main Inventory and Cursor
|
||||
RoF2Slot.SlotType = maps::MapPossessions;
|
||||
RoF2Slot.MainSlot = ServerSlot;
|
||||
|
||||
if (PacketType == ItemPacketLoot)
|
||||
{
|
||||
RoF2Slot.SlotType = maps::MapCorpse;
|
||||
RoF2Slot.MainSlot = ServerSlot - EmuConstants::CORPSE_BEGIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
RoF2Slot.SlotType = maps::MapPossessions;
|
||||
RoF2Slot.MainSlot = ServerSlot;
|
||||
}
|
||||
|
||||
if (ServerSlot == 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;
|
||||
|
||||
else if (ServerSlot >= MainAmmo) // (> 20)
|
||||
@ -5568,11 +5576,10 @@ namespace RoF2
|
||||
|
||||
static inline uint32 ServerToRoF2CorpseSlot(uint32 ServerCorpse)
|
||||
{
|
||||
//uint32 RoF2Corpse;
|
||||
return (ServerCorpse + 1);
|
||||
return (ServerCorpse - EmuConstants::CORPSE_BEGIN + 1);
|
||||
}
|
||||
|
||||
static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot)
|
||||
static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot, ItemPacketType PacketType)
|
||||
{
|
||||
uint32 ServerSlot = INVALID_INDEX;
|
||||
uint32 TempSlot = 0;
|
||||
@ -5667,6 +5674,10 @@ namespace RoF2
|
||||
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);
|
||||
|
||||
return ServerSlot;
|
||||
@ -5709,8 +5720,7 @@ namespace RoF2
|
||||
|
||||
static inline uint32 RoF2ToServerCorpseSlot(uint32 RoF2Corpse)
|
||||
{
|
||||
//uint32 ServerCorpse;
|
||||
return (RoF2Corpse - 1);
|
||||
return (RoF2Corpse + EmuConstants::CORPSE_BEGIN - 1);
|
||||
}
|
||||
}
|
||||
// end namespace RoF2
|
||||
|
||||
@ -1843,8 +1843,8 @@ struct LootingItem_Struct {
|
||||
/*000*/ uint32 lootee;
|
||||
/*004*/ uint32 looter;
|
||||
/*008*/ uint16 slot_id;
|
||||
/*010*/ uint16 unknown10;
|
||||
/*012*/ uint32 auto_loot;
|
||||
/*010*/ uint16 unknown10; // slot_id is probably uint32
|
||||
/*012*/ int32 auto_loot;
|
||||
/*016*/ uint32 unknown16;
|
||||
/*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));
|
||||
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;
|
||||
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->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))
|
||||
client->DiscoverItem(inst->GetItem()->ID);
|
||||
}
|
||||
|
||||
@ -122,7 +122,8 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu
|
||||
uint32 i;
|
||||
uint8 membercount = 0;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
// #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>
|
||||
for (int16 i = EmuConstants::EQUIPMENT_BEGIN; i < MainPowerSource; i++) // originally (i < 22)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user