mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 18:52:22 +00:00
Inventory possessions beta testing
This commit is contained in:
+3
-25
@@ -179,14 +179,6 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
|
||||
SetTwoHanderEquipped(true);
|
||||
}
|
||||
|
||||
//Power Source Slot
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
|
||||
{
|
||||
const EQEmu::ItemInstance* inst = m_inv[EQEmu::invslot::SLOT_POWER_SOURCE];
|
||||
if(inst)
|
||||
AddItemBonuses(inst, newbon);
|
||||
}
|
||||
|
||||
//tribute items
|
||||
for (i = EQEmu::invslot::TRIBUTE_BEGIN; i <= EQEmu::invslot::TRIBUTE_END; i++) {
|
||||
const EQEmu::ItemInstance* inst = m_inv[i];
|
||||
@@ -3261,7 +3253,7 @@ void NPC::CalcItemBonuses(StatBonuses *newbon)
|
||||
{
|
||||
if(newbon){
|
||||
|
||||
for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++){
|
||||
for (int i = EQEmu::invslot::BONUS_BEGIN; i <= EQEmu::invslot::BONUS_STAT_END; i++){
|
||||
const EQEmu::ItemData *cur = database.GetItem(equipment[i]);
|
||||
if(cur){
|
||||
//basic stats
|
||||
@@ -3353,13 +3345,6 @@ void Client::CalcItemScale() {
|
||||
if (CalcItemScale(EQEmu::invslot::TRIBUTE_BEGIN, EQEmu::invslot::TRIBUTE_END)) // (< 405)
|
||||
changed = true;
|
||||
|
||||
//Power Source Slot
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
|
||||
{
|
||||
if (CalcItemScale(EQEmu::invslot::SLOT_POWER_SOURCE, EQEmu::invslot::SLOT_POWER_SOURCE))
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if(changed)
|
||||
{
|
||||
CalcBonuses();
|
||||
@@ -3447,13 +3432,6 @@ void Client::DoItemEnterZone() {
|
||||
if (DoItemEnterZone(EQEmu::invslot::TRIBUTE_BEGIN, EQEmu::invslot::TRIBUTE_END)) // (< 405)
|
||||
changed = true;
|
||||
|
||||
//Power Source Slot
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
|
||||
{
|
||||
if (DoItemEnterZone(EQEmu::invslot::SLOT_POWER_SOURCE, EQEmu::invslot::SLOT_POWER_SOURCE))
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if(changed)
|
||||
{
|
||||
CalcBonuses();
|
||||
@@ -3486,7 +3464,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) {
|
||||
uint16 oldexp = inst->GetExp();
|
||||
|
||||
parse->EventItem(EVENT_ITEM_ENTER_ZONE, this, inst, nullptr, "", 0);
|
||||
if (i <= EQEmu::invslot::slotAmmo || i == EQEmu::invslot::SLOT_POWER_SOURCE) {
|
||||
if (i <= EQEmu::invslot::EQUIPMENT_END) {
|
||||
parse->EventItem(EVENT_EQUIP_ITEM, this, inst, nullptr, "", i);
|
||||
}
|
||||
|
||||
@@ -3496,7 +3474,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) {
|
||||
update_slot = true;
|
||||
}
|
||||
} else {
|
||||
if (i <= EQEmu::invslot::slotAmmo || i == EQEmu::invslot::SLOT_POWER_SOURCE) {
|
||||
if (i <= EQEmu::invslot::EQUIPMENT_END) {
|
||||
parse->EventItem(EVENT_EQUIP_ITEM, this, inst, nullptr, "", i);
|
||||
}
|
||||
|
||||
|
||||
+20
-48
@@ -38,6 +38,8 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm
|
||||
this->_botOwnerCharacterID = 0;
|
||||
}
|
||||
|
||||
m_inv.SetInventoryVersion(EQEmu::versions::MobVersion::Bot);
|
||||
|
||||
_guildRank = 0;
|
||||
_guildId = 0;
|
||||
_lastTotalPlayTime = 0;
|
||||
@@ -109,6 +111,8 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
|
||||
|
||||
auto bot_owner = GetBotOwner();
|
||||
|
||||
m_inv.SetInventoryVersion(EQEmu::versions::MobVersion::Bot);
|
||||
|
||||
_guildRank = 0;
|
||||
_guildId = 0;
|
||||
_lastTotalPlayTime = totalPlayTime;
|
||||
@@ -3658,15 +3662,13 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
|
||||
ClientReturn(const ItemInstance* item, int16 from, const char* name = "") : returnItemInstance(item), fromBotSlot(from), toClientSlot(invslot::SLOT_INVALID), adjustStackSize(0), failedItemName(name) { }
|
||||
};
|
||||
|
||||
static const int16 proxyPowerSource = 22;
|
||||
|
||||
static const int16 bot_equip_order[(invslot::CORPSE_BEGIN + 1)] = {
|
||||
static const int16 bot_equip_order[invslot::EQUIPMENT_COUNT] = {
|
||||
invslot::slotCharm, invslot::slotEar1, invslot::slotHead, invslot::slotFace,
|
||||
invslot::slotEar2, invslot::slotNeck, invslot::slotShoulders, invslot::slotArms,
|
||||
invslot::slotBack, invslot::slotWrist1, invslot::slotWrist2, invslot::slotRange,
|
||||
invslot::slotHands, invslot::slotPrimary, invslot::slotSecondary, invslot::slotFinger1,
|
||||
invslot::slotFinger2, invslot::slotChest, invslot::slotLegs, invslot::slotFeet,
|
||||
invslot::slotWaist, invslot::slotAmmo, proxyPowerSource // invslot::SLOT_POWER_SOURCE
|
||||
invslot::slotWaist, invslot::slotPowerSource, invslot::slotAmmo
|
||||
};
|
||||
|
||||
enum { stageStackable = 0, stageEmpty, stageReplaceable };
|
||||
@@ -3802,9 +3804,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
|
||||
//}
|
||||
|
||||
if (stage_loop != stageReplaceable) {
|
||||
if ((index == proxyPowerSource) && m_inv[invslot::SLOT_POWER_SOURCE])
|
||||
continue;
|
||||
else if (m_inv[index])
|
||||
if (m_inv[index])
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3853,18 +3853,10 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
|
||||
}
|
||||
}
|
||||
|
||||
if (index == proxyPowerSource) {
|
||||
trade_iterator.toBotSlot = invslot::SLOT_POWER_SOURCE;
|
||||
trade_iterator.toBotSlot = index;
|
||||
|
||||
if (m_inv[invslot::SLOT_POWER_SOURCE])
|
||||
client_return.push_back(ClientReturn(m_inv[invslot::SLOT_POWER_SOURCE], invslot::SLOT_POWER_SOURCE));
|
||||
}
|
||||
else {
|
||||
trade_iterator.toBotSlot = index;
|
||||
|
||||
if (m_inv[index])
|
||||
client_return.push_back(ClientReturn(m_inv[index], index));
|
||||
}
|
||||
if (m_inv[index])
|
||||
client_return.push_back(ClientReturn(m_inv[index], index));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -4649,6 +4641,7 @@ int32 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) {
|
||||
int32 focus_max = 0;
|
||||
int32 focus_max_real = 0;
|
||||
//item focus
|
||||
// are focus effects the same as bonus? (slotAmmo-excluded)
|
||||
for (int x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invslot::EQUIPMENT_END; x++) {
|
||||
TempItem = nullptr;
|
||||
EQEmu::ItemInstance* ins = GetBotItem(x);
|
||||
@@ -7604,10 +7597,7 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) {
|
||||
const EQEmu::ItemData* item = nullptr;
|
||||
const EQEmu::ItemInstance* inst = nullptr;
|
||||
|
||||
// Modded to display power source items (will only show up on SoF+ client inspect windows though.)
|
||||
// I don't think bots are currently coded to use them..but, you'll have to use '#bot inventory list'
|
||||
// to see them on a Titanium client when/if they are activated.
|
||||
for (int16 L = EQEmu::invslot::EQUIPMENT_BEGIN; L <= EQEmu::invslot::slotWaist; L++) {
|
||||
for (int16 L = EQEmu::invslot::EQUIPMENT_BEGIN; L <= EQEmu::invslot::EQUIPMENT_END; L++) {
|
||||
inst = inspectedBot->GetBotItem(L);
|
||||
|
||||
if(inst) {
|
||||
@@ -7616,33 +7606,15 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) {
|
||||
strcpy(insr->itemnames[L], item->Name);
|
||||
insr->itemicons[L] = item->Icon;
|
||||
}
|
||||
else
|
||||
else {
|
||||
insr->itemnames[L][0] = '\0';
|
||||
insr->itemicons[L] = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inst = inspectedBot->GetBotItem(EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
|
||||
if(inst) {
|
||||
item = inst->GetItem();
|
||||
if(item) {
|
||||
strcpy(insr->itemnames[SoF::invslot::slotPowerSource], item->Name);
|
||||
insr->itemicons[SoF::invslot::slotPowerSource] = item->Icon;
|
||||
else {
|
||||
insr->itemnames[L][0] = '\0';
|
||||
insr->itemicons[L] = 0xFFFFFFFF;
|
||||
}
|
||||
else
|
||||
insr->itemicons[SoF::invslot::slotPowerSource] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
inst = inspectedBot->GetBotItem(EQEmu::invslot::slotAmmo);
|
||||
|
||||
if(inst) {
|
||||
item = inst->GetItem();
|
||||
if(item) {
|
||||
strcpy(insr->itemnames[SoF::invslot::slotAmmo], item->Name);
|
||||
insr->itemicons[SoF::invslot::slotAmmo] = item->Icon;
|
||||
}
|
||||
else
|
||||
insr->itemicons[SoF::invslot::slotAmmo] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
strcpy(insr->text, inspectedBot->GetInspectMessage().text);
|
||||
@@ -7655,8 +7627,8 @@ void Bot::CalcItemBonuses(StatBonuses* newbon)
|
||||
{
|
||||
const EQEmu::ItemData* itemtmp = nullptr;
|
||||
|
||||
for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= (EQEmu::invslot::EQUIPMENT_END + 1); ++i) {
|
||||
const EQEmu::ItemInstance* item = GetBotItem((i == 22 ? 9999 : i));
|
||||
for (int i = EQEmu::invslot::BONUS_BEGIN; i <= EQEmu::invslot::BONUS_STAT_END; ++i) {
|
||||
const EQEmu::ItemInstance* item = GetBotItem(i);
|
||||
if(item) {
|
||||
AddItemBonuses(item, newbon);
|
||||
}
|
||||
|
||||
+25
-25
@@ -80,33 +80,33 @@ static const std::string bot_stance_name[BOT_STANCE_COUNT] = {
|
||||
|
||||
static const char* GetBotStanceName(int stance_id) { return bot_stance_name[VALIDBOTSTANCE(stance_id)].c_str(); }
|
||||
|
||||
#define VALIDBOTEQUIPSLOT(x) ((x >= EQEmu::invslot::EQUIPMENT_BEGIN && x <= EQEmu::invslot::EQUIPMENT_END) ? (x) : ((x == EQEmu::invslot::SLOT_POWER_SOURCE) ? (22) : (23)))
|
||||
#define VALIDBOTEQUIPSLOT(x) ((x >= EQEmu::invslot::EQUIPMENT_BEGIN && x <= EQEmu::invslot::EQUIPMENT_END) ? (x) : (EQEmu::invslot::EQUIPMENT_COUNT))
|
||||
|
||||
static std::string bot_equip_slot_name[EQEmu::invslot::EQUIPMENT_COUNT + 2] =
|
||||
static const std::string bot_equip_slot_name[EQEmu::invslot::EQUIPMENT_COUNT + 1] =
|
||||
{
|
||||
"Charm", // MainCharm
|
||||
"Left Ear", // MainEar1
|
||||
"Head", // MainHead
|
||||
"Face", // MainFace
|
||||
"Right Ear", // MainEar2
|
||||
"Neck", // MainNeck
|
||||
"Shoulders", // MainShoulders
|
||||
"Arms", // MainArms
|
||||
"Back", // MainBack
|
||||
"Left Wrist", // MainWrist1
|
||||
"Right Wrist", // MainWrist2
|
||||
"Range", // MainRange
|
||||
"Hands", // MainHands
|
||||
"Primary Hand", // MainPrimary
|
||||
"Secondary Hand", // MainSecondary
|
||||
"Left Finger", // MainFinger1
|
||||
"Right Finger", // MainFinger2
|
||||
"Chest", // MainChest
|
||||
"Legs", // MainLegs
|
||||
"Feet", // MainFeet
|
||||
"Waist", // MainWaist
|
||||
"Ammo", // MainAmmo
|
||||
"Power Source", // 22 (MainPowerSource = 9999)
|
||||
"Charm", // slotCharm
|
||||
"Ear 1", // slotEar1
|
||||
"Head", // slotHead
|
||||
"Face", // slotFace
|
||||
"Ear 2", // slotEar2
|
||||
"Neck", // slotNeck
|
||||
"Shoulders", // slotShoulders
|
||||
"Arms", // slotArms
|
||||
"Back", // slotBack
|
||||
"Wrist 1", // slotWrist1
|
||||
"Wrist 2", // slotWrist2
|
||||
"Range", // slotRange
|
||||
"Hands", // slotHands
|
||||
"Primary", // slotPrimary
|
||||
"Secondary", // slotSecondary
|
||||
"Finger 1", // slotFinger1
|
||||
"Finger 2", // slotFinger2
|
||||
"Chest", // slotChest
|
||||
"Legs", // slotLegs
|
||||
"Feet", // slotFeet
|
||||
"Waist", // slotWaist
|
||||
"Power Source", // slotPowerSource
|
||||
"Ammo", // slotAmmo
|
||||
"Unknown"
|
||||
};
|
||||
|
||||
|
||||
+10
-10
@@ -7194,13 +7194,13 @@ void bot_subcommand_inventory_list(Client *c, const Seperator *sep)
|
||||
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
||||
|
||||
uint32 inventory_count = 0;
|
||||
for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= (EQEmu::invslot::EQUIPMENT_END + 1); ++i) {
|
||||
for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; ++i) {
|
||||
if ((i == EQEmu::invslot::slotSecondary) && is2Hweapon)
|
||||
continue;
|
||||
|
||||
inst = my_bot->CastToBot()->GetBotItem(i == 22 ? EQEmu::invslot::SLOT_POWER_SOURCE : i);
|
||||
inst = my_bot->CastToBot()->GetBotItem(i);
|
||||
if (!inst || !inst->GetItem()) {
|
||||
c->Message(m_message, "I need something for my %s (slot %i)", GetBotEquipSlotName(i), (i == 22 ? EQEmu::invslot::SLOT_POWER_SOURCE : i));
|
||||
c->Message(m_message, "I need something for my %s (slot %i)", GetBotEquipSlotName(i), i);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -7210,7 +7210,7 @@ void bot_subcommand_inventory_list(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
linker.SetItemInst(inst);
|
||||
c->Message(m_message, "Using %s in my %s (slot %i)", linker.GenerateLink().c_str(), GetBotEquipSlotName(i), (i == 22 ? EQEmu::invslot::SLOT_POWER_SOURCE : i));
|
||||
c->Message(m_message, "Using %s in my %s (slot %i)", linker.GenerateLink().c_str(), GetBotEquipSlotName(i), i);
|
||||
|
||||
++inventory_count;
|
||||
}
|
||||
@@ -7249,8 +7249,8 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
int slotId = atoi(sep->arg[1]);
|
||||
if (!sep->IsNumber(1) || ((slotId > EQEmu::invslot::EQUIPMENT_END || slotId < EQEmu::invslot::EQUIPMENT_BEGIN) && slotId != EQEmu::invslot::SLOT_POWER_SOURCE)) {
|
||||
c->Message(m_fail, "Valid slots are 0-21 or 9999");
|
||||
if (!sep->IsNumber(1) || (slotId > EQEmu::invslot::EQUIPMENT_END || slotId < EQEmu::invslot::EQUIPMENT_BEGIN)) {
|
||||
c->Message(m_fail, "Valid slots are 0-22");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7311,7 +7311,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
|
||||
case EQEmu::invslot::slotFinger2:
|
||||
case EQEmu::invslot::slotChest:
|
||||
case EQEmu::invslot::slotWaist:
|
||||
case EQEmu::invslot::SLOT_POWER_SOURCE:
|
||||
case EQEmu::invslot::slotPowerSource:
|
||||
case EQEmu::invslot::slotAmmo:
|
||||
c->Message(m_message, "My %s is %s unequipped", GetBotEquipSlotName(slotId), ((itm) ? ("now") : ("already")));
|
||||
break;
|
||||
@@ -7356,14 +7356,14 @@ void bot_subcommand_inventory_window(Client *c, const Seperator *sep)
|
||||
//EQEmu::SayLinkEngine linker;
|
||||
//linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
||||
|
||||
for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= (EQEmu::invslot::EQUIPMENT_END + 1); ++i) {
|
||||
for (int i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; ++i) {
|
||||
const EQEmu::ItemData* item = nullptr;
|
||||
const EQEmu::ItemInstance* inst = my_bot->CastToBot()->GetBotItem(i == 22 ? EQEmu::invslot::SLOT_POWER_SOURCE : i);
|
||||
const EQEmu::ItemInstance* inst = my_bot->CastToBot()->GetBotItem(i);
|
||||
if (inst)
|
||||
item = inst->GetItem();
|
||||
|
||||
window_text.append("<c \"#FFFFFF\">");
|
||||
window_text.append(GetBotEquipSlotName(i == 22 ? EQEmu::invslot::SLOT_POWER_SOURCE : i));
|
||||
window_text.append(GetBotEquipSlotName(i));
|
||||
window_text.append(": ");
|
||||
if (item) {
|
||||
//window_text.append("</c>");
|
||||
|
||||
@@ -1138,7 +1138,7 @@ bool BotDatabase::LoadItems(const uint32 bot_id, EQEmu::InventoryProfile& invent
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
int16 slot_id = atoi(row[0]);
|
||||
if ((slot_id < EQEmu::invslot::EQUIPMENT_BEGIN || slot_id > EQEmu::invslot::EQUIPMENT_END) && slot_id != EQEmu::invslot::SLOT_POWER_SOURCE)
|
||||
if (slot_id < EQEmu::invslot::EQUIPMENT_BEGIN || slot_id > EQEmu::invslot::EQUIPMENT_END)
|
||||
continue;
|
||||
|
||||
uint32 item_id = atoi(row[1]);
|
||||
@@ -1173,7 +1173,7 @@ bool BotDatabase::LoadItems(const uint32 bot_id, EQEmu::InventoryProfile& invent
|
||||
if (item_inst->GetItem()->Attuneable) {
|
||||
if (atoi(row[4]))
|
||||
item_inst->SetAttuned(true);
|
||||
else if (((slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN) && (slot_id <= EQEmu::invslot::EQUIPMENT_END) || slot_id == EQEmu::invslot::SLOT_POWER_SOURCE))
|
||||
else if (slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN && slot_id <= EQEmu::invslot::EQUIPMENT_END)
|
||||
item_inst->SetAttuned(true);
|
||||
}
|
||||
|
||||
@@ -1241,7 +1241,7 @@ bool BotDatabase::LoadItemBySlot(Bot* bot_inst)
|
||||
|
||||
bool BotDatabase::LoadItemBySlot(const uint32 bot_id, const uint32 slot_id, uint32& item_id)
|
||||
{
|
||||
if (!bot_id || (slot_id > EQEmu::invslot::EQUIPMENT_END && slot_id != EQEmu::invslot::SLOT_POWER_SOURCE))
|
||||
if (!bot_id || slot_id > EQEmu::invslot::EQUIPMENT_END)
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `item_id` FROM `bot_inventories` WHERE `bot_id` = '%i' AND `slot_id` = '%i' LIMIT 1", bot_id, slot_id);
|
||||
@@ -1259,7 +1259,7 @@ bool BotDatabase::LoadItemBySlot(const uint32 bot_id, const uint32 slot_id, uint
|
||||
|
||||
bool BotDatabase::SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const EQEmu::ItemInstance* item_inst)
|
||||
{
|
||||
if (!bot_inst || !bot_inst->GetBotID() || (slot_id > EQEmu::invslot::EQUIPMENT_END && slot_id != EQEmu::invslot::SLOT_POWER_SOURCE))
|
||||
if (!bot_inst || !bot_inst->GetBotID() || slot_id > EQEmu::invslot::EQUIPMENT_END)
|
||||
return false;
|
||||
|
||||
if (!DeleteItemBySlot(bot_inst->GetBotID(), slot_id))
|
||||
@@ -1343,7 +1343,7 @@ bool BotDatabase::SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const EQEm
|
||||
|
||||
bool BotDatabase::DeleteItemBySlot(const uint32 bot_id, const uint32 slot_id)
|
||||
{
|
||||
if (!bot_id || (slot_id > EQEmu::invslot::EQUIPMENT_END && slot_id != EQEmu::invslot::SLOT_POWER_SOURCE))
|
||||
if (!bot_id || slot_id > EQEmu::invslot::EQUIPMENT_END)
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_inventories` WHERE `bot_id` = '%u' AND `slot_id` = '%u'", bot_id, slot_id);
|
||||
@@ -1382,7 +1382,7 @@ bool BotDatabase::SaveEquipmentColor(const uint32 bot_id, const int16 slot_id, c
|
||||
return false;
|
||||
|
||||
bool all_flag = (slot_id == -2);
|
||||
if ((slot_id < EQEmu::invslot::EQUIPMENT_BEGIN || slot_id > EQEmu::invslot::EQUIPMENT_END) && slot_id != EQEmu::invslot::SLOT_POWER_SOURCE && !all_flag)
|
||||
if ((slot_id < EQEmu::invslot::EQUIPMENT_BEGIN || slot_id > EQEmu::invslot::EQUIPMENT_END) && !all_flag)
|
||||
return false;
|
||||
|
||||
std::string where_clause;
|
||||
@@ -1659,7 +1659,7 @@ bool BotDatabase::LoadPetItems(const uint32 bot_id, uint32* pet_items)
|
||||
return true;
|
||||
|
||||
int item_index = EQEmu::invslot::EQUIPMENT_BEGIN;
|
||||
for (auto row = results.begin(); row != results.end() && item_index <= EQEmu::invslot::EQUIPMENT_END; ++row) {
|
||||
for (auto row = results.begin(); row != results.end() && (item_index >= EQEmu::invslot::EQUIPMENT_BEGIN && item_index <= EQEmu::invslot::EQUIPMENT_END); ++row) {
|
||||
pet_items[item_index] = atoi(row[0]);
|
||||
++item_index;
|
||||
}
|
||||
@@ -1683,7 +1683,7 @@ bool BotDatabase::SavePetItems(const uint32 bot_id, const uint32* pet_items, boo
|
||||
if (!saved_pet_index)
|
||||
return true;
|
||||
|
||||
for (int item_index = EQEmu::invslot::SLOT_BEGIN; item_index <= EQEmu::invslot::EQUIPMENT_END; ++item_index) {
|
||||
for (int item_index = EQEmu::invslot::EQUIPMENT_BEGIN; item_index <= EQEmu::invslot::EQUIPMENT_END; ++item_index) {
|
||||
if (!pet_items[item_index])
|
||||
continue;
|
||||
|
||||
|
||||
+18
-51
@@ -1905,7 +1905,7 @@ void Client::CheckManaEndUpdate() {
|
||||
else if (group) {
|
||||
group->SendEndurancePacketFrom(this);
|
||||
}
|
||||
|
||||
|
||||
auto endurance_packet = new EQApplicationPacket(OP_EnduranceUpdate, sizeof(EnduranceUpdate_Struct));
|
||||
EnduranceUpdate_Struct* endurance_update = (EnduranceUpdate_Struct*)endurance_packet->pBuffer;
|
||||
endurance_update->cur_end = GetEndurance();
|
||||
@@ -6004,56 +6004,34 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) {
|
||||
const EQEmu::ItemData* item = nullptr;
|
||||
const EQEmu::ItemInstance* inst = nullptr;
|
||||
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
for(int16 L = 0; L <= 20; L++) {
|
||||
for(int16 L = EQEmu::invslot::EQUIPMENT_BEGIN; L <= EQEmu::invslot::EQUIPMENT_END; L++) {
|
||||
inst = requestee->GetInv().GetItem(L);
|
||||
|
||||
if(inst) {
|
||||
item = inst->GetItem();
|
||||
if(item) {
|
||||
strcpy(insr->itemnames[L], item->Name);
|
||||
if (inst && inst->GetOrnamentationAug(ornamentationAugtype))
|
||||
{
|
||||
const EQEmu::ItemData *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
|
||||
const EQEmu::ItemData *aug_item = nullptr;
|
||||
if (inst->GetOrnamentationAug(ornamentationAugtype))
|
||||
inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
|
||||
if (aug_item)
|
||||
insr->itemicons[L] = aug_item->Icon;
|
||||
}
|
||||
else if (inst && inst->GetOrnamentationIcon())
|
||||
{
|
||||
else if (inst->GetOrnamentationIcon())
|
||||
insr->itemicons[L] = inst->GetOrnamentationIcon();
|
||||
}
|
||||
else
|
||||
{
|
||||
insr->itemicons[L] = item->Icon;
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
insr->itemnames[L][0] = '\0';
|
||||
insr->itemicons[L] = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inst = requestee->GetInv().GetItem(EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
|
||||
if(inst) {
|
||||
item = inst->GetItem();
|
||||
if(item) {
|
||||
// we shouldn't do this..but, that's the way it's coded atm...
|
||||
// (this type of action should be handled exclusively in the client translator)
|
||||
strcpy(insr->itemnames[SoF::invslot::slotPowerSource], item->Name);
|
||||
insr->itemicons[SoF::invslot::slotPowerSource] = item->Icon;
|
||||
else {
|
||||
insr->itemnames[L][0] = '\0';
|
||||
insr->itemicons[L] = 0xFFFFFFFF;
|
||||
}
|
||||
else
|
||||
insr->itemicons[SoF::invslot::slotPowerSource] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
inst = requestee->GetInv().GetItem(EQEmu::invslot::slotAmmo);
|
||||
|
||||
if(inst) {
|
||||
item = inst->GetItem();
|
||||
if(item) {
|
||||
strcpy(insr->itemnames[SoF::invslot::slotAmmo], item->Name);
|
||||
insr->itemicons[SoF::invslot::slotAmmo] = item->Icon;
|
||||
}
|
||||
else
|
||||
insr->itemicons[SoF::invslot::slotAmmo] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
strcpy(insr->text, requestee->GetInspectMessage().text);
|
||||
@@ -8406,13 +8384,8 @@ void Client::TickItemCheck()
|
||||
|
||||
if(zone->tick_items.empty()) { return; }
|
||||
|
||||
//Scan equip slots for items
|
||||
for (i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++)
|
||||
{
|
||||
TryItemTick(i);
|
||||
}
|
||||
//Scan main inventory + cursor
|
||||
for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::slotCursor; i++)
|
||||
//Scan equip, general, cursor slots for items
|
||||
for (i = EQEmu::invslot::POSSESSIONS_BEGIN; i <= EQEmu::invslot::POSSESSIONS_END; i++)
|
||||
{
|
||||
TryItemTick(i);
|
||||
}
|
||||
@@ -8464,16 +8437,10 @@ void Client::TryItemTick(int slot)
|
||||
void Client::ItemTimerCheck()
|
||||
{
|
||||
int i;
|
||||
for (i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++)
|
||||
for (i = EQEmu::invslot::POSSESSIONS_BEGIN; i <= EQEmu::invslot::POSSESSIONS_END; i++)
|
||||
{
|
||||
TryItemTimer(i);
|
||||
}
|
||||
|
||||
for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::slotCursor; i++)
|
||||
{
|
||||
TryItemTimer(i);
|
||||
}
|
||||
|
||||
for (i = EQEmu::invbag::GENERAL_BAGS_BEGIN; i <= EQEmu::invbag::CURSOR_BAG_END; i++)
|
||||
{
|
||||
TryItemTimer(i);
|
||||
|
||||
+2
-13
@@ -3002,8 +3002,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
|
||||
bool deleteItems = false;
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::RoF)
|
||||
{
|
||||
if ((in_augment->container_slot < 0 || in_augment->container_slot >= EQEmu::invslot::slotCursor) &&
|
||||
in_augment->container_slot != EQEmu::invslot::SLOT_POWER_SOURCE &&
|
||||
if ((in_augment->container_slot < EQEmu::invslot::EQUIPMENT_BEGIN || in_augment->container_slot > EQEmu::invslot::GENERAL_END) &&
|
||||
(in_augment->container_slot < EQEmu::invbag::GENERAL_BAGS_BEGIN || in_augment->container_slot > EQEmu::invbag::GENERAL_BAGS_END))
|
||||
{
|
||||
Message(13, "The server does not allow augmentation actions from this slot.");
|
||||
@@ -8239,7 +8238,7 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app)
|
||||
const EQEmu::ItemData* item = nullptr;
|
||||
|
||||
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
for (int16 L = EQEmu::invslot::EQUIPMENT_BEGIN; L <= EQEmu::invslot::slotWaist; L++) {
|
||||
for (int16 L = EQEmu::invslot::EQUIPMENT_BEGIN; L <= EQEmu::invslot::EQUIPMENT_END; L++) {
|
||||
const EQEmu::ItemInstance* inst = GetInv().GetItem(L);
|
||||
item = inst ? inst->GetItem() : nullptr;
|
||||
|
||||
@@ -8259,16 +8258,6 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app)
|
||||
else { insr->itemicons[L] = 0xFFFFFFFF; }
|
||||
}
|
||||
|
||||
const EQEmu::ItemInstance* inst = GetInv().GetItem(EQEmu::invslot::slotAmmo);
|
||||
item = inst ? inst->GetItem() : nullptr;
|
||||
|
||||
if (item) {
|
||||
// another one..I did these, didn't I!!?
|
||||
strcpy(insr->itemnames[SoF::invslot::slotAmmo], item->Name);
|
||||
insr->itemicons[SoF::invslot::slotAmmo] = item->Icon;
|
||||
}
|
||||
else { insr->itemicons[SoF::invslot::slotAmmo] = 0xFFFFFFFF; }
|
||||
|
||||
InspectMessage_Struct* newmessage = (InspectMessage_Struct*)insr->text;
|
||||
InspectMessage_Struct& playermessage = this->GetInspectMessage();
|
||||
memcpy(&playermessage, newmessage, sizeof(InspectMessage_Struct));
|
||||
|
||||
@@ -815,19 +815,6 @@ void Client::BulkSendInventoryItems()
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
|
||||
// PowerSource item
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
|
||||
const EQEmu::ItemInstance* inst = m_inv[EQEmu::invslot::SLOT_POWER_SOURCE];
|
||||
if (inst) {
|
||||
inst->Serialize(ob, EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
|
||||
if (ob.tellp() == last_pos)
|
||||
Log(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
|
||||
last_pos = ob.tellp();
|
||||
}
|
||||
}
|
||||
|
||||
// Bank items
|
||||
for (int16 slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; slot_id++) {
|
||||
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
||||
|
||||
+1
-47
@@ -2768,52 +2768,6 @@ void command_peekinv(Client *c, const Seperator *sep)
|
||||
}
|
||||
}
|
||||
|
||||
if ((scopeBit & peekEquip) && (targetClient->ClientVersion() >= EQEmu::versions::ClientVersion::SoF)) {
|
||||
inst_main = targetClient->GetInv().GetItem(EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
if (inst_main) {
|
||||
itemsFound = true;
|
||||
item_data = inst_main->GetItem();
|
||||
}
|
||||
else {
|
||||
item_data = nullptr;
|
||||
}
|
||||
|
||||
linker.SetItemInst(inst_main);
|
||||
|
||||
c->Message(
|
||||
(item_data == nullptr),
|
||||
"%sSlot: %i, Item: %i (%s), Charges: %i",
|
||||
scope_prefix[scopeIndex],
|
||||
EQEmu::invslot::SLOT_POWER_SOURCE,
|
||||
((item_data == nullptr) ? 0 : item_data->ID),
|
||||
linker.GenerateLink().c_str(),
|
||||
((inst_main == nullptr) ? 0 : inst_main->GetCharges())
|
||||
);
|
||||
|
||||
if (inst_main && inst_main->IsClassCommon()) {
|
||||
for (uint8 indexAug = EQEmu::invaug::SOCKET_BEGIN; indexAug <= EQEmu::invaug::SOCKET_END; ++indexAug) {
|
||||
inst_aug = inst_main->GetItem(indexAug);
|
||||
if (!inst_aug) // extant only
|
||||
continue;
|
||||
|
||||
item_data = inst_aug->GetItem();
|
||||
linker.SetItemInst(inst_aug);
|
||||
|
||||
c->Message(
|
||||
(item_data == nullptr),
|
||||
".%sAugSlot: %i (Slot #%i, Aug idx #%i), Item: %i (%s), Charges: %i",
|
||||
scope_prefix[scopeIndex],
|
||||
INVALID_INDEX,
|
||||
EQEmu::invslot::SLOT_POWER_SOURCE,
|
||||
indexAug,
|
||||
((item_data == nullptr) ? 0 : item_data->ID),
|
||||
linker.GenerateLink().c_str(),
|
||||
((inst_sub == nullptr) ? 0 : inst_sub->GetCharges())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scopeBit & peekLimbo) {
|
||||
int limboIndex = 0;
|
||||
for (auto it = targetClient->GetInv().cursor_cbegin(); (it != targetClient->GetInv().cursor_cend()); ++it, ++limboIndex) {
|
||||
@@ -3324,7 +3278,7 @@ void command_listpetition(Client *c, const Seperator *sep)
|
||||
void command_equipitem(Client *c, const Seperator *sep)
|
||||
{
|
||||
uint32 slot_id = atoi(sep->arg[1]);
|
||||
if (sep->IsNumber(1) && ((slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN) && (slot_id <= EQEmu::invslot::EQUIPMENT_END) || (slot_id == EQEmu::invslot::SLOT_POWER_SOURCE))) {
|
||||
if (sep->IsNumber(1) && (slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN && slot_id <= EQEmu::invslot::EQUIPMENT_END)) {
|
||||
const EQEmu::ItemInstance* from_inst = c->GetInv().GetItem(EQEmu::invslot::slotCursor);
|
||||
const EQEmu::ItemInstance* to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack)
|
||||
bool partialmove = false;
|
||||
|
||||
@@ -263,6 +263,17 @@ enum class LootResponse : uint8 {
|
||||
LootAll = 6 // SoD+
|
||||
};
|
||||
|
||||
enum class LootRequestType : uint8 {
|
||||
Forbidden = 0,
|
||||
GMPeek,
|
||||
GMAllowed,
|
||||
Self,
|
||||
AllowedPVE,
|
||||
AllowedPVPAll,
|
||||
AllowedPVPSingle, // can make this 'AllowedPVPVariable' and allow values between 1 and EQEmu::invtype::POSSESSIONS_SIZE
|
||||
AllowedPVPDefined,
|
||||
};
|
||||
|
||||
//this is our internal representation of the BUFF struct, can put whatever we want in it
|
||||
struct Buffs_Struct {
|
||||
uint16 spellid;
|
||||
|
||||
+230
-173
@@ -202,6 +202,8 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
||||
|
||||
UpdateEquipmentLight();
|
||||
UpdateActiveLight();
|
||||
|
||||
loot_request_type = LootRequestType::Forbidden;
|
||||
}
|
||||
|
||||
Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
@@ -322,15 +324,11 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
// to go into the regular slots on the player, out of bags
|
||||
std::list<uint32> removed_list;
|
||||
|
||||
// ideally, we would start at invslot::slotGeneral1 and progress to invslot::slotCursor..
|
||||
// ..then regress and process invslot::EQUIPMENT_BEGIN through invslot::EQUIPMENT_END...
|
||||
// without additional work to database loading of player corpses, this order is not
|
||||
// currently preserved and a re-work of this processing loop is not warranted.
|
||||
for (i = EQEmu::invslot::POSSESSIONS_BEGIN; i <= EQEmu::invslot::POSSESSIONS_END; ++i) {
|
||||
if (i == EQEmu::invslot::slotAmmo && client->ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
|
||||
item = client->GetInv().GetItem(EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
if (item != nullptr) {
|
||||
if (!client->IsBecomeNPC() || (client->IsBecomeNPC() && !item->GetItem()->NoRent))
|
||||
MoveItemToCorpse(client, item, EQEmu::invslot::SLOT_POWER_SOURCE, removed_list);
|
||||
}
|
||||
}
|
||||
|
||||
item = client->GetInv().GetItem(i);
|
||||
if (item == nullptr) { continue; }
|
||||
|
||||
@@ -340,25 +338,25 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
|
||||
database.TransactionBegin();
|
||||
|
||||
// I have an untested process that avoids this snarl up when all possessions inventory is removed..but this isn't broke
|
||||
// this should not be modified to include the entire range of invtype::TYPE_POSSESSIONS slots by default..
|
||||
// ..due to the possibility of 'hidden' items from client version bias..or, possibly, soul-bound items (WoW?)
|
||||
if (!removed_list.empty()) {
|
||||
std::stringstream ss("");
|
||||
ss << "DELETE FROM inventory WHERE charid=" << client->CharacterID();
|
||||
ss << " AND (";
|
||||
std::list<uint32>::const_iterator iter = removed_list.begin();
|
||||
bool first = true;
|
||||
while (iter != removed_list.end()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
ss << " OR ";
|
||||
}
|
||||
ss << "slotid=" << (*iter);
|
||||
|
||||
if (iter != removed_list.end()) {
|
||||
std::stringstream ss("");
|
||||
ss << "DELETE FROM `inventory` WHERE `charid` = " << client->CharacterID();
|
||||
ss << " AND `slotid` IN (" << (*iter);
|
||||
++iter;
|
||||
|
||||
while (iter != removed_list.end()) {
|
||||
ss << ", " << (*iter);
|
||||
++iter;
|
||||
}
|
||||
ss << ")";
|
||||
|
||||
database.QueryDatabase(ss.str().c_str());
|
||||
}
|
||||
ss << ")";
|
||||
database.QueryDatabase(ss.str().c_str());
|
||||
}
|
||||
|
||||
auto start = client->GetInv().cursor_cbegin();
|
||||
@@ -382,6 +380,8 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
UpdateEquipmentLight();
|
||||
UpdateActiveLight();
|
||||
|
||||
loot_request_type = LootRequestType::Forbidden;
|
||||
|
||||
IsRezzed(false);
|
||||
Save();
|
||||
}
|
||||
@@ -524,6 +524,8 @@ EQEmu::TintProfile(),
|
||||
|
||||
UpdateEquipmentLight();
|
||||
UpdateActiveLight();
|
||||
|
||||
loot_request_type = LootRequestType::Forbidden;
|
||||
}
|
||||
|
||||
Corpse::~Corpse() {
|
||||
@@ -873,13 +875,16 @@ void Corpse::AllowPlayerLoot(Mob *them, uint8 slot) {
|
||||
}
|
||||
|
||||
void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* app) {
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
// Added 12/08. Started compressing loot struct on live.
|
||||
if(player_corpse_depop) {
|
||||
SendLootReqErrorPacket(client, LootResponse::SomeoneElse);
|
||||
return;
|
||||
}
|
||||
|
||||
if(IsPlayerCorpse() && corpse_db_id == 0) {
|
||||
if(IsPlayerCorpse() && !corpse_db_id) { // really should try to resave in this case
|
||||
// SendLootReqErrorPacket(client, 0);
|
||||
client->Message(13, "Warning: Corpse's dbid = 0! Corpse will not survive zone shutdown!");
|
||||
std::cout << "Error: PlayerCorpse::MakeLootRequestPackets: dbid = 0!" << std::endl;
|
||||
@@ -892,165 +897,195 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
return;
|
||||
}
|
||||
|
||||
if(being_looted_by == 0)
|
||||
if(!being_looted_by || (being_looted_by != 0xFFFFFFFF && !entity_list.GetID(being_looted_by)))
|
||||
being_looted_by = 0xFFFFFFFF;
|
||||
|
||||
if(this->being_looted_by != 0xFFFFFFFF) {
|
||||
// lets double check....
|
||||
Entity* looter = entity_list.GetID(this->being_looted_by);
|
||||
if(looter == nullptr)
|
||||
this->being_looted_by = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
uint8 Loot_Request_Type = 1;
|
||||
bool loot_coin = false;
|
||||
std::string tmp;
|
||||
if(database.GetVariable("LootCoin", tmp))
|
||||
loot_coin = tmp[0] == 1 && tmp[1] == '\0';
|
||||
|
||||
if (DistanceSquaredNoZ(client->GetPosition(), m_Position) > 625) {
|
||||
SendLootReqErrorPacket(client, LootResponse::TooFar);
|
||||
// not sure if we need to send the packet back in this case? Didn't before!
|
||||
// Will just return for now
|
||||
return;
|
||||
}
|
||||
else if (this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) {
|
||||
|
||||
if (being_looted_by != 0xFFFFFFFF && being_looted_by != client->GetID()) {
|
||||
SendLootReqErrorPacket(client, LootResponse::SomeoneElse);
|
||||
Loot_Request_Type = 0;
|
||||
}
|
||||
else if (IsPlayerCorpse() && char_id == client->CharacterID()) {
|
||||
Loot_Request_Type = 2;
|
||||
}
|
||||
else if ((IsNPCCorpse() || become_npc) && CanPlayerLoot(client->CharacterID())) {
|
||||
Loot_Request_Type = 2;
|
||||
}
|
||||
else if (GetPlayerKillItem() == -1 && CanPlayerLoot(client->CharacterID())) { /* PVP loot all items, variable cash */
|
||||
Loot_Request_Type = 3;
|
||||
}
|
||||
else if (GetPlayerKillItem() == 1 && CanPlayerLoot(client->CharacterID())) { /* PVP loot 1 item, variable cash */
|
||||
Loot_Request_Type = 4;
|
||||
}
|
||||
else if (GetPlayerKillItem() > 1 && CanPlayerLoot(client->CharacterID())) { /* PVP loot 1 set item, variable cash */
|
||||
Loot_Request_Type = 5;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Loot_Request_Type == 1) {
|
||||
if (client->Admin() < 100 || !client->GetGM()) {
|
||||
SendLootReqErrorPacket(client, LootResponse::NotAtThisTime);
|
||||
// all loot session disqualifiers should occur before this point as not to interfere with any current looter
|
||||
loot_request_type = LootRequestType::Forbidden;
|
||||
|
||||
// loot_request_type is scoped to class Corpse and reset on a per-loot session basis
|
||||
if (client->GetGM()) {
|
||||
if (client->Admin() >= 100)
|
||||
loot_request_type = LootRequestType::GMAllowed;
|
||||
else
|
||||
loot_request_type = LootRequestType::GMPeek;
|
||||
}
|
||||
else {
|
||||
if (IsPlayerCorpse()) {
|
||||
if (char_id == client->CharacterID()) {
|
||||
loot_request_type = LootRequestType::Self;
|
||||
}
|
||||
else if (CanPlayerLoot(client->CharacterID())) {
|
||||
if (GetPlayerKillItem() == -1)
|
||||
loot_request_type = LootRequestType::AllowedPVPAll;
|
||||
else if (GetPlayerKillItem() == 1)
|
||||
loot_request_type = LootRequestType::AllowedPVPSingle;
|
||||
else if (GetPlayerKillItem() > 1)
|
||||
loot_request_type = LootRequestType::AllowedPVPDefined;
|
||||
}
|
||||
}
|
||||
else if ((IsNPCCorpse() || become_npc) && CanPlayerLoot(client->CharacterID())) {
|
||||
loot_request_type = LootRequestType::AllowedPVE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(Loot_Request_Type >= 2 || (Loot_Request_Type == 1 && client->Admin() >= 100 && client->GetGM())) {
|
||||
client->CommonBreakInvisible(); // we should be "all good" so lets break invis now instead of earlier before all error checking is done
|
||||
this->being_looted_by = client->GetID();
|
||||
Log(Logs::Moderate, Logs::Inventory, "MakeLootRequestPackets() LootRequestType %u for %s", loot_request_type, client->GetName());
|
||||
|
||||
if (loot_request_type == LootRequestType::Forbidden) {
|
||||
SendLootReqErrorPacket(client, LootResponse::NotAtThisTime);
|
||||
return;
|
||||
}
|
||||
|
||||
being_looted_by = client->GetID();
|
||||
client->CommonBreakInvisible(); // we should be "all good" so lets break invis now instead of earlier before all error checking is done
|
||||
|
||||
// process coin
|
||||
bool loot_coin = false;
|
||||
std::string tmp;
|
||||
if (database.GetVariable("LootCoin", tmp))
|
||||
loot_coin = (tmp[0] == 1 && tmp[1] == '\0');
|
||||
|
||||
if (loot_request_type == LootRequestType::GMPeek || loot_request_type == LootRequestType::GMAllowed) {
|
||||
client->Message(15, "This corpse contains %u platinum, %u gold, %u silver and %u copper.",
|
||||
GetPlatinum(), GetGold(), GetSilver(), GetCopper());
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct));
|
||||
moneyOnCorpseStruct* d = (moneyOnCorpseStruct*) outapp->pBuffer;
|
||||
moneyOnCorpseStruct* d = (moneyOnCorpseStruct*)outapp->pBuffer;
|
||||
|
||||
d->response = static_cast<uint8>(LootResponse::Normal);
|
||||
d->unknown1 = 0x42;
|
||||
d->unknown2 = 0xef;
|
||||
d->response = static_cast<uint8>(LootResponse::Normal);
|
||||
d->unknown1 = 0x42;
|
||||
d->unknown2 = 0xef;
|
||||
|
||||
/* Dont take the coin off if it's a gm peeking at the corpse */
|
||||
if(Loot_Request_Type == 2 || (Loot_Request_Type >= 3 && loot_coin)) {
|
||||
if(!IsPlayerCorpse() && client->IsGrouped() && client->AutoSplitEnabled() && client->GetGroup()) {
|
||||
d->copper = 0;
|
||||
d->silver = 0;
|
||||
d->gold = 0;
|
||||
d->platinum = 0;
|
||||
Group *cgroup = client->GetGroup();
|
||||
cgroup->SplitMoney(GetCopper(), GetSilver(), GetGold(), GetPlatinum(), client);
|
||||
}
|
||||
else {
|
||||
d->copper = this->GetCopper();
|
||||
d->silver = this->GetSilver();
|
||||
d->gold = this->GetGold();
|
||||
d->platinum = this->GetPlatinum();
|
||||
client->AddMoneyToPP(GetCopper(), GetSilver(), GetGold(), GetPlatinum(), false);
|
||||
}
|
||||
d->copper = 0;
|
||||
d->silver = 0;
|
||||
d->gold = 0;
|
||||
d->platinum = 0;
|
||||
|
||||
RemoveCash();
|
||||
Save();
|
||||
}
|
||||
|
||||
auto timestamps = database.GetItemRecastTimestamps(client->CharacterID());
|
||||
outapp->priority = 6;
|
||||
client->QueuePacket(outapp);
|
||||
|
||||
safe_delete(outapp);
|
||||
if(Loot_Request_Type == 5) {
|
||||
int pkitem = GetPlayerKillItem();
|
||||
const EQEmu::ItemData* item = database.GetItem(pkitem);
|
||||
EQEmu::ItemInstance* inst = database.CreateItem(item, item->MaxCharges);
|
||||
if(inst) {
|
||||
if (item->RecastDelay)
|
||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||
client->SendItemPacket(EQEmu::invslot::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||
safe_delete(inst);
|
||||
}
|
||||
else { client->Message(13, "Could not find item number %i to send!!", GetPlayerKillItem()); }
|
||||
}
|
||||
else {
|
||||
auto outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct));
|
||||
moneyOnCorpseStruct* d = (moneyOnCorpseStruct*)outapp->pBuffer;
|
||||
|
||||
client->QueuePacket(app);
|
||||
return;
|
||||
d->response = static_cast<uint8>(LootResponse::Normal);
|
||||
d->unknown1 = 0x42;
|
||||
d->unknown2 = 0xef;
|
||||
|
||||
Group* cgroup = client->GetGroup();
|
||||
|
||||
// this can be reworked into a switch and/or massaged to include specialized pve loot rules based on 'LootRequestType'
|
||||
if (!IsPlayerCorpse() && client->IsGrouped() && client->AutoSplitEnabled() && cgroup) {
|
||||
d->copper = 0;
|
||||
d->silver = 0;
|
||||
d->gold = 0;
|
||||
d->platinum = 0;
|
||||
cgroup->SplitMoney(GetCopper(), GetSilver(), GetGold(), GetPlatinum(), client);
|
||||
}
|
||||
else {
|
||||
d->copper = GetCopper();
|
||||
d->silver = GetSilver();
|
||||
d->gold = GetGold();
|
||||
d->platinum = GetPlatinum();
|
||||
client->AddMoneyToPP(GetCopper(), GetSilver(), GetGold(), GetPlatinum(), false);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
const EQEmu::ItemData* item = nullptr;
|
||||
ItemList::iterator cur,end;
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
RemoveCash();
|
||||
Save();
|
||||
|
||||
int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToMobVersion(client->ClientVersion()))->InventoryTypeSize[EQEmu::invtype::typeCorpse];
|
||||
outapp->priority = 6;
|
||||
client->QueuePacket(outapp);
|
||||
|
||||
for(; cur != end; ++cur) {
|
||||
ServerLootItem_Struct* item_data = *cur;
|
||||
item_data->lootslot = 0xFFFF;
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
// Dont display the item if it's in a bag
|
||||
// process items
|
||||
auto timestamps = database.GetItemRecastTimestamps(client->CharacterID());
|
||||
|
||||
// Added cursor queue slots to corpse item visibility list. Nothing else should be making it to corpse.
|
||||
if (!IsPlayerCorpse() || item_data->equip_slot <= EQEmu::invslot::slotCursor || item_data->equip_slot == EQEmu::invslot::SLOT_POWER_SOURCE || Loot_Request_Type >= 3 ||
|
||||
(item_data->equip_slot >= 8000 && item_data->equip_slot <= 8999)) {
|
||||
if(i < corpselootlimit) {
|
||||
item = database.GetItem(item_data->item_id);
|
||||
if(client && item) {
|
||||
EQEmu::ItemInstance* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
|
||||
if(inst) {
|
||||
if (item->RecastDelay)
|
||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||
// SlotGeneral1 is the corpse inventory start offset for Ti(EMu) - CORPSE_END = SlotGeneral1 + SlotCursor
|
||||
client->SendItemPacket(i + EQEmu::invslot::CORPSE_BEGIN, inst, ItemPacketLoot);
|
||||
safe_delete(inst);
|
||||
}
|
||||
if (loot_request_type == LootRequestType::AllowedPVPDefined) {
|
||||
auto pkitemid = GetPlayerKillItem();
|
||||
auto pkitem = database.GetItem(pkitemid);
|
||||
auto pkinst = database.CreateItem(pkitem, pkitem->MaxCharges);
|
||||
|
||||
item_data->lootslot = i;
|
||||
}
|
||||
}
|
||||
if (pkinst) {
|
||||
if (pkitem->RecastDelay)
|
||||
pkinst->SetRecastTimestamp(timestamps.count(pkitem->RecastType) ? timestamps.at(pkitem->RecastType) : 0);
|
||||
|
||||
i++;
|
||||
}
|
||||
Log(Logs::Detail, Logs::Inventory, "MakeLootRequestPackets() Slot %u, Item '%s'", EQEmu::invslot::CORPSE_BEGIN, pkitem->Name);
|
||||
|
||||
client->SendItemPacket(EQEmu::invslot::CORPSE_BEGIN, pkinst, ItemPacketLoot);
|
||||
safe_delete(pkinst);
|
||||
}
|
||||
else {
|
||||
Log(Logs::General, Logs::Inventory, "MakeLootRequestPackets() PlayerKillItem %i not found", pkitemid);
|
||||
|
||||
client->Message(CC_Red, "PlayerKillItem (id: %i) could not be found!", pkitemid);
|
||||
}
|
||||
|
||||
if(IsPlayerCorpse() && (char_id == client->CharacterID() || client->GetGM())) {
|
||||
if(i > corpselootlimit) {
|
||||
client->Message(15, "*** This corpse contains more items than can be displayed! ***");
|
||||
client->Message(0, "Remove items and re-loot corpse to access remaining inventory.");
|
||||
client->Message(0, "(%s contains %i additional %s.)", GetName(), (i - corpselootlimit), (i - corpselootlimit) == 1 ? "item" : "items");
|
||||
}
|
||||
client->QueuePacket(app);
|
||||
return;
|
||||
}
|
||||
|
||||
if(IsPlayerCorpse() && i == 0 && itemlist.size() > 0) { // somehow, player corpse contains items, but client doesn't see them...
|
||||
client->Message(13, "This corpse contains items that are inaccessable!");
|
||||
client->Message(15, "Contact a GM for item replacement, if necessary.");
|
||||
client->Message(15, "BUGGED CORPSE [DBID: %i, Name: %s, Item Count: %i]", GetCorpseDBID(), GetName(), itemlist.size());
|
||||
auto loot_slot = EQEmu::invslot::CORPSE_BEGIN;
|
||||
auto corpse_mask = client->GetInv().GetLookup()->CorpseBitmask;
|
||||
|
||||
for (auto item_data : itemlist) {
|
||||
// every loot session must either set all items' lootslots to 'invslot::SLOT_INVALID'
|
||||
// or to a valid enumerated client-versioned corpse slot (lootslot is not equip_slot)
|
||||
item_data->lootslot = 0xFFFF;
|
||||
|
||||
// align server and client corpse slot mappings so translators can function properly
|
||||
while (loot_slot <= EQEmu::invslot::CORPSE_END && (((uint64)1 << loot_slot) & corpse_mask) == 0)
|
||||
++loot_slot;
|
||||
|
||||
if (loot_slot > EQEmu::invslot::CORPSE_END)
|
||||
continue;
|
||||
|
||||
cur = itemlist.begin();
|
||||
end = itemlist.end();
|
||||
for(; cur != end; ++cur) {
|
||||
ServerLootItem_Struct* item_data = *cur;
|
||||
item = database.GetItem(item_data->item_id);
|
||||
Log(Logs::General, Logs::None, "Corpse Looting: %s was not sent to client loot window (corpse_dbid: %i, charname: %s(%s))", item->Name, GetCorpseDBID(), client->GetName(), client->GetGM() ? "GM" : "Owner");
|
||||
client->Message(0, "Inaccessable Corpse Item: %s", item->Name);
|
||||
}
|
||||
}
|
||||
if (IsPlayerCorpse()) {
|
||||
if (loot_request_type == LootRequestType::AllowedPVPSingle && loot_slot != EQEmu::invslot::CORPSE_BEGIN)
|
||||
continue;
|
||||
|
||||
if (item_data->equip_slot < EQEmu::invslot::POSSESSIONS_BEGIN || item_data->equip_slot > EQEmu::invslot::POSSESSIONS_END)
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto *item = database.GetItem(item_data->item_id);
|
||||
auto inst = database.CreateItem(
|
||||
item,
|
||||
item_data->charges,
|
||||
item_data->aug_1,
|
||||
item_data->aug_2,
|
||||
item_data->aug_3,
|
||||
item_data->aug_4,
|
||||
item_data->aug_5,
|
||||
item_data->aug_6,
|
||||
item_data->attuned
|
||||
);
|
||||
if (!inst)
|
||||
continue;
|
||||
|
||||
if (item->RecastDelay)
|
||||
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
|
||||
|
||||
Log(Logs::Moderate, Logs::Inventory, "MakeLootRequestPackets() Slot %i, Item '%s'", loot_slot, item->Name);
|
||||
|
||||
client->SendItemPacket(loot_slot, inst, ItemPacketLoot);
|
||||
safe_delete(inst);
|
||||
|
||||
item_data->lootslot = loot_slot++;
|
||||
}
|
||||
|
||||
// Disgrace: Client seems to require that we send the packet back...
|
||||
@@ -1064,8 +1099,22 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
|
||||
|
||||
void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
{
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
auto lootitem = (LootingItem_Struct *)app->pBuffer;
|
||||
|
||||
Log(Logs::Moderate, Logs::Inventory, "LootItem() LootRequestType %u, Slot %u for %s", loot_request_type, lootitem->slot_id, client->GetName());
|
||||
|
||||
if (loot_request_type == LootRequestType::Forbidden) {
|
||||
client->QueuePacket(app);
|
||||
SendEndLootErrorPacket(client);
|
||||
// unlock corpse for others
|
||||
if (IsBeingLootedBy(client))
|
||||
ResetLooter();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!loot_cooldown_timer.Check()) {
|
||||
client->QueuePacket(app);
|
||||
SendEndLootErrorPacket(client);
|
||||
@@ -1093,7 +1142,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
if (IsPlayerCorpse() && !CanPlayerLoot(client->CharacterID()) && !become_npc &&
|
||||
(char_id != client->CharacterID() && client->Admin() < 150)) {
|
||||
(char_id != client->CharacterID() && client->Admin() < 150)) {
|
||||
client->Message(13, "Error: This is a player corpse and you dont own it.");
|
||||
client->QueuePacket(app);
|
||||
SendEndLootErrorPacket(client);
|
||||
@@ -1108,7 +1157,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
if (IsPlayerCorpse() && (char_id != client->CharacterID()) && CanPlayerLoot(client->CharacterID()) &&
|
||||
GetPlayerKillItem() == 0) {
|
||||
GetPlayerKillItem() == 0) {
|
||||
client->Message(13, "Error: You cannot loot any more items from this corpse.");
|
||||
client->QueuePacket(app);
|
||||
SendEndLootErrorPacket(client);
|
||||
@@ -1123,12 +1172,13 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
memset(bag_item_data, 0, sizeof(bag_item_data));
|
||||
if (GetPlayerKillItem() > 1) {
|
||||
item = database.GetItem(GetPlayerKillItem());
|
||||
} else if (GetPlayerKillItem() == -1 || GetPlayerKillItem() == 1) {
|
||||
}
|
||||
else if (GetPlayerKillItem() == -1 || GetPlayerKillItem() == 1) {
|
||||
item_data =
|
||||
GetItem(lootitem->slot_id -
|
||||
EQEmu::invslot::CORPSE_BEGIN); // dont allow them to loot entire bags of items as pvp reward
|
||||
} else {
|
||||
item_data = GetItem(lootitem->slot_id - EQEmu::invslot::CORPSE_BEGIN, bag_item_data);
|
||||
GetItem(lootitem->slot_id); // dont allow them to loot entire bags of items as pvp reward
|
||||
}
|
||||
else {
|
||||
item_data = GetItem(lootitem->slot_id, bag_item_data);
|
||||
}
|
||||
|
||||
if (GetPlayerKillItem() <= 1 && item_data != 0) {
|
||||
@@ -1138,9 +1188,10 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
if (item != 0) {
|
||||
if (item_data) {
|
||||
inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1,
|
||||
item_data->aug_2, item_data->aug_3, item_data->aug_4,
|
||||
item_data->aug_5, item_data->aug_6, item_data->attuned);
|
||||
} else {
|
||||
item_data->aug_2, item_data->aug_3, item_data->aug_4,
|
||||
item_data->aug_5, item_data->aug_6, item_data->attuned);
|
||||
}
|
||||
else {
|
||||
inst = database.CreateItem(item);
|
||||
}
|
||||
}
|
||||
@@ -1175,7 +1226,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
char q_corpse_name[64];
|
||||
strcpy(q_corpse_name, corpse_name);
|
||||
snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(),
|
||||
EntityList::RemoveNumbers(q_corpse_name));
|
||||
EntityList::RemoveNumbers(q_corpse_name));
|
||||
buf[87] = '\0';
|
||||
std::vector<EQEmu::Any> args;
|
||||
args.push_back(inst);
|
||||
@@ -1187,6 +1238,8 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
delete inst;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// do we want this to have a fail option too?
|
||||
parse->EventItem(EVENT_LOOT, client, inst, this, buf, 0);
|
||||
|
||||
@@ -1211,7 +1264,8 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
if (lootitem->auto_loot > 0) {
|
||||
if (!client->AutoPutLootInInventory(*inst, true, true, bag_item_data))
|
||||
client->PutLootInInventory(EQEmu::invslot::slotCursor, *inst, bag_item_data);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
client->PutLootInInventory(EQEmu::invslot::slotCursor, *inst, bag_item_data);
|
||||
}
|
||||
|
||||
@@ -1222,9 +1276,9 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
/* Remove it from Corpse */
|
||||
if (item_data) {
|
||||
/* Delete needs to be before RemoveItem because its deletes the pointer for
|
||||
* item_data/bag_item_data */
|
||||
* item_data/bag_item_data */
|
||||
database.DeleteItemOffCharacterCorpse(this->corpse_db_id, item_data->equip_slot,
|
||||
item_data->item_id);
|
||||
item_data->item_id);
|
||||
/* Delete Item Instance */
|
||||
RemoveItem(item_data->lootslot);
|
||||
}
|
||||
@@ -1234,10 +1288,10 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
for (int i = EQEmu::invbag::SLOT_BEGIN; i <= EQEmu::invbag::SLOT_END; i++) {
|
||||
if (bag_item_data[i]) {
|
||||
/* Delete needs to be before RemoveItem because its deletes the pointer for
|
||||
* item_data/bag_item_data */
|
||||
* item_data/bag_item_data */
|
||||
database.DeleteItemOffCharacterCorpse(this->corpse_db_id,
|
||||
bag_item_data[i]->equip_slot,
|
||||
bag_item_data[i]->item_id);
|
||||
bag_item_data[i]->equip_slot,
|
||||
bag_item_data[i]->item_id);
|
||||
/* Delete Item Instance */
|
||||
RemoveItem(bag_item_data[i]);
|
||||
}
|
||||
@@ -1261,16 +1315,18 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
Group *g = client->GetGroup();
|
||||
if (g != nullptr) {
|
||||
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE,
|
||||
client->GetName(), linker.Link().c_str());
|
||||
} else {
|
||||
client->GetName(), linker.Link().c_str());
|
||||
}
|
||||
else {
|
||||
Raid *r = client->GetRaid();
|
||||
if (r != nullptr) {
|
||||
r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE,
|
||||
client->GetName(), linker.Link().c_str());
|
||||
client->GetName(), linker.Link().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
SendEndLootErrorPacket(client);
|
||||
safe_delete(inst);
|
||||
return;
|
||||
@@ -1278,7 +1334,8 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
|
||||
if (IsPlayerCorpse()) {
|
||||
client->SendItemLink(inst);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
client->SendItemLink(inst, true);
|
||||
}
|
||||
|
||||
@@ -1457,7 +1514,7 @@ void Corpse::UpdateEquipmentLight()
|
||||
m_Light.Level[EQEmu::lightsource::LightEquipment] = 0;
|
||||
|
||||
for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
|
||||
if (((*iter)->equip_slot < EQEmu::invslot::EQUIPMENT_BEGIN || (*iter)->equip_slot > EQEmu::invslot::EQUIPMENT_END) && (*iter)->equip_slot != EQEmu::invslot::SLOT_POWER_SOURCE) { continue; }
|
||||
if ((*iter)->equip_slot < EQEmu::invslot::EQUIPMENT_BEGIN || (*iter)->equip_slot > EQEmu::invslot::EQUIPMENT_END) { continue; }
|
||||
if ((*iter)->equip_slot == EQEmu::invslot::slotAmmo) { continue; }
|
||||
|
||||
auto item = database.GetItem((*iter)->item_id);
|
||||
|
||||
+2
-1
@@ -116,7 +116,7 @@ class Corpse : public Mob {
|
||||
inline void Lock() { is_locked = true; }
|
||||
inline void UnLock() { is_locked = false; }
|
||||
inline bool IsLocked() { return is_locked; }
|
||||
inline void ResetLooter() { being_looted_by = 0xFFFFFFFF; }
|
||||
inline void ResetLooter() { being_looted_by = 0xFFFFFFFF; loot_request_type = LootRequestType::Forbidden; }
|
||||
inline bool IsBeingLooted() { return (being_looted_by != 0xFFFFFFFF); }
|
||||
inline bool IsBeingLootedBy(Client *c) { return being_looted_by == c->GetID(); }
|
||||
|
||||
@@ -161,6 +161,7 @@ private:
|
||||
Timer loot_cooldown_timer; /* Delay between loot actions on the corpse entity */
|
||||
EQEmu::TintProfile item_tint;
|
||||
|
||||
LootRequestType loot_request_type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -1128,9 +1128,9 @@ void PerlembParser::ExportItemVariables(std::string &package_name, Mob *mob) {
|
||||
std::string hashname = package_name + std::string("::oncursor");
|
||||
perl->eval(std::string("%").append(hashname).append(" = ();").c_str());
|
||||
char *hi_decl = nullptr;
|
||||
int itemid = mob->CastToClient()->GetItemIDAt(30);
|
||||
int itemid = mob->CastToClient()->GetItemIDAt(EQEmu::invslot::slotCursor);
|
||||
if(!HASITEM_ISNULLITEM(itemid)) {
|
||||
MakeAnyLenString(&hi_decl, "push (@{$%s{%d}},%d);",hashname.c_str(), itemid, 30);
|
||||
MakeAnyLenString(&hi_decl, "push (@{$%s{%d}},%d);",hashname.c_str(), itemid, EQEmu::invslot::slotCursor);
|
||||
perl->eval(hi_decl);
|
||||
safe_delete_array(hi_decl);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "zone.h"
|
||||
#include "data_bucket.h"
|
||||
|
||||
#include <cctype>
|
||||
|
||||
extern Zone *zone;
|
||||
extern QueryServ *QServ;
|
||||
|
||||
@@ -348,6 +350,83 @@ XS(XS__incstat) {
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__inventory);
|
||||
XS(XS__inventory) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: quest::inventory(string identifier)");
|
||||
|
||||
int16 RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
std::string identifier = (Const_char *)SvPV_nolen(ST(0));
|
||||
for (std::string::size_type i = 0; i < identifier.length(); ++i)
|
||||
identifier[i] = std::tolower(identifier[i]);
|
||||
|
||||
if (identifier == "invalid") RETVAL = EQEmu::invslot::SLOT_INVALID;
|
||||
else if (identifier == "cursor") RETVAL = EQEmu::invslot::slotCursor;
|
||||
else if (identifier == "possessions_begin") RETVAL = EQEmu::invslot::POSSESSIONS_BEGIN;
|
||||
else if (identifier == "possessions_end") RETVAL = EQEmu::invslot::POSSESSIONS_END;
|
||||
else if (identifier == "bank_begin") RETVAL = EQEmu::invslot::BANK_BEGIN;
|
||||
else if (identifier == "bank_end") RETVAL = EQEmu::invslot::BANK_END;
|
||||
else if (identifier == "sharedbank_begin") RETVAL = EQEmu::invslot::SHARED_BANK_BEGIN;
|
||||
else if (identifier == "sharedbank_end") RETVAL = EQEmu::invslot::SHARED_BANK_END;
|
||||
else if (identifier == "generalbags_begin") RETVAL = EQEmu::invbag::GENERAL_BAGS_BEGIN;
|
||||
else if (identifier == "generalbags_end") RETVAL = EQEmu::invbag::GENERAL_BAGS_END;
|
||||
else if (identifier == "cursorbag_begin") RETVAL = EQEmu::invbag::CURSOR_BAG_BEGIN;
|
||||
else if (identifier == "cursorbag_end") RETVAL = EQEmu::invbag::CURSOR_BAG_END;
|
||||
else if (identifier == "bankbags_begin") RETVAL = EQEmu::invbag::BANK_BAGS_BEGIN;
|
||||
else if (identifier == "bankbags_end") RETVAL = EQEmu::invbag::BANK_BAGS_END;
|
||||
else if (identifier == "sharedbankbags_begin") RETVAL = EQEmu::invbag::SHARED_BANK_BAGS_BEGIN;
|
||||
else if (identifier == "sharedbankbags_end") RETVAL = EQEmu::invbag::SHARED_BANK_BAGS_END;
|
||||
else if (identifier == "bagslot_begin") RETVAL = EQEmu::invbag::SLOT_BEGIN;
|
||||
else if (identifier == "bagslot_end") RETVAL = EQEmu::invbag::SLOT_END;
|
||||
else if (identifier == "augsocket_begin") RETVAL = EQEmu::invaug::SOCKET_BEGIN;
|
||||
else if (identifier == "augsocket_end") RETVAL = EQEmu::invaug::SOCKET_END;
|
||||
else if (identifier == "equipment_begin") RETVAL = EQEmu::invslot::EQUIPMENT_BEGIN;
|
||||
else if (identifier == "equipment_end") RETVAL = EQEmu::invslot::EQUIPMENT_END;
|
||||
else if (identifier == "general_begin") RETVAL = EQEmu::invslot::GENERAL_BEGIN;
|
||||
else if (identifier == "general_end") RETVAL = EQEmu::invslot::GENERAL_END;
|
||||
else if (identifier == "charm") RETVAL = EQEmu::invslot::slotCharm;
|
||||
else if (identifier == "ear1") RETVAL = EQEmu::invslot::slotEar1;
|
||||
else if (identifier == "head") RETVAL = EQEmu::invslot::slotHead;
|
||||
else if (identifier == "face") RETVAL = EQEmu::invslot::slotFace;
|
||||
else if (identifier == "ear2") RETVAL = EQEmu::invslot::slotEar2;
|
||||
else if (identifier == "neck") RETVAL = EQEmu::invslot::slotNeck;
|
||||
else if (identifier == "shoulders") RETVAL = EQEmu::invslot::slotShoulders;
|
||||
else if (identifier == "arms") RETVAL = EQEmu::invslot::slotArms;
|
||||
else if (identifier == "back") RETVAL = EQEmu::invslot::slotBack;
|
||||
else if (identifier == "wrist1") RETVAL = EQEmu::invslot::slotWrist1;
|
||||
else if (identifier == "wrist2") RETVAL = EQEmu::invslot::slotWrist2;
|
||||
else if (identifier == "range") RETVAL = EQEmu::invslot::slotRange;
|
||||
else if (identifier == "hands") RETVAL = EQEmu::invslot::slotHands;
|
||||
else if (identifier == "primary") RETVAL = EQEmu::invslot::slotPrimary;
|
||||
else if (identifier == "secondary") RETVAL = EQEmu::invslot::slotSecondary;
|
||||
else if (identifier == "finger1") RETVAL = EQEmu::invslot::slotFinger1;
|
||||
else if (identifier == "finger2") RETVAL = EQEmu::invslot::slotFinger2;
|
||||
else if (identifier == "chest") RETVAL = EQEmu::invslot::slotChest;
|
||||
else if (identifier == "legs") RETVAL = EQEmu::invslot::slotLegs;
|
||||
else if (identifier == "feet") RETVAL = EQEmu::invslot::slotFeet;
|
||||
else if (identifier == "waist") RETVAL = EQEmu::invslot::slotWaist;
|
||||
else if (identifier == "powersource") RETVAL = EQEmu::invslot::slotPowerSource;
|
||||
else if (identifier == "ammo") RETVAL = EQEmu::invslot::slotAmmo;
|
||||
else if (identifier == "general1") RETVAL = EQEmu::invslot::slotGeneral1;
|
||||
else if (identifier == "general2") RETVAL = EQEmu::invslot::slotGeneral2;
|
||||
else if (identifier == "general3") RETVAL = EQEmu::invslot::slotGeneral3;
|
||||
else if (identifier == "general4") RETVAL = EQEmu::invslot::slotGeneral4;
|
||||
else if (identifier == "general5") RETVAL = EQEmu::invslot::slotGeneral5;
|
||||
else if (identifier == "general6") RETVAL = EQEmu::invslot::slotGeneral6;
|
||||
else if (identifier == "general7") RETVAL = EQEmu::invslot::slotGeneral7;
|
||||
else if (identifier == "general8") RETVAL = EQEmu::invslot::slotGeneral8;
|
||||
else if (identifier == "general9") RETVAL = EQEmu::invslot::slotGeneral9;
|
||||
else if (identifier == "general10") RETVAL = EQEmu::invslot::slotGeneral10;
|
||||
else RETVAL = EQEmu::invslot::SLOT_INVALID;
|
||||
|
||||
XSprePUSH; PUSHu((IV)RETVAL);
|
||||
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__castspell);
|
||||
XS(XS__castspell) {
|
||||
dXSARGS;
|
||||
@@ -3683,6 +3762,7 @@ EXTERN_C XS(boot_quest) {
|
||||
newXS(strcpy(buf, "gmsay"), XS__gmsay, file);
|
||||
newXS(strcpy(buf, "has_zone_flag"), XS__has_zone_flag, file);
|
||||
newXS(strcpy(buf, "incstat"), XS__incstat, file);
|
||||
newXS(strcpy(buf, "inventory"), XS__inventory, file);
|
||||
newXS(strcpy(buf, "isdisctome"), XS__isdisctome, file);
|
||||
newXS(strcpy(buf, "isdooropen"), XS__isdooropen, file);
|
||||
newXS(strcpy(buf, "istaskactive"), XS__istaskactive, file);
|
||||
|
||||
+273
-122
@@ -44,23 +44,9 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
|
||||
x++;
|
||||
}
|
||||
|
||||
DeleteItemInInventory(i, 0, true);
|
||||
DeleteItemInInventory(i, 0, ((((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask) != 0));
|
||||
}
|
||||
}
|
||||
|
||||
if (GetItemIDAt(EQEmu::invslot::SLOT_POWER_SOURCE) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(EQEmu::invslot::SLOT_POWER_SOURCE) != INVALID_ID)) {
|
||||
cur = m_inv.GetItem(EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
if(cur && cur->GetItem()->Stackable) {
|
||||
x += cur->GetCharges();
|
||||
} else {
|
||||
x++;
|
||||
}
|
||||
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
|
||||
DeleteItemInInventory(EQEmu::invslot::SLOT_POWER_SOURCE, 0, true);
|
||||
else
|
||||
DeleteItemInInventory(EQEmu::invslot::SLOT_POWER_SOURCE, 0, false); // Prevents Titanium crash
|
||||
}
|
||||
}
|
||||
|
||||
if(where_to_check & invWhereCursor) {
|
||||
@@ -99,7 +85,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
|
||||
x++;
|
||||
}
|
||||
|
||||
DeleteItemInInventory(i, 0, true);
|
||||
DeleteItemInInventory(i, 0, ((((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask) != 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +98,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
|
||||
x++;
|
||||
}
|
||||
|
||||
DeleteItemInInventory(i, 0, true);
|
||||
DeleteItemInInventory(i, 0, ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((i - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) == 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,7 +113,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
|
||||
x++;
|
||||
}
|
||||
|
||||
DeleteItemInInventory(i, 0, true);
|
||||
DeleteItemInInventory(i, 0, ((i - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +126,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
|
||||
x++;
|
||||
}
|
||||
|
||||
DeleteItemInInventory(i, 0, true);
|
||||
DeleteItemInInventory(i, 0, (((i - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -554,8 +540,8 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
|
||||
inst->SetOrnamentHeroModel(ornament_hero_model);
|
||||
|
||||
// check to see if item is usable in requested slot
|
||||
if (enforceusable && (((to_slot >= EQEmu::invslot::slotCharm) && (to_slot <= EQEmu::invslot::slotAmmo)) || (to_slot == EQEmu::invslot::SLOT_POWER_SOURCE))) {
|
||||
uint32 slottest = (to_slot == EQEmu::invslot::SLOT_POWER_SOURCE) ? 22 : to_slot; // can't change '22' just yet...
|
||||
if (enforceusable && (to_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && to_slot <= EQEmu::invslot::EQUIPMENT_END)) {
|
||||
uint32 slottest = to_slot;
|
||||
|
||||
if(!(slots & ((uint32)1 << slottest))) {
|
||||
Message(0, "This item is not equipable at slot %u - moving to cursor.", to_slot);
|
||||
@@ -716,6 +702,25 @@ void Client::DropInst(const EQEmu::ItemInstance* inst)
|
||||
|
||||
// Returns a slot's item ID (returns INVALID_ID if not found)
|
||||
int32 Client::GetItemIDAt(int16 slot_id) {
|
||||
if (slot_id <= EQEmu::invslot::POSSESSIONS_END && slot_id >= EQEmu::invslot::POSSESSIONS_BEGIN) {
|
||||
if ((((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
||||
return INVALID_ID;
|
||||
}
|
||||
else if (slot_id <= EQEmu::invbag::GENERAL_BAGS_END && slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN) {
|
||||
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
|
||||
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
||||
return INVALID_ID;
|
||||
}
|
||||
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
|
||||
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
|
||||
return INVALID_ID;
|
||||
}
|
||||
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
|
||||
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
|
||||
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
|
||||
return INVALID_ID;
|
||||
}
|
||||
|
||||
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
||||
if (inst)
|
||||
return inst->GetItem()->ID;
|
||||
@@ -727,6 +732,25 @@ int32 Client::GetItemIDAt(int16 slot_id) {
|
||||
// Returns an augment's ID that's in an item (returns INVALID_ID if not found)
|
||||
// Pass in the slot ID of the item and which augslot you want to check (0-5)
|
||||
int32 Client::GetAugmentIDAt(int16 slot_id, uint8 augslot) {
|
||||
if (slot_id <= EQEmu::invslot::POSSESSIONS_END && slot_id >= EQEmu::invslot::POSSESSIONS_BEGIN) {
|
||||
if ((((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
||||
return INVALID_ID;
|
||||
}
|
||||
else if (slot_id <= EQEmu::invbag::GENERAL_BAGS_END && slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN) {
|
||||
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
|
||||
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
||||
return INVALID_ID;
|
||||
}
|
||||
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
|
||||
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
|
||||
return INVALID_ID;
|
||||
}
|
||||
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
|
||||
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
|
||||
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
|
||||
return INVALID_ID;
|
||||
}
|
||||
|
||||
const EQEmu::ItemInstance* inst = m_inv[slot_id];
|
||||
if (inst && inst->GetAugmentItemID(augslot)) {
|
||||
return inst->GetAugmentItemID(augslot);
|
||||
@@ -963,7 +987,7 @@ void Client::PutLootInInventory(int16 slot_id, const EQEmu::ItemInstance &inst,
|
||||
}
|
||||
|
||||
if (bag_item_data) {
|
||||
for (int index = 0; index < EQEmu::invbag::SLOT_COUNT; ++index) {
|
||||
for (int index = EQEmu::invbag::SLOT_BEGIN; index <= EQEmu::invbag::SLOT_END; ++index) {
|
||||
if (bag_item_data[index] == nullptr)
|
||||
continue;
|
||||
|
||||
@@ -1003,12 +1027,15 @@ void Client::PutLootInInventory(int16 slot_id, const EQEmu::ItemInstance &inst,
|
||||
|
||||
CalcBonuses();
|
||||
}
|
||||
bool Client::TryStacking(EQEmu::ItemInstance* item, uint8 type, bool try_worn, bool try_cursor){
|
||||
bool Client::TryStacking(EQEmu::ItemInstance* item, uint8 type, bool try_worn, bool try_cursor) {
|
||||
if(!item || !item->IsStackable() || item->GetCharges()>=item->GetItem()->StackSize)
|
||||
return false;
|
||||
int16 i;
|
||||
uint32 item_id = item->GetItem()->ID;
|
||||
for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) {
|
||||
if (((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue;
|
||||
|
||||
EQEmu::ItemInstance* tmp_inst = m_inv.GetItem(i);
|
||||
if(tmp_inst && tmp_inst->GetItem()->ID == item_id && tmp_inst->GetCharges() < tmp_inst->GetItem()->StackSize){
|
||||
MoveItemCharges(*item, i, type);
|
||||
@@ -1020,6 +1047,9 @@ bool Client::TryStacking(EQEmu::ItemInstance* item, uint8 type, bool try_worn, b
|
||||
}
|
||||
}
|
||||
for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) {
|
||||
if (((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue;
|
||||
|
||||
for (uint8 j = EQEmu::invbag::SLOT_BEGIN; j <= EQEmu::invbag::SLOT_END; j++) {
|
||||
uint16 slotid = EQEmu::InventoryProfile::CalcSlotId(i, j);
|
||||
EQEmu::ItemInstance* tmp_inst = m_inv.GetItem(slotid);
|
||||
@@ -1044,15 +1074,9 @@ bool Client::AutoPutLootInInventory(EQEmu::ItemInstance& inst, bool try_worn, bo
|
||||
{
|
||||
// #1: Try to auto equip
|
||||
if (try_worn && inst.IsEquipable(GetBaseRace(), GetClass()) && inst.GetItem()->ReqLevel <= level && (!inst.GetItem()->Attuneable || inst.IsAttuned()) && inst.GetItem()->ItemType != EQEmu::item::ItemTypeAugmentation) {
|
||||
// too messy as-is... <watch>
|
||||
for (int16 i = EQEmu::invslot::EQUIPMENT_BEGIN; i < EQEmu::invslot::SLOT_POWER_SOURCE; i++) { // originally (i < 22)
|
||||
if (i == EQEmu::invslot::GENERAL_BEGIN) {
|
||||
// added power source check for SoF+ clients
|
||||
if (this->ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
|
||||
i = EQEmu::invslot::SLOT_POWER_SOURCE;
|
||||
else
|
||||
break;
|
||||
}
|
||||
for (int16 i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++) {
|
||||
if (((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue;
|
||||
|
||||
if (!m_inv[i]) {
|
||||
if (i == EQEmu::invslot::slotPrimary && inst.IsWeapon()) { // If item is primary slot weapon
|
||||
@@ -1373,23 +1397,34 @@ void Client::SendLootItemInPacket(const EQEmu::ItemInstance* inst, int16 slot_id
|
||||
}
|
||||
|
||||
bool Client::IsValidSlot(uint32 slot) {
|
||||
if ((slot == (uint32)INVALID_INDEX) ||
|
||||
(slot >= EQEmu::invslot::POSSESSIONS_BEGIN && slot <= EQEmu::invslot::POSSESSIONS_END) ||
|
||||
(slot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && slot <= EQEmu::invbag::CURSOR_BAG_END) ||
|
||||
(slot >= EQEmu::invslot::TRIBUTE_BEGIN && slot <= EQEmu::invslot::TRIBUTE_END) ||
|
||||
(slot >= EQEmu::invslot::BANK_BEGIN && slot <= EQEmu::invslot::BANK_END) ||
|
||||
(slot >= EQEmu::invbag::BANK_BAGS_BEGIN && slot <= EQEmu::invbag::BANK_BAGS_END) ||
|
||||
(slot >= EQEmu::invslot::SHARED_BANK_BEGIN && slot <= EQEmu::invslot::SHARED_BANK_END) ||
|
||||
(slot >= EQEmu::invbag::SHARED_BANK_BAGS_BEGIN && slot <= EQEmu::invbag::SHARED_BANK_BAGS_END) ||
|
||||
(slot >= EQEmu::invslot::TRADE_BEGIN && slot <= EQEmu::invslot::TRADE_END) ||
|
||||
(slot >= EQEmu::invslot::WORLD_BEGIN && slot <= EQEmu::invslot::WORLD_END) ||
|
||||
(slot == EQEmu::invslot::SLOT_POWER_SOURCE)
|
||||
) {
|
||||
if (slot <= EQEmu::invslot::POSSESSIONS_END && slot >= EQEmu::invslot::POSSESSIONS_BEGIN) {
|
||||
return ((((uint64)1 << slot) & GetInv().GetLookup()->PossessionsBitmask) != 0);
|
||||
}
|
||||
else if (slot <= EQEmu::invbag::GENERAL_BAGS_END && slot >= EQEmu::invbag::GENERAL_BAGS_BEGIN) {
|
||||
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
|
||||
return ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) != 0);
|
||||
}
|
||||
else if (slot <= EQEmu::invslot::BANK_END && slot >= EQEmu::invslot::BANK_BEGIN) {
|
||||
return ((slot - EQEmu::invslot::BANK_BEGIN) < GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]);
|
||||
}
|
||||
else if (slot <= EQEmu::invbag::BANK_BAGS_END && slot >= EQEmu::invbag::BANK_BAGS_BEGIN) {
|
||||
auto temp_slot = (slot - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
|
||||
return (temp_slot < GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]);
|
||||
}
|
||||
else if (
|
||||
(slot == (uint32)INVALID_INDEX) ||
|
||||
(slot == (uint32)EQEmu::invslot::slotCursor) ||
|
||||
(slot <= EQEmu::invbag::CURSOR_BAG_END && slot >= EQEmu::invbag::CURSOR_BAG_BEGIN) ||
|
||||
(slot <= EQEmu::invslot::TRIBUTE_END && slot >= EQEmu::invslot::TRIBUTE_BEGIN) ||
|
||||
(slot <= EQEmu::invslot::SHARED_BANK_END && slot >= EQEmu::invslot::SHARED_BANK_BEGIN) ||
|
||||
(slot <= EQEmu::invbag::SHARED_BANK_BAGS_END && slot >= EQEmu::invbag::SHARED_BANK_BAGS_BEGIN) ||
|
||||
(slot <= EQEmu::invslot::TRADE_END && slot >= EQEmu::invslot::TRADE_BEGIN) ||
|
||||
(slot <= EQEmu::invslot::WORLD_END && slot >= EQEmu::invslot::WORLD_BEGIN)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Client::IsBankSlot(uint32 slot)
|
||||
@@ -1481,10 +1516,14 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
return true; // Item deletion
|
||||
}
|
||||
}
|
||||
if (auto_attack && (move_in->from_slot == EQEmu::invslot::slotPrimary || move_in->from_slot == EQEmu::invslot::slotSecondary || move_in->from_slot == EQEmu::invslot::slotRange))
|
||||
SetAttackTimer();
|
||||
else if (auto_attack && (move_in->to_slot == EQEmu::invslot::slotPrimary || move_in->to_slot == EQEmu::invslot::slotSecondary || move_in->to_slot == EQEmu::invslot::slotRange))
|
||||
SetAttackTimer();
|
||||
|
||||
if (auto_attack) {
|
||||
if (move_in->from_slot == EQEmu::invslot::slotPrimary || move_in->from_slot == EQEmu::invslot::slotSecondary || move_in->from_slot == EQEmu::invslot::slotRange)
|
||||
SetAttackTimer();
|
||||
else if (move_in->to_slot == EQEmu::invslot::slotPrimary || move_in->to_slot == EQEmu::invslot::slotSecondary || move_in->to_slot == EQEmu::invslot::slotRange)
|
||||
SetAttackTimer();
|
||||
}
|
||||
|
||||
// Step 1: Variables
|
||||
int16 src_slot_id = (int16)move_in->from_slot;
|
||||
int16 dst_slot_id = (int16)move_in->to_slot;
|
||||
@@ -1530,13 +1569,11 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
uint32 srcbagid =0;
|
||||
uint32 dstbagid = 0;
|
||||
|
||||
//if (src_slot_id >= 250 && src_slot_id < 330) {
|
||||
if (src_slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN && src_slot_id <= EQEmu::invbag::GENERAL_BAGS_END) {
|
||||
srcbag = m_inv.GetItem(((int)(src_slot_id / 10)) - 3);
|
||||
if (srcbag)
|
||||
srcbagid = srcbag->GetItem()->ID;
|
||||
}
|
||||
//if (dst_slot_id >= 250 && dst_slot_id < 330) {
|
||||
if (dst_slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN && dst_slot_id <= EQEmu::invbag::GENERAL_BAGS_END) {
|
||||
dstbag = m_inv.GetItem(((int)(dst_slot_id / 10)) - 3);
|
||||
if (dstbag)
|
||||
@@ -1808,7 +1845,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
}
|
||||
else {
|
||||
// Not dealing with charges - just do direct swap
|
||||
if (src_inst && (dst_slot_id <= EQEmu::invslot::EQUIPMENT_END || dst_slot_id == EQEmu::invslot::SLOT_POWER_SOURCE) && dst_slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN) {
|
||||
if (src_inst && (dst_slot_id <= EQEmu::invslot::EQUIPMENT_END) && dst_slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN) {
|
||||
if (src_inst->GetItem()->Attuneable) {
|
||||
src_inst->SetAttuned(true);
|
||||
}
|
||||
@@ -1840,7 +1877,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
|
||||
Log(Logs::Detail, Logs::Inventory, "Moving entire item from slot %d to slot %d", src_slot_id, dst_slot_id);
|
||||
|
||||
if (src_slot_id <= EQEmu::invslot::EQUIPMENT_END || src_slot_id == EQEmu::invslot::SLOT_POWER_SOURCE) {
|
||||
if (src_slot_id <= EQEmu::invslot::EQUIPMENT_END) {
|
||||
if(src_inst) {
|
||||
parse->EventItem(EVENT_UNEQUIP_ITEM, this, src_inst, nullptr, "", src_slot_id);
|
||||
}
|
||||
@@ -1850,7 +1887,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
}
|
||||
}
|
||||
|
||||
if (dst_slot_id <= EQEmu::invslot::EQUIPMENT_END || dst_slot_id == EQEmu::invslot::SLOT_POWER_SOURCE) {
|
||||
if (dst_slot_id <= EQEmu::invslot::EQUIPMENT_END) {
|
||||
if(dst_inst) {
|
||||
parse->EventItem(EVENT_UNEQUIP_ITEM, this, dst_inst, nullptr, "", dst_slot_id);
|
||||
}
|
||||
@@ -1904,7 +1941,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) {
|
||||
Log(Logs::Detail, Logs::Inventory, "Inventory desyncronization. (charname: %s, source: %i, destination: %i)", GetName(), move_slots->from_slot, move_slots->to_slot);
|
||||
Message(15, "Inventory Desyncronization detected: Resending slot data...");
|
||||
|
||||
if ((move_slots->from_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->from_slot <= EQEmu::invbag::CURSOR_BAG_END) || move_slots->from_slot == EQEmu::invslot::SLOT_POWER_SOURCE) {
|
||||
if (move_slots->from_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->from_slot <= EQEmu::invbag::CURSOR_BAG_END) {
|
||||
int16 resync_slot = (EQEmu::InventoryProfile::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : EQEmu::InventoryProfile::CalcSlotId(move_slots->from_slot);
|
||||
if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) {
|
||||
// This prevents the client from crashing when closing any 'phantom' bags
|
||||
@@ -1947,7 +1984,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) {
|
||||
else { Message(13, "Could not resyncronize source slot %i.", move_slots->from_slot); }
|
||||
}
|
||||
|
||||
if ((move_slots->to_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->to_slot <= EQEmu::invbag::CURSOR_BAG_END) || move_slots->to_slot == EQEmu::invslot::SLOT_POWER_SOURCE) {
|
||||
if (move_slots->to_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->to_slot <= EQEmu::invbag::CURSOR_BAG_END) {
|
||||
int16 resync_slot = (EQEmu::InventoryProfile::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : EQEmu::InventoryProfile::CalcSlotId(move_slots->to_slot);
|
||||
if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) {
|
||||
const EQEmu::ItemData* token_struct = database.GetItem(22292); // 'Copper Coin'
|
||||
@@ -2182,47 +2219,118 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) {
|
||||
EQEmu::ItemInstance* ins = nullptr;
|
||||
int x;
|
||||
int num = 0;
|
||||
for(x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invbag::GENERAL_BAGS_END; x++)
|
||||
{
|
||||
if (x == EQEmu::invslot::slotCursor + 1)
|
||||
x = EQEmu::invbag::GENERAL_BAGS_BEGIN;
|
||||
|
||||
for (x = EQEmu::invslot::POSSESSIONS_BEGIN; x <= EQEmu::invslot::POSSESSIONS_END; ++x) {
|
||||
if (num >= amt)
|
||||
break;
|
||||
if (((uint64)1 << x) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue;
|
||||
|
||||
TempItem = nullptr;
|
||||
ins = GetInv().GetItem(x);
|
||||
if (ins)
|
||||
TempItem = ins->GetItem();
|
||||
if (TempItem && TempItem->ID == type)
|
||||
{
|
||||
num += ins->GetCharges();
|
||||
if (num >= amt)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = EQEmu::invbag::GENERAL_BAGS_BEGIN; x <= EQEmu::invbag::GENERAL_BAGS_END; ++x) {
|
||||
if (num >= amt)
|
||||
break;
|
||||
if ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((x - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
||||
continue;
|
||||
|
||||
TempItem = nullptr;
|
||||
ins = GetInv().GetItem(x);
|
||||
if (ins)
|
||||
TempItem = ins->GetItem();
|
||||
if (TempItem && TempItem->ID == type)
|
||||
num += ins->GetCharges();
|
||||
}
|
||||
|
||||
for (x = EQEmu::invbag::CURSOR_BAG_BEGIN; x <= EQEmu::invbag::CURSOR_BAG_END; ++x) {
|
||||
if (num >= amt)
|
||||
break;
|
||||
|
||||
TempItem = nullptr;
|
||||
ins = GetInv().GetItem(x);
|
||||
if (ins)
|
||||
TempItem = ins->GetItem();
|
||||
if (TempItem && TempItem->ID == type)
|
||||
num += ins->GetCharges();
|
||||
}
|
||||
|
||||
if (num < amt)
|
||||
return false;
|
||||
for(x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invbag::GENERAL_BAGS_END; x++) // should this be CURSOR_BAG_END?
|
||||
{
|
||||
if (x == EQEmu::invslot::slotCursor + 1)
|
||||
x = EQEmu::invbag::GENERAL_BAGS_BEGIN;
|
||||
|
||||
|
||||
for (x = EQEmu::invslot::POSSESSIONS_BEGIN; x <= EQEmu::invslot::POSSESSIONS_END; ++x) {
|
||||
if (amt < 1)
|
||||
break;
|
||||
if (((uint64)1 << x) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue;
|
||||
|
||||
TempItem = nullptr;
|
||||
ins = GetInv().GetItem(x);
|
||||
if (ins)
|
||||
TempItem = ins->GetItem();
|
||||
if (TempItem && TempItem->ID == type)
|
||||
{
|
||||
if (ins->GetCharges() < amt)
|
||||
{
|
||||
amt -= ins->GetCharges();
|
||||
DeleteItemInInventory(x,amt,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeleteItemInInventory(x,amt,true);
|
||||
amt = 0;
|
||||
}
|
||||
if (amt < 1)
|
||||
break;
|
||||
if (TempItem && TempItem->ID != type)
|
||||
continue;
|
||||
|
||||
if (ins->GetCharges() < amt) {
|
||||
amt -= ins->GetCharges();
|
||||
DeleteItemInInventory(x, amt, true);
|
||||
}
|
||||
else {
|
||||
DeleteItemInInventory(x, amt, true);
|
||||
amt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = EQEmu::invbag::GENERAL_BAGS_BEGIN; x <= EQEmu::invbag::GENERAL_BAGS_END; ++x) {
|
||||
if (amt < 1)
|
||||
break;
|
||||
if ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((x - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
||||
continue;
|
||||
|
||||
TempItem = nullptr;
|
||||
ins = GetInv().GetItem(x);
|
||||
if (ins)
|
||||
TempItem = ins->GetItem();
|
||||
if (TempItem && TempItem->ID != type)
|
||||
continue;
|
||||
|
||||
if (ins->GetCharges() < amt) {
|
||||
amt -= ins->GetCharges();
|
||||
DeleteItemInInventory(x, amt, true);
|
||||
}
|
||||
else {
|
||||
DeleteItemInInventory(x, amt, true);
|
||||
amt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = EQEmu::invbag::CURSOR_BAG_BEGIN; x <= EQEmu::invbag::CURSOR_BAG_END; ++x) {
|
||||
if (amt < 1)
|
||||
break;
|
||||
|
||||
TempItem = nullptr;
|
||||
ins = GetInv().GetItem(x);
|
||||
if (ins)
|
||||
TempItem = ins->GetItem();
|
||||
if (TempItem && TempItem->ID != type)
|
||||
continue;
|
||||
|
||||
if (ins->GetCharges() < amt) {
|
||||
amt -= ins->GetCharges();
|
||||
DeleteItemInInventory(x, amt, true);
|
||||
}
|
||||
else {
|
||||
DeleteItemInInventory(x, amt, true);
|
||||
amt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2299,6 +2407,9 @@ static bool CopyBagContents(EQEmu::ItemInstance* new_bag, const EQEmu::ItemInsta
|
||||
void Client::DisenchantSummonedBags(bool client_update)
|
||||
{
|
||||
for (auto slot_id = EQEmu::invslot::GENERAL_BEGIN; slot_id <= EQEmu::invslot::GENERAL_END; ++slot_id) {
|
||||
if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue; // not useable this session - will be disenchanted once player logs in on client that doesn't exclude affected slots
|
||||
|
||||
auto inst = m_inv[slot_id];
|
||||
if (!inst) { continue; }
|
||||
if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; }
|
||||
@@ -2320,6 +2431,9 @@ void Client::DisenchantSummonedBags(bool client_update)
|
||||
}
|
||||
|
||||
for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) {
|
||||
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
|
||||
continue;
|
||||
|
||||
auto inst = m_inv[slot_id];
|
||||
if (!inst) { continue; }
|
||||
if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; }
|
||||
@@ -2410,6 +2524,9 @@ void Client::DisenchantSummonedBags(bool client_update)
|
||||
void Client::RemoveNoRent(bool client_update)
|
||||
{
|
||||
for (auto slot_id = EQEmu::invslot::EQUIPMENT_BEGIN; slot_id <= EQEmu::invslot::EQUIPMENT_END; ++slot_id) {
|
||||
if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue;
|
||||
|
||||
auto inst = m_inv[slot_id];
|
||||
if(inst && !inst->GetItem()->NoRent) {
|
||||
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
|
||||
@@ -2418,6 +2535,9 @@ void Client::RemoveNoRent(bool client_update)
|
||||
}
|
||||
|
||||
for (auto slot_id = EQEmu::invslot::GENERAL_BEGIN; slot_id <= EQEmu::invslot::GENERAL_END; ++slot_id) {
|
||||
if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue;
|
||||
|
||||
auto inst = m_inv[slot_id];
|
||||
if (inst && !inst->GetItem()->NoRent) {
|
||||
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
|
||||
@@ -2425,15 +2545,11 @@ void Client::RemoveNoRent(bool client_update)
|
||||
}
|
||||
}
|
||||
|
||||
if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]) {
|
||||
auto inst = m_inv[EQEmu::invslot::SLOT_POWER_SOURCE];
|
||||
if (inst && !inst->GetItem()->NoRent) {
|
||||
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
DeleteItemInInventory(EQEmu::invslot::SLOT_POWER_SOURCE, 0, (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) ? client_update : false); // Ti slot non-existent
|
||||
}
|
||||
}
|
||||
|
||||
for (auto slot_id = EQEmu::invbag::GENERAL_BAGS_BEGIN; slot_id <= EQEmu::invbag::CURSOR_BAG_END; ++slot_id) {
|
||||
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
|
||||
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
||||
continue;
|
||||
|
||||
auto inst = m_inv[slot_id];
|
||||
if(inst && !inst->GetItem()->NoRent) {
|
||||
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
|
||||
@@ -2442,6 +2558,9 @@ void Client::RemoveNoRent(bool client_update)
|
||||
}
|
||||
|
||||
for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) {
|
||||
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
|
||||
continue;
|
||||
|
||||
auto inst = m_inv[slot_id];
|
||||
if(inst && !inst->GetItem()->NoRent) {
|
||||
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
|
||||
@@ -2450,6 +2569,10 @@ void Client::RemoveNoRent(bool client_update)
|
||||
}
|
||||
|
||||
for (auto slot_id = EQEmu::invbag::BANK_BAGS_BEGIN; slot_id <= EQEmu::invbag::BANK_BAGS_END; ++slot_id) {
|
||||
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
|
||||
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
|
||||
continue;
|
||||
|
||||
auto inst = m_inv[slot_id];
|
||||
if(inst && !inst->GetItem()->NoRent) {
|
||||
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
|
||||
@@ -2504,6 +2627,9 @@ void Client::RemoveNoRent(bool client_update)
|
||||
void Client::RemoveDuplicateLore(bool client_update)
|
||||
{
|
||||
for (auto slot_id = EQEmu::invslot::EQUIPMENT_BEGIN; slot_id <= EQEmu::invslot::EQUIPMENT_END; ++slot_id) {
|
||||
if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue;
|
||||
|
||||
auto inst = m_inv.PopItem(slot_id);
|
||||
if (inst == nullptr) { continue; }
|
||||
if(CheckLoreConflict(inst->GetItem())) {
|
||||
@@ -2517,6 +2643,9 @@ void Client::RemoveDuplicateLore(bool client_update)
|
||||
}
|
||||
|
||||
for (auto slot_id = EQEmu::invslot::GENERAL_BEGIN; slot_id <= EQEmu::invslot::GENERAL_END; ++slot_id) {
|
||||
if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue;
|
||||
|
||||
auto inst = m_inv.PopItem(slot_id);
|
||||
if (inst == nullptr) { continue; }
|
||||
if (CheckLoreConflict(inst->GetItem())) {
|
||||
@@ -2529,21 +2658,11 @@ void Client::RemoveDuplicateLore(bool client_update)
|
||||
safe_delete(inst);
|
||||
}
|
||||
|
||||
if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]) {
|
||||
auto inst = m_inv.PopItem(EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
if (inst) {
|
||||
if (CheckLoreConflict(inst->GetItem())) {
|
||||
Log(Logs::Detail, Logs::Inventory, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
database.SaveInventory(character_id, nullptr, EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
}
|
||||
else {
|
||||
m_inv.PutItem(EQEmu::invslot::SLOT_POWER_SOURCE, *inst);
|
||||
}
|
||||
safe_delete(inst);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto slot_id = EQEmu::invbag::GENERAL_BAGS_BEGIN; slot_id <= EQEmu::invbag::CURSOR_BAG_END; ++slot_id) {
|
||||
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
|
||||
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
||||
continue;
|
||||
|
||||
auto inst = m_inv.PopItem(slot_id);
|
||||
if (inst == nullptr) { continue; }
|
||||
if(CheckLoreConflict(inst->GetItem())) {
|
||||
@@ -2557,6 +2676,9 @@ void Client::RemoveDuplicateLore(bool client_update)
|
||||
}
|
||||
|
||||
for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) {
|
||||
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
|
||||
continue;
|
||||
|
||||
auto inst = m_inv.PopItem(slot_id);
|
||||
if (inst == nullptr) { continue; }
|
||||
if(CheckLoreConflict(inst->GetItem())) {
|
||||
@@ -2570,6 +2692,10 @@ void Client::RemoveDuplicateLore(bool client_update)
|
||||
}
|
||||
|
||||
for (auto slot_id = EQEmu::invbag::BANK_BAGS_BEGIN; slot_id <= EQEmu::invbag::BANK_BAGS_END; ++slot_id) {
|
||||
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
|
||||
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
|
||||
continue;
|
||||
|
||||
auto inst = m_inv.PopItem(slot_id);
|
||||
if (inst == nullptr) { continue; }
|
||||
if(CheckLoreConflict(inst->GetItem())) {
|
||||
@@ -2642,15 +2768,21 @@ void Client::MoveSlotNotAllowed(bool client_update)
|
||||
}
|
||||
}
|
||||
|
||||
if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE] && !m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]->IsSlotAllowed(EQEmu::invslot::SLOT_POWER_SOURCE)) {
|
||||
auto inst = m_inv.PopItem(EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
bool is_arrow = (inst->GetItem()->ItemType == EQEmu::item::ItemTypeArrow) ? true : false;
|
||||
int16 free_slot_id = m_inv.FindFreeSlot(inst->IsClassBag(), true, inst->GetItem()->Size, is_arrow);
|
||||
Log(Logs::Detail, Logs::Inventory, "Slot Assignment Error: Moving %s from slot %i to %i", inst->GetItem()->Name, EQEmu::invslot::SLOT_POWER_SOURCE, free_slot_id);
|
||||
PutItemInInventory(free_slot_id, *inst, (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) ? client_update : false);
|
||||
database.SaveInventory(character_id, nullptr, EQEmu::invslot::SLOT_POWER_SOURCE);
|
||||
safe_delete(inst);
|
||||
}
|
||||
// added this check to move any client-based excluded slots
|
||||
//for (auto slot_id = EQEmu::invslot::POSSESSIONS_BEGIN; slot_id <= EQEmu::invslot::POSSESSIONS_END; ++slot_id) {
|
||||
// if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask != 0)
|
||||
// continue;
|
||||
|
||||
// if (m_inv[slot_id]) { // this is currently dangerous for bag-based movements since limbo does not save bag slots
|
||||
// auto inst = m_inv.PopItem(slot_id);
|
||||
// bool is_arrow = (inst->GetItem()->ItemType == EQEmu::item::ItemTypeArrow) ? true : false;
|
||||
// int16 free_slot_id = m_inv.FindFreeSlot(inst->IsClassBag(), true, inst->GetItem()->Size, is_arrow);
|
||||
// Log(Logs::Detail, Logs::Inventory, "Slot Assignment Error: Moving %s from slot %i to %i", inst->GetItem()->Name, slot_id, free_slot_id);
|
||||
// PutItemInInventory(free_slot_id, *inst, client_update);
|
||||
// database.SaveInventory(character_id, nullptr, slot_id);
|
||||
// safe_delete(inst);
|
||||
// }
|
||||
//}
|
||||
|
||||
// No need to check inventory, cursor, bank or shared bank since they allow max item size and containers
|
||||
// Code can be added to check item size vs. container size, but it is left to attrition for now.
|
||||
@@ -2716,7 +2848,26 @@ void Client::SendItemPacket(int16 slot_id, const EQEmu::ItemInstance* inst, Item
|
||||
if (!inst)
|
||||
return;
|
||||
|
||||
// Serialize item into |-delimited string
|
||||
if (slot_id <= EQEmu::invslot::POSSESSIONS_END && slot_id >= EQEmu::invslot::POSSESSIONS_BEGIN) {
|
||||
if ((((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
||||
return;
|
||||
}
|
||||
else if (slot_id <= EQEmu::invbag::GENERAL_BAGS_END && slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN) {
|
||||
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
|
||||
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0)
|
||||
return;
|
||||
}
|
||||
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
|
||||
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
|
||||
return;
|
||||
}
|
||||
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
|
||||
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
|
||||
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
|
||||
return;
|
||||
}
|
||||
|
||||
// Serialize item into |-delimited string (Titanium- uses '|' delimiter .. newer clients use pure data serialization)
|
||||
std::string packet = inst->Serialize(slot_id);
|
||||
|
||||
EmuOpcode opcode = OP_Unknown;
|
||||
@@ -3000,6 +3151,8 @@ bool Client::MoveItemToInventory(EQEmu::ItemInstance *ItemToReturn, bool UpdateC
|
||||
if(ItemToReturn->IsStackable()) {
|
||||
|
||||
for (int16 i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::slotCursor; i++) { // changed slot max to 30 from 29. client will stack into slot 30 (bags too) before moving.
|
||||
if (((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue;
|
||||
|
||||
EQEmu::ItemInstance* InvItem = m_inv.GetItem(i);
|
||||
|
||||
@@ -3059,6 +3212,8 @@ bool Client::MoveItemToInventory(EQEmu::ItemInstance *ItemToReturn, bool UpdateC
|
||||
// We have tried stacking items, now just try and find an empty slot.
|
||||
|
||||
for (int16 i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::slotCursor; i++) { // changed slot max to 30 from 29. client will move into slot 30 (bags too) before pushing onto cursor.
|
||||
if (((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask == 0)
|
||||
continue;
|
||||
|
||||
EQEmu::ItemInstance* InvItem = m_inv.GetItem(i);
|
||||
|
||||
@@ -3119,7 +3274,7 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool
|
||||
std::map<int16, const EQEmu::ItemInstance*> instmap;
|
||||
|
||||
// build reference map
|
||||
for (int16 index = EQEmu::invslot::EQUIPMENT_BEGIN; index <= EQEmu::invslot::POSSESSIONS_END; ++index) {
|
||||
for (int16 index = EQEmu::invslot::POSSESSIONS_BEGIN; index <= EQEmu::invslot::POSSESSIONS_END; ++index) {
|
||||
auto inst = m_inv[index];
|
||||
if (inst == nullptr) { continue; }
|
||||
instmap[index] = inst;
|
||||
@@ -3163,9 +3318,6 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool
|
||||
instmap[8000 + limbo] = *cursor_itr;
|
||||
}
|
||||
|
||||
if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE])
|
||||
instmap[EQEmu::invslot::SLOT_POWER_SOURCE] = m_inv[EQEmu::invslot::SLOT_POWER_SOURCE];
|
||||
|
||||
// call InterrogateInventory_ for error check
|
||||
for (auto instmap_itr = instmap.begin(); (instmap_itr != instmap.end()) && (!error); ++instmap_itr) {
|
||||
InterrogateInventory_(true, requester, instmap_itr->first, INVALID_INDEX, instmap_itr->second, nullptr, log, silent, error, 0);
|
||||
@@ -3270,8 +3422,7 @@ bool Client::InterrogateInventory_error(int16 head, int16 index, const EQEmu::It
|
||||
(head >= EQEmu::invslot::EQUIPMENT_BEGIN && head <= EQEmu::invslot::EQUIPMENT_END) ||
|
||||
(head >= EQEmu::invslot::TRIBUTE_BEGIN && head <= EQEmu::invslot::TRIBUTE_END) ||
|
||||
(head >= EQEmu::invslot::WORLD_BEGIN && head <= EQEmu::invslot::WORLD_END) ||
|
||||
(head >= 8000 && head <= 8101) ||
|
||||
(head == EQEmu::invslot::SLOT_POWER_SOURCE)) {
|
||||
(head >= 8000 && head <= 8101)) {
|
||||
switch (depth)
|
||||
{
|
||||
case 0: // requirement: inst is extant
|
||||
|
||||
+1
-1
@@ -323,7 +323,7 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch
|
||||
// @merth: IDFile size has been increased, this needs to change
|
||||
uint16 emat;
|
||||
if(item2->Material <= 0
|
||||
|| item2->Slots & (1 << EQEmu::invslot::slotPrimary | 1 << EQEmu::invslot::slotSecondary)) {
|
||||
|| (item2->Slots & ((1 << EQEmu::invslot::slotPrimary) | (1 << EQEmu::invslot::slotSecondary)))) {
|
||||
memset(newid, 0, sizeof(newid));
|
||||
for(int i=0;i<7;i++){
|
||||
if (!isalpha(item2->IDFile[i])){
|
||||
|
||||
+37
-13
@@ -1870,27 +1870,22 @@ luabind::scope lua_register_slot() {
|
||||
luabind::value("Face", static_cast<int>(EQEmu::invslot::slotFace)),
|
||||
luabind::value("Ear2", static_cast<int>(EQEmu::invslot::slotEar2)),
|
||||
luabind::value("Neck", static_cast<int>(EQEmu::invslot::slotNeck)),
|
||||
luabind::value("Shoulder", static_cast<int>(EQEmu::invslot::slotShoulders)), // deprecated
|
||||
luabind::value("Shoulders", static_cast<int>(EQEmu::invslot::slotShoulders)),
|
||||
luabind::value("Arms", static_cast<int>(EQEmu::invslot::slotArms)),
|
||||
luabind::value("Back", static_cast<int>(EQEmu::invslot::slotBack)),
|
||||
luabind::value("Bracer1", static_cast<int>(EQEmu::invslot::slotWrist1)), // deprecated
|
||||
luabind::value("Wrist1", static_cast<int>(EQEmu::invslot::slotWrist1)),
|
||||
luabind::value("Bracer2", static_cast<int>(EQEmu::invslot::slotWrist2)), // deprecated
|
||||
luabind::value("Wrist2", static_cast<int>(EQEmu::invslot::slotWrist2)),
|
||||
luabind::value("Range", static_cast<int>(EQEmu::invslot::slotRange)),
|
||||
luabind::value("Hands", static_cast<int>(EQEmu::invslot::slotHands)),
|
||||
luabind::value("Primary", static_cast<int>(EQEmu::invslot::slotPrimary)),
|
||||
luabind::value("Secondary", static_cast<int>(EQEmu::invslot::slotSecondary)),
|
||||
luabind::value("Ring1", static_cast<int>(EQEmu::invslot::slotFinger1)), // deprecated
|
||||
luabind::value("Finger1", static_cast<int>(EQEmu::invslot::slotFinger1)),
|
||||
luabind::value("Ring2", static_cast<int>(EQEmu::invslot::slotFinger2)), // deprecated
|
||||
luabind::value("Finger2", static_cast<int>(EQEmu::invslot::slotFinger2)),
|
||||
luabind::value("Chest", static_cast<int>(EQEmu::invslot::slotChest)),
|
||||
luabind::value("Legs", static_cast<int>(EQEmu::invslot::slotLegs)),
|
||||
luabind::value("Feet", static_cast<int>(EQEmu::invslot::slotFeet)),
|
||||
luabind::value("Waist", static_cast<int>(EQEmu::invslot::slotWaist)),
|
||||
luabind::value("PowerSource", static_cast<int>(EQEmu::invslot::SLOT_POWER_SOURCE)),
|
||||
luabind::value("PowerSource", static_cast<int>(EQEmu::invslot::slotPowerSource)),
|
||||
luabind::value("Ammo", static_cast<int>(EQEmu::invslot::slotAmmo)),
|
||||
luabind::value("General1", static_cast<int>(EQEmu::invslot::slotGeneral1)),
|
||||
luabind::value("General2", static_cast<int>(EQEmu::invslot::slotGeneral2)),
|
||||
@@ -1900,15 +1895,43 @@ luabind::scope lua_register_slot() {
|
||||
luabind::value("General6", static_cast<int>(EQEmu::invslot::slotGeneral6)),
|
||||
luabind::value("General7", static_cast<int>(EQEmu::invslot::slotGeneral7)),
|
||||
luabind::value("General8", static_cast<int>(EQEmu::invslot::slotGeneral8)),
|
||||
luabind::value("General9", static_cast<int>(EQEmu::invslot::slotGeneral9)),
|
||||
luabind::value("General10", static_cast<int>(EQEmu::invslot::slotGeneral10)),
|
||||
luabind::value("Cursor", static_cast<int>(EQEmu::invslot::slotCursor)),
|
||||
luabind::value("PersonalBegin", static_cast<int>(EQEmu::invslot::GENERAL_BEGIN)), // deprecated
|
||||
luabind::value("PossessionsBegin", static_cast<int>(EQEmu::invslot::POSSESSIONS_BEGIN)),
|
||||
luabind::value("PossessionsEnd", static_cast<int>(EQEmu::invslot::POSSESSIONS_END)),
|
||||
luabind::value("EquipmentBegin", static_cast<int>(EQEmu::invslot::EQUIPMENT_BEGIN)),
|
||||
luabind::value("EquipmentEnd", static_cast<int>(EQEmu::invslot::EQUIPMENT_END)),
|
||||
luabind::value("GeneralBegin", static_cast<int>(EQEmu::invslot::GENERAL_BEGIN)),
|
||||
luabind::value("PersonalEnd", static_cast<int>(EQEmu::invslot::GENERAL_END)), // deprecated
|
||||
luabind::value("GeneralEnd", static_cast<int>(EQEmu::invslot::GENERAL_END)),
|
||||
luabind::value("GeneralBagsBegin", static_cast<int>(EQEmu::invbag::GENERAL_BAGS_BEGIN)),
|
||||
luabind::value("GeneralBagsEnd", static_cast<int>(EQEmu::invbag::GENERAL_BAGS_END)),
|
||||
luabind::value("CursorBagBegin", static_cast<int>(EQEmu::invbag::CURSOR_BAG_BEGIN)),
|
||||
luabind::value("CursorBagEnd", static_cast<int>(EQEmu::invbag::CURSOR_BAG_END)),
|
||||
luabind::value("BankBegin", static_cast<int>(EQEmu::invslot::BANK_BEGIN)),
|
||||
luabind::value("BankEnd", static_cast<int>(EQEmu::invslot::BANK_END)),
|
||||
luabind::value("BankBagsBegin", static_cast<int>(EQEmu::invbag::BANK_BAGS_BEGIN)),
|
||||
luabind::value("BankBagsEnd", static_cast<int>(EQEmu::invbag::BANK_BAGS_END)),
|
||||
luabind::value("SharedBankBegin", static_cast<int>(EQEmu::invslot::SHARED_BANK_BEGIN)),
|
||||
luabind::value("SharedBankEnd", static_cast<int>(EQEmu::invslot::SHARED_BANK_END)),
|
||||
luabind::value("SharedBankBagsBegin", static_cast<int>(EQEmu::invbag::SHARED_BANK_BAGS_BEGIN)),
|
||||
luabind::value("SharedBankBagsEnd", static_cast<int>(EQEmu::invbag::SHARED_BANK_BAGS_END)),
|
||||
luabind::value("BagSlotBegin", static_cast<int>(EQEmu::invbag::SLOT_BEGIN)),
|
||||
luabind::value("BagSlotEnd", static_cast<int>(EQEmu::invbag::SLOT_END)),
|
||||
luabind::value("AugSocketBegin", static_cast<int>(EQEmu::invaug::SOCKET_BEGIN)),
|
||||
luabind::value("AugSocketEnd", static_cast<int>(EQEmu::invaug::SOCKET_END)),
|
||||
luabind::value("Invalid", static_cast<int>(EQEmu::invslot::SLOT_INVALID)),
|
||||
|
||||
luabind::value("Shoulder", static_cast<int>(EQEmu::invslot::slotShoulders)), // deprecated
|
||||
luabind::value("Bracer1", static_cast<int>(EQEmu::invslot::slotWrist1)), // deprecated
|
||||
luabind::value("Bracer2", static_cast<int>(EQEmu::invslot::slotWrist2)), // deprecated
|
||||
luabind::value("Ring1", static_cast<int>(EQEmu::invslot::slotFinger1)), // deprecated
|
||||
luabind::value("Ring2", static_cast<int>(EQEmu::invslot::slotFinger2)), // deprecated
|
||||
luabind::value("PersonalBegin", static_cast<int>(EQEmu::invslot::GENERAL_BEGIN)), // deprecated
|
||||
luabind::value("PersonalEnd", static_cast<int>(EQEmu::invslot::GENERAL_END)), // deprecated
|
||||
luabind::value("CursorEnd", 0xFFFE), // deprecated
|
||||
luabind::value("Tradeskill", static_cast<int>(EQEmu::legacy::SLOT_TRADESKILL)), // deprecated
|
||||
luabind::value("Augment", static_cast<int>(EQEmu::legacy::SLOT_AUGMENT)), // deprecated
|
||||
luabind::value("Invalid", INVALID_INDEX)
|
||||
luabind::value("Augment", static_cast<int>(EQEmu::legacy::SLOT_AUGMENT)) // deprecated
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1919,16 +1942,17 @@ luabind::scope lua_register_material() {
|
||||
luabind::value("Head", static_cast<int>(EQEmu::textures::armorHead)),
|
||||
luabind::value("Chest", static_cast<int>(EQEmu::textures::armorChest)),
|
||||
luabind::value("Arms", static_cast<int>(EQEmu::textures::armorArms)),
|
||||
luabind::value("Bracer", static_cast<int>(EQEmu::textures::armorWrist)), // deprecated
|
||||
luabind::value("Wrist", static_cast<int>(EQEmu::textures::armorWrist)),
|
||||
luabind::value("Hands", static_cast<int>(EQEmu::textures::armorHands)),
|
||||
luabind::value("Legs", static_cast<int>(EQEmu::textures::armorLegs)),
|
||||
luabind::value("Feet", static_cast<int>(EQEmu::textures::armorFeet)),
|
||||
luabind::value("Primary", static_cast<int>(EQEmu::textures::weaponPrimary)),
|
||||
luabind::value("Secondary", static_cast<int>(EQEmu::textures::weaponSecondary)),
|
||||
luabind::value("Max", static_cast<int>(EQEmu::textures::materialCount)), // deprecated
|
||||
luabind::value("Count", static_cast<int>(EQEmu::textures::materialCount)),
|
||||
luabind::value("Invalid", static_cast<int>(EQEmu::textures::materialInvalid))
|
||||
luabind::value("Invalid", static_cast<int>(EQEmu::textures::materialInvalid)),
|
||||
|
||||
luabind::value("Bracer", static_cast<int>(EQEmu::textures::armorWrist)), // deprecated
|
||||
luabind::value("Max", static_cast<int>(EQEmu::textures::materialCount)) // deprecated
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
+5
-11
@@ -217,22 +217,16 @@ void Merc::CalcItemBonuses(StatBonuses* newbon) {
|
||||
|
||||
unsigned int i;
|
||||
//should not include 21 (SLOT_AMMO)
|
||||
for (i = 0; i < EQEmu::invslot::slotAmmo; i++) {
|
||||
if(equipment[i] == 0)
|
||||
for (i = EQEmu::invslot::BONUS_BEGIN; i <= EQEmu::invslot::BONUS_STAT_END; i++) {
|
||||
if (i == EQEmu::invslot::slotAmmo)
|
||||
continue;
|
||||
if (equipment[i] == 0)
|
||||
continue;
|
||||
const EQEmu::ItemData * itm = database.GetItem(equipment[i]);
|
||||
if(itm)
|
||||
if (itm)
|
||||
AddItemBonuses(itm, newbon);
|
||||
}
|
||||
|
||||
//Power Source Slot
|
||||
/*if (GetClientVersion() >= EQClientSoF)
|
||||
{
|
||||
const EQEmu::ItemInstance* inst = m_inv[MainPowerSource];
|
||||
if(inst)
|
||||
AddItemBonuses(inst, newbon);
|
||||
}*/
|
||||
|
||||
// Caps
|
||||
if(newbon->HPRegen > CalcHPRegenCap())
|
||||
newbon->HPRegen = CalcHPRegenCap();
|
||||
|
||||
@@ -3026,7 +3026,7 @@ XS(XS_Client_SummonItem) {
|
||||
dXSARGS;
|
||||
if (items < 2 || items > 10)
|
||||
Perl_croak(aTHX_
|
||||
"Usage: Client::SummonItem(THIS, uint32 item_id, [int16 charges = -1], [bool attune = false], [uint32 aug1 = 0], [uint32 aug2 = 0], [uint32 aug3 = 0], [uint32 aug4 = 0], [uint32 aug5 = 0], [uint16 slot_id = 30])");
|
||||
"Usage: Client::SummonItem(THIS, uint32 item_id, [int16 charges = -1], [bool attune = false], [uint32 aug1 = 0], [uint32 aug2 = 0], [uint32 aug3 = 0], [uint32 aug4 = 0], [uint32 aug5 = 0], [uint16 slot_id = cursor])");
|
||||
{
|
||||
Client *THIS;
|
||||
uint32 item_id = (uint32) SvUV(ST(1));
|
||||
@@ -3037,7 +3037,7 @@ XS(XS_Client_SummonItem) {
|
||||
uint32 aug3 = 0;
|
||||
uint32 aug4 = 0;
|
||||
uint32 aug5 = 0;
|
||||
uint16 slot_id = 30;
|
||||
uint16 slot_id = EQEmu::invslot::slotCursor;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||
|
||||
+1
-1
@@ -527,7 +527,7 @@ void NPC::GetPetState(SpellBuff_Struct *pet_buffs, uint32 *items, char *name) {
|
||||
memcpy(items, equipment, sizeof(uint32) * EQEmu::invslot::EQUIPMENT_COUNT);
|
||||
|
||||
//save their buffs.
|
||||
for (int i=0; i < GetPetMaxTotalSlots(); i++) {
|
||||
for (int i=EQEmu::invslot::EQUIPMENT_BEGIN; i < GetPetMaxTotalSlots(); i++) {
|
||||
if (buffs[i].spellid != SPELL_UNKNOWN) {
|
||||
pet_buffs[i].spellid = buffs[i].spellid;
|
||||
pet_buffs[i].effect_type = i+1;
|
||||
|
||||
+1
-1
@@ -281,7 +281,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
if (itm && (itm->GetItem()->Click.Type == EQEmu::item::ItemEffectEquipClick) && !(item_slot <= EQEmu::invslot::slotAmmo || item_slot == EQEmu::invslot::SLOT_POWER_SOURCE)){
|
||||
if (itm && (itm->GetItem()->Click.Type == EQEmu::item::ItemEffectEquipClick) && item_slot > EQEmu::invslot::EQUIPMENT_END){
|
||||
if (CastToClient()->ClientVersion() < EQEmu::versions::ClientVersion::SoF) {
|
||||
// They are attempting to cast a must equip clicky without having it equipped
|
||||
Log(Logs::General, Logs::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) without equiping it!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
|
||||
|
||||
+4
-4
@@ -1202,7 +1202,7 @@ void Client::SendSingleTraderItem(uint32 CharID, int SerialNumber) {
|
||||
|
||||
EQEmu::ItemInstance* inst= database.LoadSingleTraderItem(CharID, SerialNumber);
|
||||
if(inst) {
|
||||
SendItemPacket(30, inst, ItemPacketMerchant); // MainCursor?
|
||||
SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketMerchant); // MainCursor?
|
||||
safe_delete(inst);
|
||||
}
|
||||
|
||||
@@ -1233,7 +1233,7 @@ void Client::BulkSendTraderInventory(uint32 char_id) {
|
||||
}
|
||||
|
||||
inst->SetPrice(TraderItems->ItemCost[i]);
|
||||
SendItemPacket(30, inst, ItemPacketMerchant); // MainCursor?
|
||||
SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketMerchant); // MainCursor?
|
||||
safe_delete(inst);
|
||||
}
|
||||
else
|
||||
@@ -2072,7 +2072,7 @@ static void UpdateTraderCustomerItemsAdded(uint32 CustomerID, TraderCharges_Stru
|
||||
Log(Logs::Detail, Logs::Trading, "Sending price update for %s, Serial No. %i with %i charges",
|
||||
item->Name, gis->SerialNumber[i], gis->Charges[i]);
|
||||
|
||||
Customer->SendItemPacket(30, inst, ItemPacketMerchant); // MainCursor?
|
||||
Customer->SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketMerchant); // MainCursor?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2156,7 +2156,7 @@ static void UpdateTraderCustomerPriceChanged(uint32 CustomerID, TraderCharges_St
|
||||
Log(Logs::Detail, Logs::Trading, "Sending price update for %s, Serial No. %i with %i charges",
|
||||
item->Name, gis->SerialNumber[i], gis->Charges[i]);
|
||||
|
||||
Customer->SendItemPacket(30, inst, ItemPacketMerchant); // MainCursor??
|
||||
Customer->SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketMerchant); // MainCursor??
|
||||
}
|
||||
safe_delete(inst);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user