// Miscellaneous int LuaExports::dropItemReactor(lua_State *luaVm) { int32_t itemid = lua_tointeger(luaVm, 1); int16_t amount = 1; if (lua_isnumber(luaVm, 2)) { amount = lua_tointeger(luaVm, 2); } Reactor *reactor = getReactor(luaVm); Player *player = getPlayer(luaVm); Drop *drop; if (GameLogicUtilities::isEquip(itemid)) { Item f(itemid, true); drop = new Drop(reactor->getMapId(), f, reactor->getPos(), player != nullptr ? player->getId() : 0); } else { Item f(itemid, amount); drop = new Drop(reactor->getMapId(), f, reactor->getPos(), player != nullptr ? player->getId() : 0); } drop->setTime(player != nullptr ? 100 : 0); // FFA if player isn't around drop->doDrop(reactor->getPos()); return 0; }
void InventoryHandler::itemMove(Player *player, PacketReader &packet) { if (!player->updateTickCount(packet.get<int32_t>())) { // Tickcount was the same or less than 100 of the difference. return; } int8_t inv = packet.get<int8_t>(); int16_t slot1 = packet.get<int16_t>(); int16_t slot2 = packet.get<int16_t>(); if (slot2 == 0) { // Dropping an item int16_t amount = packet.get<int16_t>(); Item *item = player->getInventory()->getItem(inv, slot1); if (item == nullptr) { return; } if (!GameLogicUtilities::isStackable(item->getId())) { amount = item->getAmount(); } else if (amount <= 0 || amount > item->getAmount()) { // Hacking return; } else if (ItemDataProvider::Instance()->isCash(item->getId())) { // Hacks or modded client. return; } Item droppeditem(item); droppeditem.setAmount(amount); if (item->getAmount() == amount) { InventoryPacket::moveItem(player, inv, slot1, slot2); player->getInventory()->deleteItem(inv, slot1); } else { item->decAmount(amount); player->getInventory()->changeItemAmount(item->getId(), -amount); InventoryPacket::updateItemAmounts(player, inv, slot1, item->getAmount(), 0, 0); } Drop *drop = new Drop(player->getMap(), droppeditem, player->getPos(), player->getId(), true); drop->setTime(0); bool istradeable = ItemDataProvider::Instance()->isTradeable(droppeditem.getId()); drop->setTradeable(istradeable); drop->doDrop(player->getPos()); if (istradeable) { // Drop is deleted otherwise, avoid like plague ReactorHandler::checkDrop(player, drop); } } else { // Change item slot (swapping) Item *item1 = player->getInventory()->getItem(inv, slot1); Item *item2 = player->getInventory()->getItem(inv, slot2); if (item1 == nullptr) { // Hacking return; } if (item2 != nullptr && GameLogicUtilities::isStackable(item1->getId()) && item1->getId() == item2->getId()) { if (item1->getAmount() + item2->getAmount() <= ItemDataProvider::Instance()->getMaxSlot(item1->getId())) { item2->incAmount(item1->getAmount()); player->getInventory()->deleteItem(inv, slot1, false); InventoryPacket::updateItemAmounts(player, inv, slot2, item2->getAmount(), 0, 0); InventoryPacket::moveItem(player, inv, slot1, 0); } else { item1->decAmount(ItemDataProvider::Instance()->getMaxSlot(item1->getId()) - item2->getAmount()); item2->setAmount(ItemDataProvider::Instance()->getMaxSlot(item2->getId())); InventoryPacket::updateItemAmounts(player, inv, slot1, item1->getAmount(), slot2, item2->getAmount()); } } else { if (slot2 < 0) { bool iscash = ItemDataProvider::Instance()->isCash(item1->getId()); uint8_t desiredslot = -(slot2 + (iscash ? 100 : 0)); if (!EquipDataProvider::Instance()->validSlot(item1->getId(), desiredslot)) { // Hacking return; } Item *remove = nullptr; int16_t oldslot = 0; bool weapon = -slot2 == EquipSlots::Weapon; bool shield = -slot2 == EquipSlots::Shield; bool top = -slot2 == EquipSlots::Top; bool bottom = -slot2 == EquipSlots::Bottom; if (weapon && GameLogicUtilities::is2hWeapon(item1->getId()) && player->getInventory()->getEquippedId(EquipSlots::Shield) != 0) { oldslot = -EquipSlots::Shield; } else if (shield && GameLogicUtilities::is2hWeapon(player->getInventory()->getEquippedId(EquipSlots::Weapon))) { oldslot = -EquipSlots::Weapon; } else if (top && GameLogicUtilities::isOverall(item1->getId()) && player->getInventory()->getEquippedId(EquipSlots::Bottom) != 0) { oldslot = -EquipSlots::Bottom; } else if (bottom && GameLogicUtilities::isOverall(player->getInventory()->getEquippedId(EquipSlots::Top))) { oldslot = -EquipSlots::Top; } if (oldslot != 0) { remove = player->getInventory()->getItem(inv, oldslot); bool onlyswap = true; if ((player->getInventory()->getEquippedId(EquipSlots::Shield) != 0) && (player->getInventory()->getEquippedId(EquipSlots::Weapon) != 0)) { onlyswap = false; } else if ((player->getInventory()->getEquippedId(EquipSlots::Top) != 0) && (player->getInventory()->getEquippedId(EquipSlots::Bottom) != 0)) { onlyswap = false; } if (onlyswap) { int16_t swapslot = 0; if (weapon) { swapslot = -EquipSlots::Shield; player->getActiveBuffs()->stopBooster(); player->getActiveBuffs()->stopCharge(); } else if (shield) { swapslot = -EquipSlots::Weapon; player->getActiveBuffs()->stopBooster(); player->getActiveBuffs()->stopCharge(); } else if (top) { swapslot = -EquipSlots::Bottom; } else if (bottom) { swapslot = -EquipSlots::Top; } player->getInventory()->setItem(inv, swapslot, nullptr); player->getInventory()->setItem(inv, slot1, remove); player->getInventory()->setItem(inv, slot2, item1); InventoryPacket::moveItem(player, inv, slot1, slot2); InventoryPacket::moveItem(player, inv, swapslot, slot1); InventoryPacket::updatePlayer(player); return; } else { if (player->getInventory()->getOpenSlotsNum(inv) == 0) { InventoryPacket::blankUpdate(player); return; } int16_t freeslot = 0; for (int16_t s = 1; s <= player->getInventory()->getMaxSlots(inv); s++) { Item *olditem = player->getInventory()->getItem(inv, s); if (olditem == nullptr) { freeslot = s; break; } } player->getInventory()->setItem(inv, freeslot, remove); player->getInventory()->setItem(inv, oldslot, nullptr); InventoryPacket::moveItem(player, inv, oldslot, freeslot); } } } else if (slot1 < 0 && item2 != nullptr && !ItemDataProvider::Instance()->isCash(item2->getId())) { // Client tries to switch a cash item with a regular item return; } player->getInventory()->setItem(inv, slot1, item2); player->getInventory()->setItem(inv, slot2, item1); if (item1->getPetId() > 0) { player->getPets()->getPet(item1->getPetId())->setInventorySlot((int8_t) slot2); } if (item2 != nullptr && item2->getPetId() > 0) { player->getPets()->getPet(item2->getPetId())->setInventorySlot((int8_t) slot1); } InventoryPacket::moveItem(player, inv, slot1, slot2); } } if ((slot1 < 0 && -slot1 == EquipSlots::Weapon) || (slot2 < 0 && -slot2 == EquipSlots::Weapon)) { player->getActiveBuffs()->stopBooster(); player->getActiveBuffs()->stopCharge(); player->getActiveBuffs()->stopBulletSkills(); } // Check if the label ring changed, so we can update the look of the pet. if ((slot1 < 0 && -slot1 - 100 == EquipSlots::PetLabelRing1) || (slot2 < 0 && -slot2 - 100 == EquipSlots::PetLabelRing1)) { if (Pet *pet = player->getPets()->getSummoned(0)) { PetsPacket::changeName(player, pet); } } if ((slot1 < 0 && -slot1 - 100 == EquipSlots::PetLabelRing2) || (slot2 < 0 && -slot2 - 100 == EquipSlots::PetLabelRing2)) { if (Pet *pet = player->getPets()->getSummoned(1)) { PetsPacket::changeName(player, pet); } } if ((slot1 < 0 && -slot1 - 100 == EquipSlots::PetLabelRing3) || (slot2 < 0 && -slot2 - 100 == EquipSlots::PetLabelRing3)) { if (Pet *pet = player->getPets()->getSummoned(2)) { PetsPacket::changeName(player, pet); } } if (slot1 < 0 || slot2 < 0) { InventoryPacket::updatePlayer(player); } }