static int InventoryL_AddItem(lua_State* luaVM) { bool success = false; const int nargs = lua_gettop(luaVM); Inventory* inv; if(nargs > 1) { inv = luaW_to<Inventory>(luaVM, 1); switch(nargs) { case 2: { success = inv->addItem(lua_tonumber(luaVM, 2)); break; } case 3: { success = inv->addItem(lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3)); break; } } } lua_pushboolean(luaVM, success); return 1; }
void Game::onTimeElapsed() { Inventory inventory; inventory.addItem(InventoryItem(SWAP_BONUS_IDENTIFIER, swapRemaining)); inventory.addItem(InventoryItem(CHANGE_BONUS_IDENTIFIER, changeRemaining)); inventory.addItem(InventoryItem(REMOVE_BONUS_IDENTIFIER, removeRemaining)); gameSpice->updateInventory(inventory); auto gameSpice = GameSpice::getInstance(); gameSpice->addFund(Fund(score), [&] (Fund f) {}); gameSpice->getHighScore(GAMESPICE_LEADERBOARD_ID, [&] (HighScore s) { submitScore(); int oldScore = s.getScore(); bool isNewHighScore = score > oldScore; auto scene = isNewHighScore ? NewHighScore::scene() : GameOver::scene(); GameManager::sharedGameManager()->runScene(scene); }); }
int punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher, float time_from_last_punch) { // Take item into inventory ItemStack item = createItemStack(); Inventory *inv = puncher->getInventory(); if(inv != NULL) { std::string wieldlist = puncher->getWieldList(); ItemStack leftover = inv->addItem(wieldlist, item); puncher->setInventoryModified(); if(leftover.empty()) { m_removed = true; } else { m_itemstring = leftover.getItemString(); m_itemstring_changed = true; } } return 0; }
void Inventory::addAllItemsTo(Inventory& target) const { std::map<std::string, unsigned int>::const_iterator iter = m_Items.begin(); while (iter!=m_Items.end()) { target.addItem(iter->first, iter->second); ++iter; }//while }
void CoinNodeAbstractListener::askForBlock(const std::string& hash) { InventoryItem block(MSG_BLOCK, uchar_vector(hash)); Inventory inv; inv.addItem(block); GetDataMessage getData(inv); CoinNodeMessage msg(this->getMagic(), &getData); this->sendMessage(msg); }
//add item int Script::addItem(lua_State* L){ short tx = (short)luaL_checknumber(L, 1); short ty = (short)luaL_checknumber(L, 2); string name = string(luaL_checkstring(L, 3)); Item it = Templates::instance()->searchItem(name); Creature* creat = dynamic_cast<Creature*>(wrld.getObject(Vector2D(tx,ty))); Inventory* inv = creat->getInventory(); inv->addItem(it); return 0; }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionGiveItem::execute (Creature * pCreature1 , Creature * pCreature2) throw(Error) { __BEGIN_TRY Assert(pCreature2 != NULL); Assert(pCreature2->isPC()); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature2); Assert(pPC != NULL); Player* pPlayer = pCreature2->getPlayer(); Assert(pPlayer != NULL); list<OptionType_t> optionTypeList; Item* pItem = g_pItemFactoryManager->createItem(m_ItemClass, m_ItemType, optionTypeList); Assert(pItem != NULL); _TPOINT pt; Inventory* pInventory = pPC->getInventory(); Assert(pInventory != NULL); if (!pInventory->getEmptySlot(pItem, pt)) { // ConditionHasInvenSpace 컨디션과 반드시 함께 써야만 한다. throw Error("ActionGiveItem: 제발 ConditionHasInvenSpace랑 같이 쓰자. 인벤토리에 자리없다."); } CoordInven_t X = pt.x; CoordInven_t Y = pt.y; pPC->getZone()->getObjectRegistry().registerObject(pItem); pInventory->addItem(X, Y, pItem); pItem->create(pPC->getName(), STORAGE_INVENTORY, 0, X, Y); if (pItem != NULL && pItem->isTraceItem() ) { remainTraceLog(pItem, "ActionGiveItem", pCreature2->getName(), ITEM_LOG_CREATE, DETAIL_EVENTNPC); remainTraceLogNew(pItem, pCreature2->getName(), ITL_GET, ITLD_EVENTNPC , pCreature2->getZone()->getZoneID()); } // 클라이언트에 선물이 추가되었음을 알린다. GCCreateItem gcCreateItem; makeGCCreateItem(&gcCreateItem, pItem, X, Y); pPlayer->sendPacket(&gcCreateItem); __END_CATCH }
/** * Attempts to add an item to the inventory at the given location, returns true * if the space required for the item was available. * * @param Item item The item to add to the inventory. * @param integer x The x location to add the item at. * @param integer y The y location to add the item at. * @returns boolean True if the item was added to the inventory successfully. */ int Inventory_add_item(lua_State *lua) { Inventory *inv = castUData<Inventory>(lua, 1); if (inv) { Item *item = castUData<Item>(lua, 2); if (item) { int args = lua_gettop(lua); if (args == 2) { lua_pushboolean(lua, inv->addItem(item)); return 1; } else if (args == 4 && lua_isnum(lua, 3) && lua_isnum(lua, 4)) { lua_pushboolean(lua, inv->addItem(item, lua_tointeger(lua, 3), lua_tointeger(lua, 4))); return 1; } } return LuaState::expectedArgs(lua, "add_item", 2, "Item item", "Item item, integer x, integer y"); } return LuaState::expectedContext(lua, "add_item", "Inventory"); }
void StoreTab::run(Inventory &stationData) { //run through the store tab //uis tend to have a ton of bloated code loadInventories(playerData.getConvertedInventory(), stationData.getConvertedInventory()); playerCash->setText((stringw(L"Your Credits :") + stringw(playerData.getCredits())).c_str()); int index = playerInventory->getSelected(); //this is needed to maintain syncing between the index and objectmanager enum std::vector<ObjectManager::E_ITEM_LIST> syncedInventory = playerData.getConvertedInventoryNoSpaces(); if (index != -1) { //has something selected so we load its information selectedValue->setText((stringw(L"Value :") + stringw(ObjectManager::itemList[syncedInventory[index]]->getPrice())).c_str()); selectedWeight->setText((stringw(L"Weight :") + stringw(ObjectManager::itemList[syncedInventory[index]]->getWeight())).c_str()); selectedDescription->setText(ObjectManager::itemList[syncedInventory[index]]->getDesc()); if (sellButton->isPressed()) { //sell selected item playerData.addCredits(ObjectManager::itemList[syncedInventory[index]]->getPrice()); playerData.removeItem(syncedInventory[index]); stationData.addItem(syncedInventory[index], 1); playerInventory->clear(); stationInventory->clear(); } } else { //reset text if nothing is selected selectedValue->setText(L"Value :"); selectedWeight->setText(L"Weight :"); selectedDescription->setText(L""); } index = stationInventory->getSelected(); syncedInventory = stationData.getConvertedInventoryNoSpaces(); if (index != -1) { //has something selected so we load its information selectedValue->setText((stringw(L"Value :") + stringw(ObjectManager::itemList[syncedInventory[index]]->getPrice())).c_str()); selectedWeight->setText((stringw(L"Weight :") + stringw(ObjectManager::itemList[syncedInventory[index]]->getWeight())).c_str()); selectedDescription->setText(ObjectManager::itemList[syncedInventory[index]]->getDesc()); if (buyButton->isPressed()) { //sell selected item playerData.addCredits(-ObjectManager::itemList[syncedInventory[index]]->getPrice()); playerData.addItem(syncedInventory[index], 1); stationData.removeItem(syncedInventory[index]); playerInventory->clear(); stationInventory->clear(); } } }
void CGAddMouseToQuickSlotHandler::execute (CGAddMouseToQuickSlot* pPacket , Player* pPlayer) throw(ProtocolException, Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ Assert(pPacket != NULL); Assert(pPlayer != NULL); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Creature* pCreature = pGamePlayer->getCreature(); bool Success = false; if (pCreature->isSlayer()) { Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature); InventorySlot* pExtraSlot = pSlayer->getExtraInventorySlot(); Item* pItem = pExtraSlot->getItem(); if (pItem == NULL) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } ObjectID_t ItemObjectID = pItem->getObjectID(); SlotID_t SlotID = pPacket->getSlotID(); Item::ItemClass IClass = pItem->getItemClass(); // 아이템의 ObjectID가 일치하는지 체크한다. if (ItemObjectID != pPacket->getObjectID()) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } // 벨트를 입고 있지 않다면 벨트에다 아이템을 더할 수가 없다. if (!pSlayer->isWear(Slayer::WEAR_BELT)) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } // 포션도 아니고, 탄창도 아니라면 더할 수가 없지. if (IClass != Item::ITEM_CLASS_POTION && IClass != Item::ITEM_CLASS_MAGAZINE && IClass != Item::ITEM_CLASS_EVENT_ETC && IClass != Item::ITEM_CLASS_KEY) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } if (IClass == Item::ITEM_CLASS_EVENT_ETC && pItem->getItemType() < 14 ) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } Item* pBelt = pSlayer->getWearItem(Slayer::WEAR_BELT); Inventory* pBeltInventory = ((Belt*)pBelt)->getInventory(); if (pBeltInventory->canAdding(SlotID, 0, pItem)) { // 현재 벨트에 있는 Item을 받아온다. Item* pPrevItem = pBeltInventory->getItem(SlotID, 0); // 지정한 자리에 아이템이 있다면... if (pPrevItem != NULL) { // 아이템이 완전히 같은 아이템이라면... if (isStackable(pItem) && isSameItem(pItem, pPrevItem)) { int MaxStack = ItemMaxStack[pItem->getItemClass()]; if (pItem->getNum() + pPrevItem->getNum() > MaxStack) { ItemNum_t CurrentNum = pPrevItem->getNum(); ItemNum_t AddNum = pItem->getNum(); ItemNum_t NewNum = AddNum + CurrentNum - MaxStack; pPrevItem->setNum(MaxStack); pItem->setNum(NewNum); pBeltInventory->increaseNum(MaxStack - CurrentNum); pBeltInventory->increaseWeight(pItem->getWeight()* (MaxStack - CurrentNum)); //pPrevItem->save(pSlayer->getName(), STORAGE_BELT, pBelt->getItemID(), SlotID, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Num=%d, Storage=%d, StorageID=%lu, X=%d", MaxStack, STORAGE_BELT, pBelt->getItemID(), SlotID); pPrevItem->tinysave(pField); //pItem->save(pSlayer->getName(), STORAGE_EXTRASLOT, 0, 0, 0); // item저장 최적화. by sigi. 2002.5.13 sprintf(pField, "Num=%d, Storage=%d", NewNum, STORAGE_EXTRASLOT); pItem->tinysave(pField); Success = true; } else // 숫자가 9개를 넘지 않을 때. { pSlayer->deleteItemFromExtraInventorySlot(); pPrevItem->setNum(pPrevItem->getNum() + pItem->getNum()); pBeltInventory->increaseNum(pItem->getNum()); pBeltInventory->increaseWeight(pItem->getWeight()* pItem->getNum()); //pPrevItem->save(pSlayer->getName(), STORAGE_BELT , pBelt->getItemID(), SlotID, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Num=%d, Storage=%d, StorageID=%lu, X=%d", pPrevItem->getNum(), STORAGE_BELT, pBelt->getItemID(), SlotID); pPrevItem->tinysave(pField); pItem->destroy(); SAFE_DELETE(pItem); Success = true; } } else // 클래스랑 타입이 같지 않을때 { // 마우스에 달려있는 아이템과 벨트에 있는 아이템을 제거한다. pSlayer->deleteItemFromExtraInventorySlot(); pBeltInventory->deleteItem(pPrevItem->getObjectID()); // 둘의 위치를 바꿔 준다. pSlayer->addItemToExtraInventorySlot(pPrevItem); pBeltInventory->addItem(SlotID , 0 , pItem); // DB에다가 저장을 한다. //pPrevItem->save(pSlayer->getName(), STORAGE_EXTRASLOT, 0, 0, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Storage=%d", STORAGE_EXTRASLOT); pPrevItem->tinysave(pField); //pItem->save(pSlayer->getName(), STORAGE_BELT , pBelt->getItemID(), SlotID, 0); // item저장 최적화. by sigi. 2002.5.13 sprintf(pField, "Storage=%d, StorageID=%lu, X=%d", STORAGE_BELT, pBelt->getItemID(), SlotID); pItem->tinysave(pField); Success = true; } } else // 슬랏에 아무런 기존의 아이템이 없을때. { // Inventory에 특정 아이템을 넣는다. pBeltInventory->addItem(SlotID, 0 , pItem); // 넣기에 성공하면 마우스에 달려있는 아이템을 없앤다. pSlayer->deleteItemFromExtraInventorySlot(); //pItem->save(pSlayer->getName(), STORAGE_BELT, pBelt->getItemID(), SlotID, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Storage=%d, StorageID=%lu, X=%d", STORAGE_BELT, pBelt->getItemID(), SlotID); pItem->tinysave(pField); Success = true; } } // end of if (pBeltInventory->canAdding(SlotID, 0, pItem)) } // if (pCreature->isSlayer()) else if (pCreature->isOusters()) { Ousters* pOusters = dynamic_cast<Ousters*>(pCreature); InventorySlot* pExtraSlot = pOusters->getExtraInventorySlot(); Item* pItem = pExtraSlot->getItem(); if (pItem == NULL) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } ObjectID_t ItemObjectID = pItem->getObjectID(); SlotID_t SlotID = pPacket->getSlotID(); Item::ItemClass IClass = pItem->getItemClass(); // 아이템의 ObjectID가 일치하는지 체크한다. if (ItemObjectID != pPacket->getObjectID()) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } Ousters::WearPart part = (SlotID > 2 ? Ousters::WEAR_ARMSBAND2 : Ousters::WEAR_ARMSBAND1); if (SlotID > 2 ) SlotID -= 3; // 해당 암스밴드가 없다 if (!pOusters->isWear(part)) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } // 푸파도 아니고, 콤포스메이도 아니라면 더할 수가 없지. if (IClass != Item::ITEM_CLASS_PUPA && IClass != Item::ITEM_CLASS_COMPOS_MEI && IClass != Item::ITEM_CLASS_EVENT_ETC ) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } if (IClass == Item::ITEM_CLASS_EVENT_ETC && pItem->getItemType() < 14 ) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } Item* pArmsband = pOusters->getWearItem(part); Inventory* pArmsbandInventory = ((OustersArmsband*)pArmsband)->getInventory(); if (pArmsbandInventory->canAdding(SlotID, 0, pItem)) { // 현재 벨트에 있는 Item을 받아온다. Item* pPrevItem = pArmsbandInventory->getItem(SlotID, 0); // 지정한 자리에 아이템이 있다면... if (pPrevItem != NULL) { // 아이템이 완전히 같은 아이템이라면... if (isSameItem(pItem, pPrevItem)) { int MaxStack = ItemMaxStack[pItem->getItemClass()]; if (pItem->getNum() + pPrevItem->getNum() > MaxStack) { ItemNum_t CurrentNum = pPrevItem->getNum(); ItemNum_t AddNum = pItem->getNum(); ItemNum_t NewNum = AddNum + CurrentNum - MaxStack; pPrevItem->setNum(MaxStack); pItem->setNum(NewNum); pArmsbandInventory->increaseNum(MaxStack - CurrentNum); pArmsbandInventory->increaseWeight(pItem->getWeight()* (MaxStack - CurrentNum)); //pPrevItem->save(pOusters->getName(), STORAGE_BELT, pArmsband->getItemID(), SlotID, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Num=%d, Storage=%d, StorageID=%lu, X=%d", MaxStack, STORAGE_BELT, pArmsband->getItemID(), SlotID); pPrevItem->tinysave(pField); //pItem->save(pOusters->getName(), STORAGE_EXTRASLOT, 0, 0, 0); // item저장 최적화. by sigi. 2002.5.13 sprintf(pField, "Num=%d, Storage=%d", NewNum, STORAGE_EXTRASLOT); pItem->tinysave(pField); Success = true; } else // 숫자가 9개를 넘지 않을 때. { pOusters->deleteItemFromExtraInventorySlot(); pPrevItem->setNum(pPrevItem->getNum() + pItem->getNum()); pArmsbandInventory->increaseNum(pItem->getNum()); pArmsbandInventory->increaseWeight(pItem->getWeight()* pItem->getNum()); //pPrevItem->save(pOusters->getName(), STORAGE_BELT , pArmsband->getItemID(), SlotID, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Num=%d, Storage=%d, StorageID=%lu, X=%d", pPrevItem->getNum(), STORAGE_BELT, pArmsband->getItemID(), SlotID); pPrevItem->tinysave(pField); pItem->destroy(); SAFE_DELETE(pItem); Success = true; } } else // 클래스랑 타입이 같지 않을때 { // 마우스에 달려있는 아이템과 벨트에 있는 아이템을 제거한다. pOusters->deleteItemFromExtraInventorySlot(); pArmsbandInventory->deleteItem(pPrevItem->getObjectID()); // 둘의 위치를 바꿔 준다. pOusters->addItemToExtraInventorySlot(pPrevItem); pArmsbandInventory->addItem(SlotID , 0 , pItem); // DB에다가 저장을 한다. //pPrevItem->save(pOusters->getName(), STORAGE_EXTRASLOT, 0, 0, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Storage=%d", STORAGE_EXTRASLOT); pPrevItem->tinysave(pField); //pItem->save(pOusters->getName(), STORAGE_BELT , pArmsband->getItemID(), SlotID, 0); // item저장 최적화. by sigi. 2002.5.13 sprintf(pField, "Storage=%d, StorageID=%lu, X=%d", STORAGE_BELT, pArmsband->getItemID(), SlotID); pItem->tinysave(pField); Success = true; } } else // 슬랏에 아무런 기존의 아이템이 없을때. { // Inventory에 특정 아이템을 넣는다. pArmsbandInventory->addItem(SlotID, 0 , pItem); // 넣기에 성공하면 마우스에 달려있는 아이템을 없앤다. pOusters->deleteItemFromExtraInventorySlot(); //pItem->save(pOusters->getName(), STORAGE_BELT, pArmsband->getItemID(), SlotID, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Storage=%d, StorageID=%lu, X=%d", STORAGE_BELT, pArmsband->getItemID(), SlotID); pItem->tinysave(pField); Success = true; } } // end of if (pArmsbandInventory->canAdding(SlotID, 0, pItem)) } // if (pCreature->isOusters()) // QuickSlot에 넣는 것을 실패 하였을때 실패 패킷을 날린다. if (!Success) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); } #endif // __GAME_SERVER__ __END_DEBUG_EX __END_CATCH }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionTradeGiftBox::execute(Creature * pCreature1 , Creature * pCreature2) throw(Error) { __BEGIN_TRY Assert(pCreature1 != NULL); Assert(pCreature2 != NULL); Assert(pCreature1->isNPC()); Assert(pCreature2->isPC()); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature2); Assert(pPC != NULL); Player* pPlayer = pPC->getPlayer(); Assert(pPlayer != NULL); Inventory* pInventory = pPC->getInventory(); Assert(pInventory != NULL); Zone* pZone = pPC->getZone(); Assert(pZone != NULL); FlagSet* pFlagSet = pPC->getFlagSet(); Item::ItemClass ItemClass; ItemType_t ItemType; OptionType_t OptionType; Item* pItem; Item* pGiftBoxItem; // 이미 선물을 교환해 갔다면 if (pFlagSet->isOn(FLAGSET_TRADE_GIFT_BOX_2002_12 ) ) { GCNPCResponse response; response.setCode(NPC_RESPONSE_TRADE_GIFT_BOX_ALREADY_TRADE); pPlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } // 빨간 선물 상자가 있는지 확인한다. CoordInven_t X,Y; pGiftBoxItem = pInventory->findItem(Item::ITEM_CLASS_EVENT_GIFT_BOX, 1, X, Y); if (pGiftBoxItem == NULL ) { GCNPCResponse response; response.setCode(NPC_RESPONSE_TRADE_GIFT_BOX_NO_ITEM); pPlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } LuaSelectItem* pLuaSelectItem = NULL; string luaFileName; if (pPC->isSlayer() ) { // 루아에 슬레이어 능력치의 합을 set한다. Slayer* pSlayer = dynamic_cast<Slayer*>(pPC); Assert(pSlayer != NULL); Attr_t sum = pSlayer->getSTR(ATTR_BASIC ) + pSlayer->getDEX(ATTR_BASIC ) + pSlayer->getINT(ATTR_BASIC); m_pLuaSlayerItem->setSum(sum); pLuaSelectItem = m_pLuaSlayerItem; luaFileName = m_SlayerFilename; } else if (pPC->isVampire() ) { // 루아에 뱀파이어의 레벨을 set한다. Vampire* pVampire = dynamic_cast<Vampire*>(pPC); Assert(pVampire != NULL); int level = pVampire->getLevel(); m_pLuaVampireItem->setLevel(level); pLuaSelectItem = m_pLuaVampireItem; luaFileName = m_VampireFilename; } //-------------------------------------------------------- // 속도 체크를 위해서 1000번 돌려보는 코드 // 결과는.. 0.07초 정도 나왔다. 감덩~ -_-; /* Timeval beforeTime; getCurrentTime(beforeTime); for (int i=0; i<1000; i++) { // 루아의 계산 결과를 받아 아이템을 생성한다. pLuaSelectItem->prepare(); int result = pLuaSelectItem->executeFile(luaFileName); LuaState::logError(result); pLuaSelectItem->clear(); } Timeval afterTime; getCurrentTime(afterTime); cout << "luaExecute time before : " << beforeTime.tv_sec << "." << beforeTime.tv_usec << endl; cout << "luaExecute time after : " << afterTime.tv_sec << "." << afterTime.tv_usec << endl; */ //-------------------------------------------------------- // 루아의 계산 결과를 받아 아이템을 생성한다. pLuaSelectItem->prepare(); int result = pLuaSelectItem->executeFile(luaFileName); LuaState::logError(result); ItemClass = pLuaSelectItem->getItemClass(); ItemType = pLuaSelectItem->getItemType(); OptionType = pLuaSelectItem->getOptionType(); pLuaSelectItem->clear(); if(ItemClass >= Item::ITEM_CLASS_MAX ) //|| ItemType >= ITEM_TYPE_MAX || ItemType < 0 // || OptionType == 0) { filelog("XMasEventError.txt", "[ ItemInfo Error ] : ItemClass = %d , ItemType = %d , OptionType = %d", ItemClass, ItemType, OptionType); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } // 클라이언트에 선물상자를 지우도록 한다. GCDeleteInventoryItem gcDeleteInventoryItem; gcDeleteInventoryItem.setObjectID(pGiftBoxItem->getObjectID()); pPlayer->sendPacket(&gcDeleteInventoryItem); // 선물상자를 지운다. pInventory->deleteItem(X, Y); // ItemTraceLog 를 남긴다 if (pGiftBoxItem != NULL && pGiftBoxItem->isTraceItem() ) { remainTraceLog(pGiftBoxItem, pCreature2->getName(), pCreature1->getName(), ITEM_LOG_DELETE, DETAIL_EVENTNPC); } pGiftBoxItem->destroy(); SAFE_DELETE(pGiftBoxItem); // 선물(Item)을 만든다. list<OptionType_t> optionTypeList; if (OptionType != 0 ) optionTypeList.push_back(OptionType); pItem = g_pItemFactoryManager->createItem(ItemClass, ItemType, optionTypeList); Assert(pItem != NULL); // 선물을 인벤토리에 추가한다. pZone->getObjectRegistry().registerObject(pItem); pInventory->addItem(X, Y, pItem); pItem->create(pPC->getName(), STORAGE_INVENTORY, 0, X, Y); // ItemTraceLog 를 남긴다 if (pItem != NULL && pItem->isTraceItem() ) { remainTraceLog(pItem, pCreature1->getName(), pCreature2->getName(), ITEM_LOG_CREATE, DETAIL_EVENTNPC); } // 클라이언트에 선물이 추가되었음을 알린다. GCCreateItem gcCreateItem; makeGCCreateItem(&gcCreateItem, pItem, X, Y); pPlayer->sendPacket(&gcCreateItem); // Flag을 켠다. pFlagSet->turnOn(FLAGSET_TRADE_GIFT_BOX_2002_12); // Flag을 저장한다. pFlagSet->save(pPC->getName()); // 아이템 교환이 이루어 졌다고 클라이언트에 알린다. GCNPCResponse response; response.setCode(NPC_RESPONSE_TRADE_GIFT_BOX_OK); pPlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); __END_CATCH }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionTradeLairItem::execute(Creature * pCreature1 , Creature * pCreature2) throw(Error) { __BEGIN_TRY Assert(pCreature1 != NULL); Assert(pCreature2 != NULL); Assert(pCreature1->isNPC()); Assert(pCreature2->isPC()); if (m_Type <= 5 ) { SYSTEM_RETURN_IF_NOT(SYSTEM_MASTER_LAIR); } PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature2); Assert(pPC != NULL); Player* pPlayer = pPC->getPlayer(); Assert(pPlayer != NULL); GCNPCResponse okpkt; pPlayer->sendPacket(&okpkt); StringStream message; /* GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage("아직 지원되지 않는 기능입니다"); pPlayer->sendPacket(&gcSystemMessage); */ //cout << "ActionTradeLairItem" << ":" << m_Type; Inventory* pInventory = pPC->getInventory(); // 먼저 아이템을 가지고 있는가를 체크한다. Item* pMasterItem = NULL; MonsterType_t MonsterType = 0; Item* pItem1 = NULL; bool bUpgrade = false; // 옵션에 따라서 다른 아이템을 검사해야 한다. // 코난 : 팬던트/ 비쥬만 체크한다. // 브리콜라카스: 테페즈 펜던트/비쥬만 체크해야 한다 // 카임 : 바토리 팬던트/비쥬만 체크해야 한다. if (m_Type == 0) // 코난, 비쥬 { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 0); MonsterType = BATORI_TYPE; if (pMasterItem == NULL ) { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 2); MonsterType = TEPEZ_TYPE; if (pMasterItem == NULL ) { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 8); //질드레 비쥬 MonsterType = GDR_TYPE; bUpgrade = true; } } } else if (m_Type == 1) // 코난, 팬던트 { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 1); MonsterType = BATORI_TYPE; if (pMasterItem == NULL) { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 3); MonsterType = TEPEZ_TYPE; if (pMasterItem == NULL ) { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 9); //질드레 펜던트 MonsterType = GDR_TYPE; bUpgrade = true; } } } else if (m_Type == 2) // 브리콜라카스, 비쥬 { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 2); // if (pMasterItem == NULL ) pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 8); //질드레 비쥬 MonsterType = TEPEZ_TYPE; } else if (m_Type == 3) // 브리콜라카스, 팬던트 { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 3); // if (pMasterItem == NULL ) pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 9); //질드레 펜던트 MonsterType = TEPEZ_TYPE; } else if (m_Type == 4) // 카임, 비쥬 { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 0); // if (pMasterItem == NULL ) pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 8); //질드레 비쥬 MonsterType = BATORI_TYPE; } else if (m_Type == 5) // 카임, 팬던트 { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 1); // if (pMasterItem == NULL ) pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 9); //질드레 펜던트 MonsterType = BATORI_TYPE; } else if (m_Type == 10) // 질드레, 비쥬 { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 8); bUpgrade = true; MonsterType = GDR_TYPE; } else if (m_Type == 11) // 질드레, 팬던트 { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 9); bUpgrade = true; MonsterType = GDR_TYPE; } else if (m_Type == 6) // 젬스톤이지롱~ { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 4); MonsterType = BATORI_TYPE; } else if (m_Type == 7) // 보름달~ { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 5); ItemMineInfo* pItemMineInfo; if (pPC->isSlayer() ) { Slayer* pSlayer = dynamic_cast<Slayer*>(pPC); Assert(pSlayer != NULL); Attr_t totalAttr = pSlayer->getTotalAttr(ATTR_BASIC); if (totalAttr <= 130 ) // 하드코딩 ㅜ.ㅠ pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(0); else if (totalAttr <= 210 ) pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(1); else if (totalAttr <= 270 ) pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(2); else if (totalAttr <= 300 ) pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(3); else pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(4); } else if (pPC->isVampire() ) { Vampire* pVampire = dynamic_cast<Vampire*>(pPC); Assert(pVampire != NULL); Level_t level = pVampire->getLevel(); if (level <= 20 ) pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(5); else if (level <= 40 ) pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(6); else if (level <= 60 ) pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(7); else if (level <= 90 ) pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(8); else pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(9); } else if (pPC->isOusters() ) { Ousters* pOusters = dynamic_cast<Ousters*>(pPC); Assert(pOusters != NULL); Level_t level = pOusters->getLevel(); if (level <= 20 ) pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(10); else if (level <= 40 ) pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(11); else if (level <= 60 ) pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(12); else if (level <= 90 ) pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(13); else pItemMineInfo = g_pItemMineInfoManager->getItemMineInfo(14); } else Assert(false); pItem1 = pItemMineInfo->getItem(); setItemGender(pItem1, (pPC->getSex()==FEMALE)?GENDER_FEMALE:GENDER_MALE); } else if (m_Type == 8) // 그믐달~ { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 6); if (pPC->isSlayer() ) { pItem1 = g_pItemMineInfoManager->getRandomItem(15, 32); } else if (pPC->isVampire() ) { pItem1 = g_pItemMineInfoManager->getRandomItem(33, 45); } else if (pPC->isOusters() ) { pItem1 = g_pItemMineInfoManager->getRandomItem(46, 61); } setItemGender(pItem1, (pPC->getSex()==FEMALE)?GENDER_FEMALE:GENDER_MALE); } else if (m_Type == 9) // 빨간색 복주머니 { pMasterItem = pInventory->findItem(Item::ITEM_CLASS_QUEST_ITEM, 7); if (pPC->isSlayer() ) { pItem1 = g_pItemMineInfoManager->getRandomItem(62, 81); } else if (pPC->isVampire() ) { pItem1 = g_pItemMineInfoManager->getRandomItem(82, 96); } else if (pPC->isOusters() ) { pItem1 = g_pItemMineInfoManager->getRandomItem(97, 112); } } else { // 거래를 위한 NPC의 Property가 잘못되었다. 이런 경우에는 // 운영팀으로 문의를 하면 바로 처리를 할 수 있다. GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NPC_ERROR )); pPlayer->sendPacket(&gcSystemMessage); GCNPCResponse response; response.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&response); return; } if (pMasterItem == NULL) { GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NO_LAIR_ITEM )); pPlayer->sendPacket(&gcSystemMessage); GCNPCResponse response; response.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&response); return; } Zone* pZone = pPC->getZone(); // if (MonsterType != 0 ) // 루팅표를 참조해서 아이템을 만들어오는 경우 if (pItem1 == NULL ) { QuestItemInfo* pItemInfo = dynamic_cast<QuestItemInfo*>(g_pQuestItemInfoManager->getItemInfo(pMasterItem->getItemType() )); Assert(pItemInfo!=NULL); /////////////////////////////////////////////////////////////////////////////// // 가장 난감한 부분 // 아이템을 랜덤하게 선택해야 한다. // 일단은 기본 아이템 하나로 한다. ////////////////////////////////////////////////////////////////////////////// const MonsterInfo* pMonsterInfo = g_pMonsterInfoManager->getMonsterInfo(MonsterType); TreasureList *pTreasureList = NULL; // 종족에 따라서 주는 아이템도 달라야 한다. if (pCreature2->isSlayer()) pTreasureList = pMonsterInfo->getSlayerTreasureList(); else if (pCreature2->isVampire()) pTreasureList = pMonsterInfo->getVampireTreasureList(); else if (pCreature2->isOusters()) pTreasureList = pMonsterInfo->getOustersTreasureList(); const list<Treasure*>& treasures = pTreasureList->getTreasures(); list<Treasure*>::const_iterator itr = treasures.begin(); ITEM_TEMPLATE it; for(; itr != treasures.end(); itr++) { Treasure* pTreasure = (*itr); it.ItemClass = Item::ITEM_CLASS_MAX; it.ItemType = 0; // QuestItem 마다 다른.. 옵션이 2개 붙을 확률 it.NextOptionRatio = pItemInfo->getBonusRatio(); //cout << "TradeLairItem: BonusRatio = " << it.NextOptionRatio << endl; if (pTreasure->getRandomItem(&it) ) { /* if (bUpgrade && isPossibleUpgradeItemType(it.ItemClass ) ) { it.ItemType = getUpgradeItemType(it.ItemClass, it.ItemType, 1); } */ pItem1 = g_pItemFactoryManager->createItem(it.ItemClass, it.ItemType, it.OptionType); Assert(pItem1 != NULL); } } if (pItem1 == NULL) { StringStream msg; msg << "ActionTradeLairItem: " << (int)it.ItemClass << ", " << (int)it.ItemType << ", " << (int)it.bCreateOption << ", " << getOptionTypeToString(it.OptionType); filelog("tradeLairItemBUG.txt", "%s", msg.toString().c_str()); GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_ITEM_CREATE_ERROR )); pPlayer->sendPacket(&gcSystemMessage); GCNPCResponse response; response.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&response); return; } } TPOINT pt; pItem1->setGrade(min(7,ItemGradeManager::Instance().getRandomBeadGrade())); pZone->registerObject(pItem1); // 만약 inventory에 공간이 있다면, 넣는다. if(pInventory->addItem(pItem1, pt)) { pItem1->create(pPC->getName(), STORAGE_INVENTORY, 0, pt.x, pt.y); GCCreateItem gcCreateItem; /* gcCreateItem.setObjectID(pItem1->getObjectID()); gcCreateItem.setItemClass(pItem1->getItemClass()); gcCreateItem.setItemType(pItem1->getItemType()); gcCreateItem.setOptionType(pItem1->getOptionTypeList()); gcCreateItem.setDurability(pItem1->getDurability()); gcCreateItem.setItemNum(pItem1->getNum()); gcCreateItem.setInvenX(pt.x); gcCreateItem.setInvenY(pt.y); gcCreateItem.setGrade(pItem1->getGrade());*/ makeGCCreateItem(&gcCreateItem, pItem1, pt.x, pt.y); pPlayer->sendPacket(&gcCreateItem); // ItemTraceLog 를 남긴다 if (pItem1 != NULL && pItem1->isTraceItem() ) { remainTraceLog(pItem1, pCreature1->getName(), pCreature2->getName(), ITEM_LOG_CREATE, DETAIL_EVENTNPC); } // 기존의 아이템을 없앤다 GCDeleteInventoryItem gcDeleteInventoryItem; gcDeleteInventoryItem.setObjectID(pMasterItem->getObjectID()); pPlayer->sendPacket(&gcDeleteInventoryItem); // 서버에서 없애준다. pInventory->deleteItem(pMasterItem->getObjectID()); // 좌표로 바꿔주면 좋을건데.. // ItemTraceLog 를 남긴다 if (pMasterItem != NULL && pMasterItem->isTraceItem() ) { remainTraceLog(pMasterItem, pCreature2->getName(), pCreature1->getName(), ITEM_LOG_DELETE, DETAIL_EVENTNPC); } pMasterItem->destroy(); SAFE_DELETE(pMasterItem); // 사용자에게 성공 메시지 출력 // StringStream message; // message << "성공적으로 교환되었습니다"; GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_TRADE_SUCCESS )); pPlayer->sendPacket(&gcSystemMessage); } else { // StringStream buf; // buf << "인벤토리에 공간이 부족합니다"; GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NOT_ENOUGH_INVENTORY_SPACE )); pPlayer->sendPacket(&gcSystemMessage); } GCNPCResponse response; response.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&response); __END_CATCH }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionGiveAccountEventItem::execute(Creature * pCreature1 , Creature * pCreature2) throw(Error) { __BEGIN_TRY Assert(pCreature1 != NULL); Assert(pCreature2 != NULL); Assert(pCreature1->isNPC()); Assert(pCreature2->isPC()); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature2); Assert(pPC != NULL); Player* pPlayer = pPC->getPlayer(); Assert(pPlayer != NULL); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); Inventory* pInventory = pPC->getInventory(); Assert(pInventory != NULL); Zone* pZone = pPC->getZone(); Assert(pZone != NULL); Item::ItemClass ItemClass; ItemType_t ItemType; OptionType_t OptionType; OptionType_t OptionType2; Item* pItem; // 이벤트가 진행중이지 않은 경우 if (!g_pVariableManager->isActiveGiveEventItem()) { GCNPCResponse response; response.setCode(NPC_RESPONSE_GIVE_EVENT_ITEM_FAIL_NOW); pPlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } // 이미 받았는지 체크한다. if (pGamePlayer->getSpecialEventCount() & m_SpecialEventFlag) { GCNPCResponse response; response.setCode(NPC_RESPONSE_GIVE_EVENT_ITEM_FAIL); pPlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } // 유료 사용자 여부를 체크한다. if (!PaySystem::isPayPlayingPeriodPersonal(pGamePlayer->getID() ) ) { GCNPCResponse response; response.setCode(NPC_RESPONSE_GIVE_PREMIUM_USER_ONLY); pPlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } LuaSelectItem* pLuaSelectItem = NULL; string luaFileName; if (pPC->isSlayer() ) { // 루아에 슬레이어 능력치의 합을 set한다. Slayer* pSlayer = dynamic_cast<Slayer*>(pPC); Assert(pSlayer != NULL); Attr_t sum = pSlayer->getSTR(ATTR_BASIC ) + pSlayer->getDEX(ATTR_BASIC ) + pSlayer->getINT(ATTR_BASIC); m_pLuaSlayerItem->setSum(sum); pLuaSelectItem = m_pLuaSlayerItem; luaFileName = m_SlayerFilename; } else if (pPC->isVampire() ) { // 루아에 뱀파이어의 레벨을 set한다. Vampire* pVampire = dynamic_cast<Vampire*>(pPC); Assert(pVampire != NULL); int level = pVampire->getLevel(); m_pLuaVampireItem->setLevel(level); pLuaSelectItem = m_pLuaVampireItem; luaFileName = m_VampireFilename; } // 루아의 계산 결과를 받아 아이템을 생성한다. pLuaSelectItem->prepare(); int result = pLuaSelectItem->executeFile(luaFileName); LuaState::logError(result); ItemClass = pLuaSelectItem->getItemClass(); ItemType = pLuaSelectItem->getItemType(); OptionType = pLuaSelectItem->getOptionType(); OptionType2 = pLuaSelectItem->getOptionType2(); pLuaSelectItem->clear(); if(ItemClass >= Item::ITEM_CLASS_MAX ) { filelog("AccountEventItemError.txt", "[ ItemInfo Error ] : ItemClass = %d , ItemType = %d , OptionType = %d", ItemClass, ItemType, OptionType); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } // 선물(Item)을 만든다. list<OptionType_t> optionTypeList; if (OptionType != 0 ) optionTypeList.push_back(OptionType); if (OptionType2 != 0 ) optionTypeList.push_back(OptionType2); pItem = g_pItemFactoryManager->createItem(ItemClass, ItemType, optionTypeList); Assert(pItem != NULL); // 인벤토리에 아이템을 넣을 빈 자리를 받아온다. TPOINT p; if (!pInventory->getEmptySlot(pItem, p)) { SAFE_DELETE(pItem); GCNPCResponse response; response.setCode(NPC_RESPONSE_NO_EMPTY_SLOT); pGamePlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } // 선물을 인벤토리에 추가한다. pZone->getObjectRegistry().registerObject(pItem); pInventory->addItem(p.x, p.y, pItem); pItem->create(pPC->getName(), STORAGE_INVENTORY, 0, p.x, p.y); // ItemTraceLog 를 남긴다 if (pItem != NULL && pItem->isTraceItem() ) { remainTraceLog(pItem, pCreature1->getName(), pCreature2->getName(), ITEM_LOG_CREATE, DETAIL_EVENTNPC); remainTraceLogNew(pItem, pCreature2->getName(), ITL_GET, ITLD_EVENTNPC, pCreature1->getZone()->getZoneID(), pCreature1->getX(), pCreature1->getY()); } // 클라이언트에 선물이 추가되었음을 알린다. GCCreateItem gcCreateItem; makeGCCreateItem(&gcCreateItem, pItem, p.x, p.y); pPlayer->sendPacket(&gcCreateItem); // 선물을 받았다고 Flag 를 켠다. pGamePlayer->setSpecialEventCount(pGamePlayer->getSpecialEventCount() | m_SpecialEventFlag); // Flag 를 저장한다. pGamePlayer->saveSpecialEventCount(); // 보상을 받았다고 클라이언트에 보낸다. GCNPCResponse response; response.setCode(NPC_RESPONSE_GIVE_EVENT_ITEM_OK); pPlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); __END_CATCH }
void CGShopRequestSellHandler::executeOpSwapAdvancementItem(CGShopRequestSell* pPacket, Player* pPlayer) throw(ProtocolException, Error) { __BEGIN_TRY #ifdef __GAME_SERVER__ ObjectID_t NPCID = pPacket->getObjectID(); ObjectID_t ITEMOID = pPacket->getItemObjectID(); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Creature* pCreature = pGamePlayer->getCreature(); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature); if (!pPC->isAdvanced() ) { return sendFailPacket(pPacket, pPlayer); } Zone* pZone = pPC->getZone(); if (pZone == NULL) return sendFailPacket(pPacket, pPlayer); Creature* pNPCBase = pZone->getCreature(NPCID); if (pNPCBase == NULL || !pNPCBase->isNPC()) return sendFailPacket(pPacket, pPlayer); NPC* pNPC = dynamic_cast<NPC*>(pNPCBase); Inventory* pInventory = pPC->getInventory(); Item* pItem = pInventory->getItemWithObjectID(ITEMOID); if (pItem == NULL || pItem->isTimeLimitItem() ) { return sendFailPacket(pPacket, pPlayer); } Item::ItemClass iClass = Item::ITEM_CLASS_MAX; ItemType_t iType = 0; Grade_t iGrade = 0; FlagSetType fType = FLAGSET_MAX; ItemInfo* pItemInfo = g_pItemInfoManager->getItemInfo(pItem->getItemClass(), pItem->getItemType()); Assert(pItemInfo!=NULL); switch (pItem->getItemClass() ) { case Item::ITEM_CLASS_SWORD: case Item::ITEM_CLASS_BLADE: case Item::ITEM_CLASS_AR: case Item::ITEM_CLASS_SR: case Item::ITEM_CLASS_SG: case Item::ITEM_CLASS_SMG: { switch (pItem->getItemType() ) { case 9: { iClass = pItem->getItemClass(); iType = 14; iGrade = 2; break; } case 11: { iClass = pItem->getItemClass(); iType = 14; iGrade = 4; break; } case 12: { iClass = pItem->getItemClass(); iType = 14; iGrade = 6; break; } case 13: { iClass = pItem->getItemClass(); iType = 14; iGrade = 8; break; } default: break; } if (iClass == Item::ITEM_CLASS_SG ) iClass = Item::ITEM_CLASS_SR; if (iClass == Item::ITEM_CLASS_SMG ) iClass = Item::ITEM_CLASS_AR; break; } case Item::ITEM_CLASS_CROSS: case Item::ITEM_CLASS_MACE: { switch (pItem->getItemType() ) { case 7: { iClass = pItem->getItemClass(); iType = 12; iGrade = 2; break; } case 9: { iClass = pItem->getItemClass(); iType = 12; iGrade = 4; break; } case 10: { iClass = pItem->getItemClass(); iType = 12; iGrade = 6; break; } case 11: { iClass = pItem->getItemClass(); iType = 12; iGrade = 8; break; } default: break; } break; } case Item::ITEM_CLASS_COAT: case Item::ITEM_CLASS_TROUSER: { switch (pItem->getItemType() ) { case 14: case 15: { iClass = pItem->getItemClass(); iType = 24 + (pItem->getItemType()%2); iGrade = 2; break; } case 18: case 19: case 20: case 21: case 22: case 23: { iClass = pItem->getItemClass(); iType = 24 + (pItem->getItemType()%2); iGrade = 4 + (((pItem->getItemType()-18)/2)*2); break; } default: break; } break; } case Item::ITEM_CLASS_VAMPIRE_WEAPON: { switch (pItem->getItemType() ) { case 14: { iClass = pItem->getItemClass(); iType = 19; iGrade = 2; break; } case 16: { iClass = pItem->getItemClass(); iType = 19; iGrade = 4; break; } case 17: { iClass = pItem->getItemClass(); iType = 19; iGrade = 6; break; } case 18: { iClass = pItem->getItemClass(); iType = 19; iGrade = 8; break; } default: break; } break; } case Item::ITEM_CLASS_VAMPIRE_COAT: { switch (pItem->getItemType() ) { case 10: case 11: { iClass = pItem->getItemClass(); iType = 20 + (pItem->getItemType()%2); iGrade = 2; break; } case 14: case 15: case 16: case 17: case 18: case 19: { iClass = pItem->getItemClass(); iType = 20 + (pItem->getItemType()%2); iGrade = 4 + (((pItem->getItemType()-14)/2)*2); break; } default: break; } break; } case Item::ITEM_CLASS_OUSTERS_CHAKRAM: { switch (pItem->getItemType() ) { case 9: { iClass = pItem->getItemClass(); iType = 14; iGrade = 2; break; } case 10: { iClass = pItem->getItemClass(); iType = 14; iGrade = 4; break; } case 11: { iClass = pItem->getItemClass(); iType = 14; iGrade = 6; break; } case 13: { iClass = pItem->getItemClass(); iType = 14; iGrade = 8; break; } default: break; } break; } case Item::ITEM_CLASS_OUSTERS_WRISTLET: { switch (pItem->getItemType() ) { case 9: case 30: case 31: case 39: { iClass = pItem->getItemClass(); iType = 42; iGrade = pItemInfo->getItemLevel() * 2 - 16; break; } case 19: case 32: case 33: case 40: { iClass = pItem->getItemClass(); iType = 43; iGrade = pItemInfo->getItemLevel() * 2 - 16; break; } case 29: case 34: case 35: case 41: { iClass = pItem->getItemClass(); iType = 44; iGrade = pItemInfo->getItemLevel() * 2 - 16; break; } default: break; } break; } case Item::ITEM_CLASS_OUSTERS_COAT: case Item::ITEM_CLASS_OUSTERS_BOOTS: { switch (pItem->getItemType() ) { case 7: { iClass = pItem->getItemClass(); iType = 12; iGrade = 2; break; } case 8: { iClass = pItem->getItemClass(); iType = 12; iGrade = 4; break; } case 9: { iClass = pItem->getItemClass(); iType = 12; iGrade = 6; break; } case 11: { iClass = pItem->getItemClass(); iType = 12; iGrade = 8; break; } default: break; } break; } default: break; } switch (iClass ) { case Item::ITEM_CLASS_SWORD: case Item::ITEM_CLASS_BLADE: case Item::ITEM_CLASS_AR: case Item::ITEM_CLASS_SR: case Item::ITEM_CLASS_CROSS: case Item::ITEM_CLASS_MACE: case Item::ITEM_CLASS_VAMPIRE_WEAPON: case Item::ITEM_CLASS_OUSTERS_CHAKRAM: case Item::ITEM_CLASS_OUSTERS_WRISTLET: fType = FLAGSET_SWAP_WEAPON; break; case Item::ITEM_CLASS_COAT: case Item::ITEM_CLASS_VAMPIRE_COAT: case Item::ITEM_CLASS_OUSTERS_COAT: fType = FLAGSET_SWAP_COAT; break; case Item::ITEM_CLASS_TROUSER: case Item::ITEM_CLASS_OUSTERS_BOOTS: fType = FLAGSET_SWAP_TROUSER; break; default: break; } if (iClass == Item::ITEM_CLASS_MAX || fType == FLAGSET_MAX ) { sendFailPacket(pPacket, pPlayer); return; } FlagSet* pFlagSet = pPC->getFlagSet(); if (pFlagSet->isOn(fType) ) { sendFailPacket(pPacket, pPlayer); return; } Item* pNewItem = g_pItemFactoryManager->createItem(iClass, iType, pItem->getOptionTypeList()); if (pNewItem == NULL ) { sendFailPacket(pPacket, pPlayer); return; } pNewItem->setGrade(iGrade); _TPOINT tp; if (!pInventory->getEmptySlot(pNewItem, tp) ) { SAFE_DELETE(pNewItem); sendFailPacket(pPacket, pPlayer); return; } filelog("ItemSwap.log", "[%s:%s] %s <-> %s", pGamePlayer->getID().c_str(), pPC->getName().c_str(), pItem->toString().c_str(), pNewItem->toString().c_str()); pNewItem->setTraceItem(bTraceLog(pNewItem )); pInventory->deleteItem(ITEMOID); pItem->whenPCLost(pPC); if (!pItem->destroy()) { filelog("shopDBBug.txt", "NoSuchItemInDB-destroy: %s", pItem->toString().c_str()); throw DisconnectException("아이템 지울려는데 DB에 없다."); } pZone->registerObject(pNewItem); GCShopSellOK okpkt; okpkt.setObjectID(NPCID); okpkt.setShopVersion(-1); okpkt.setItemObjectID(ITEMOID); okpkt.setPrice(0); pGamePlayer->sendPacket(&okpkt); // 삭제할 아이템의 ItemTrace Log 를 남겨야 한다면 남긴다 if (pItem != NULL && pItem->isTraceItem() ) { remainTraceLog(pItem, pCreature->getName() , pNPC->getName(), ITEM_LOG_DELETE, DETAIL_SHOPSELL); } // 인벤토리에 추가 Assert(pInventory->addItem(pNewItem, tp )); // DB 에 생성 pNewItem->create(pPC->getName(), STORAGE_INVENTORY, 0, tp.x, tp.y); // 교환해줄 아이템의 ItemTrace Log 를 남겨야 한다면 남긴다 if (pNewItem->isTraceItem() ) { remainTraceLog(pNewItem, pNPC->getName() , pCreature->getName(), ITEM_LOG_CREATE, DETAIL_SHOPBUY); } pFlagSet->turnOn(fType); pFlagSet->save(pPC->getName()); GCCreateItem gcCI; makeGCCreateItem(&gcCI, pNewItem, tp.x, tp.y); pGamePlayer->sendPacket(&gcCI); #endif __END_CATCH }
////////////////////////////////////////////////////////////////////////////// // 슬레이어 오브젝트 핸들러 ////////////////////////////////////////////////////////////////////////////// void Restore::execute(Slayer* pSlayer, ObjectID_t TargetObjectID, SkillSlot* pSkillSlot, CEffectID_t CEffectID) throw(Error) { __BEGIN_TRY //cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " Begin" << endl; //cout << "Restore2 Start" << endl; Assert(pSlayer != NULL); Assert(pSkillSlot != NULL); try { Player* pPlayer = pSlayer->getPlayer(); Zone* pZone = pSlayer->getZone(); Assert(pPlayer != NULL); Assert(pZone != NULL); Creature* pFromCreature = pZone->getCreature(TargetObjectID); // 뱀파이어만 건드릴 수가 있다. // NoSuch제거. by sigi. 2002.5.2 if (pFromCreature==NULL || !pFromCreature->isVampire()) { executeSkillFailException(pSlayer, getSkillType()); //cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl; return; } GCSkillToObjectOK1 _GCSkillToObjectOK1; // 스킬 쓴 넘에게... GCMorph1 _GCMorph1; // 변신 당사자에게.. GCMorphSlayer2 _GCMorphSlayer2; // 변신 구경꾼들에게.. SkillType_t SkillType = pSkillSlot->getSkillType(); SkillInfo* pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType); bool bRangeCheck = verifyDistance(pSlayer, pFromCreature, pSkillInfo->getRange()); bool bHitRoll = true; if (bRangeCheck && bHitRoll) { ////////////////////////////////////////////////////////////////////// // 각종 존 레벨 정보를 삭제해야 한다. ////////////////////////////////////////////////////////////////////// // 파티 초대 중이라면 정보를 삭제해 준다. PartyInviteInfoManager* pPIIM = pZone->getPartyInviteInfoManager(); Assert(pPIIM != NULL); pPIIM->cancelInvite(pFromCreature); // 파티 관련 정보를 삭제해 준다. int PartyID = pFromCreature->getPartyID(); if (PartyID != 0) { // 먼저 로컬에서 삭제하고... LocalPartyManager* pLPM = pZone->getLocalPartyManager(); Assert(pLPM != NULL); pLPM->deletePartyMember(PartyID, pFromCreature); // 글로벌에서도 삭제해 준다. deleteAllPartyInfo(pFromCreature); } // 트레이드 중이었다면 트레이드 관련 정보를 삭제해준다. TradeManager* pTM = pZone->getTradeManager(); Assert(pTM != NULL); pTM->cancelTrade(pFromCreature); ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// Slayer* pNewSlayer = new Slayer; Vampire* pVampire = dynamic_cast<Vampire*>(pFromCreature); // DB에서 혹시 남아있을 지 모르는 흡혈 정보를 삭제해준다. Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); StringStream sql; sql << "DELETE FROM EffectBloodDrain WHERE OwnerID = '" + pFromCreature->getName() + "'"; pStmt->executeQuery(sql.toString()); SAFE_DELETE(pStmt); } END_DB(pStmt) pNewSlayer->setName(pFromCreature->getName()); // 크리쳐 안의 플레이어 포인터와 플레이어 안의 크리쳐 포인터를 갱신한다. Player* pFromPlayer = pFromCreature->getPlayer(); pNewSlayer->setPlayer(pFromPlayer); GamePlayer* pFromGamePlayer = dynamic_cast<GamePlayer*>(pFromPlayer); pFromGamePlayer->setCreature(pNewSlayer); pNewSlayer->setZone(pZone); pNewSlayer->load(); pNewSlayer->setObjectID(pFromCreature->getObjectID()); pNewSlayer->setMoveMode(Creature::MOVE_MODE_WALKING); ZoneCoord_t x = pFromCreature->getX(); ZoneCoord_t y = pFromCreature->getY(); Dir_t dir = pFromCreature->getDir(); Tile& tile = pZone->getTile(x, y); // 곧 pFromCreature 즉, 원래의 뱀파이어 객체는 지워질 것이므로, // PCFinder에 들어가 있는 값은 쓰레기 값이 될 것이다. // 그러므로 뱀파이어 포인터를 지워주고, 새로운 슬레이어 포인터를 더한다. g_pPCFinder->deleteCreature(pFromCreature->getName()); g_pPCFinder->addCreature(pNewSlayer); // 길드 현재 접속 멤버 리스트에서 삭제한다. if (pVampire->getGuildID() != 0 ) g_pGuildManager->getGuild(pVampire->getGuildID() )->deleteCurrentMember(pVampire->getName()); // 인벤토리 교체. Inventory* pInventory = pVampire->getInventory(); pNewSlayer->setInventory(pInventory); pVampire->setInventory(NULL); // 보관함 교체 pNewSlayer->deleteStash(); pNewSlayer->setStash(pVampire->getStash()); pNewSlayer->setStashNum(pVampire->getStashNum()); pNewSlayer->setStashStatus(false); pVampire->setStash(NULL); /* // 가비지 교체 while (true) { Item* pGarbage = pVampire->popItemFromGarbage(); // 더 이상 없다면 브레이크... if (pGarbage == NULL) break; pNewSlayer->addItemToGarbage(pGarbage); } */ // 플래그 셋 교체 pNewSlayer->deleteFlagSet(); pNewSlayer->setFlagSet(pVampire->getFlagSet()); pVampire->setFlagSet(NULL); Item* pItem = NULL; _TPOINT point; // 입고 있는 아이템들을 인벤토리 또는 바닥으로 옮긴다. for(int part = 0; part < (int)Vampire::VAMPIRE_WEAR_MAX; part++) { pItem = pVampire->getWearItem((Vampire::WearPart)part); if (pItem != NULL) { // 먼저 기어에서 삭제하고... pVampire->deleteWearItem((Vampire::WearPart)part); // 인벤토리에 자리가 있으면 인벤토리에 더하고... if (pInventory->getEmptySlot(pItem, point)) { pInventory->addItem(point.x, point.y, pItem); pItem->save(pNewSlayer->getName(), STORAGE_INVENTORY, 0, point.x, point.y); } // 자리가 없으면 바닥에 떨어뜨린다. else { ZoneCoord_t ZoneX = pVampire->getX(); ZoneCoord_t ZoneY = pVampire->getY(); TPOINT pt; pt = pZone->addItem(pItem, ZoneX , ZoneY); if (pt.x != -1) { pItem->save("", STORAGE_ZONE, pZone->getZoneID(), pt.x, pt.y); } else { pItem->destroy(); SAFE_DELETE(pItem); } } } } pItem = pVampire->getExtraInventorySlotItem(); if (pItem != NULL) { pVampire->deleteItemFromExtraInventorySlot(); // 인벤토리에 자리가 있으면 인벤토리에 더하고... if (pInventory->getEmptySlot(pItem, point)) { pInventory->addItem(point.x, point.y, pItem); pItem->save(pNewSlayer->getName(), STORAGE_INVENTORY, 0, point.x, point.y); } // 자리가 없으면 바닥에 떨어뜨린다. else { TPOINT pt; ZoneCoord_t ZoneX = pVampire->getX(); ZoneCoord_t ZoneY = pVampire->getY(); pt = pZone->addItem(pItem, ZoneX , ZoneY); if (pt.x != -1) { pItem->save("", STORAGE_ZONE, pZone->getZoneID(), pt.x, pt.y); } else { pItem->destroy(); SAFE_DELETE(pItem); } } } // 뱀파이어 가지고 있던 돈을 슬레이어로 옮겨준다. pNewSlayer->setGoldEx(pVampire->getGold()); // 스킬 정보를 전송한다. pNewSlayer->sendSlayerSkillInfo(); _GCMorph1.setPCInfo2(pNewSlayer->getSlayerInfo2()); _GCMorph1.setInventoryInfo(pNewSlayer->getInventoryInfo()); _GCMorph1.setGearInfo(pNewSlayer->getGearInfo()); _GCMorph1.setExtraInfo(pNewSlayer->getExtraInfo()); _GCMorphSlayer2.setSlayerInfo(pNewSlayer->getSlayerInfo3()); pFromPlayer->sendPacket(&_GCMorph1); //pFromGamePlayer->deleteEvent(Event::EVENT_CLASS_REGENERATION); pZone->broadcastPacket(x, y, &_GCMorphSlayer2, pNewSlayer); // 타일 및 존에서 기존 뱀파이어를 삭제하고, 새로운 슬레이어를 더한다. tile.deleteCreature(pFromCreature->getObjectID()); pZone->deletePC(pFromCreature); TPOINT pt = findSuitablePosition(pZone, x, y, Creature::MOVE_MODE_WALKING); Tile& newtile = pZone->getTile(pt.x, pt.y); newtile.addCreature(pNewSlayer); pNewSlayer->setXYDir(pt.x, pt.y, dir); pZone->addPC(pNewSlayer); pNewSlayer->tinysave("Race='SLAYER'"); SAFE_DELETE(pFromCreature); // 시야 update.. pZone->updateHiddenScan(pNewSlayer); _GCSkillToObjectOK1.setSkillType(SkillType); _GCSkillToObjectOK1.setCEffectID(CEffectID); _GCSkillToObjectOK1.setTargetObjectID(TargetObjectID); _GCSkillToObjectOK1.setDuration(0); pPlayer->sendPacket(&_GCSkillToObjectOK1); pSkillSlot->setRunTime(0); EffectRestore* pEffectRestore = new EffectRestore(pNewSlayer); pEffectRestore->setDeadline(60*60*24*7*10); // 7일 pNewSlayer->addEffect(pEffectRestore); pNewSlayer->setFlag(Effect::EFFECT_CLASS_RESTORE); pEffectRestore->create(pNewSlayer->getName()); } else { executeSkillFailNormal(pSlayer, getSkillType(), pFromCreature); } }
void CGTameMonsterHandler::execute (CGTameMonster* pPacket , Player* pPlayer) throw(Error) { __BEGIN_TRY #ifdef __GAME_SERVER__ GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pGamePlayer->getCreature()); Assert(pPC != NULL); Zone* pZone = pPC->getZone(); Assert(pZone != NULL); Monster* pMonster = dynamic_cast<Monster*>(pZone->getCreature(pPacket->getObjectID() )); if (pMonster == NULL ) return; Item* pItem = pPC->getExtraInventorySlotItem(); if (pItem == NULL || pItem->getItemClass() != Item::ITEM_CLASS_PET_FOOD || pItem->getNum() != 1 ) return; PetFoodInfo* pPetFoodInfo = dynamic_cast<PetFoodInfo*>(g_pPetFoodInfoManager->getItemInfo(pItem->getItemType() )); Assert(pPetFoodInfo != NULL); Inventory* pInventory = pPC->getInventory(); if (pInventory == NULL ) return; ItemType_t petType = PET_COMMON; PetItem* pPetItem = dynamic_cast<PetItem*>(g_pItemFactoryManager->createItem(Item::ITEM_CLASS_PET_ITEM, petType, list<OptionType_t>() )); Assert(pPetItem != NULL); _TPOINT pt; if (!pInventory->getEmptySlot(pPetItem, pt ) ) { GCCannotUse gcCannotUse; pGamePlayer->sendPacket(&gcCannotUse); SAFE_DELETE(pPetItem); return; } pPC->deleteItemFromExtraInventorySlot(); GCDeleteInventoryItem gcDI; gcDI.setObjectID(pItem->getObjectID()); pGamePlayer->sendPacket(&gcDI); pItem->destroy(); SAFE_DELETE(pItem); /* * 여기서 뭔가 확인을 해야 한다. */ int ratio = rand()%100; if (g_pVariableManager->getVariable(PET_DAY_EVENT) != 0 ) { ratio = 100; } // 공용 펫만 꼬실 수 있다. PetTypeInfo* pPetTypeInfo = PetTypeInfoManager::getInstance()->getPetTypeInfo(petType); if (pPetTypeInfo == NULL || pPetTypeInfo->getOriginalMonsterType() != pMonster->getMonsterType() || ratio >= pPetFoodInfo->getTameRatio() ) { //cout << "꼬시기 실패 : " << ratio << endl; SAFE_DELETE(pPetItem); pMonster->addEnemy(pPC); return; } pZone->deleteCreature(pMonster, pMonster->getX(), pMonster->getY()); SAFE_DELETE(pMonster); /* * 여기서 해당 펫의 정보를 가져와야 된다. */ PetInfo* pPetInfo = new PetInfo; pPetInfo->setPetType(petType); pPetInfo->setPetLevel(0); pPetInfo->setPetCreatureType(pPetTypeInfo->getPetCreatureType(0)); pPetInfo->setPetAttr(0xff); pPetInfo->setPetExp(0); pPetInfo->setPetAttrLevel(0); pPetInfo->setFoodType(pPetFoodInfo->getItemType()); pPetInfo->setGamble(0); pPetInfo->setCutHead(0); pPetInfo->setPetHP(pPetFoodInfo->getPetHP()); pPetInfo->setFeedTime(VSDateTime::currentDateTime()); // 양방향 링크 pPetItem->setPetInfo(pPetInfo); pPetInfo->setPetItem(pPetItem); pZone->registerObject(pPetItem); pInventory->addItem(pPetItem, pt); Assert(pt.x != -1); pPetItem->create(pPC->getName(), STORAGE_INVENTORY, 0, pt.x, pt.y); // TraceLog 를 남긴다. remainTraceLog(pPetItem, "GOD", pPC->getName(), ITEM_LOG_CREATE, DETAIL_PICKUP); GCCreateItem gcCreateItem; makeGCCreateItem(&gcCreateItem, pPetItem, pt.x, pt.y); pGamePlayer->sendPacket(&gcCreateItem); //pPetItem->whenPCTake(pPC); pPC->getGQuestManager()->tamePet(pPetInfo); addOlympicStat(pPC, 9); #endif __END_CATCH }
void CGAddInventoryToMouseHandler::execute(CGAddInventoryToMouse* pPacket , Player* pPlayer) throw(ProtocolException, Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); Creature* pCreature = pGamePlayer->getCreature(); Assert(pCreature != NULL); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPC != NULL); Zone* pZone = pPC->getZone(); Assert(pZone != NULL); if (pPC->getStore()->isOpen() ) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } CoordInven_t InvenX = pPacket->getX(); CoordInven_t InvenY = pPacket->getY(); ObjectID_t ItemOID = pPacket->getObjectID(); Inventory* pInventory = pPC->getInventory(); Assert(pInventory != NULL); int invenID = 0; /* Commenting the SubInventory stuff, since it's not supported by the client we use SubInventory* pInventoryItem = NULL; int invenID = 0; if (pPacket->getInventoryItemObjectID() != 0 ) { CoordInven_t X, Y; pInventoryItem = dynamic_cast<SubInventory*>(pInventory->findItemOID(pPacket->getInventoryItemObjectID(), X, Y )); if (pInventoryItem == NULL ) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } pInventory = pInventoryItem->getInventory(); invenID = pInventoryItem->getItemID(); } */ // 인벤토리 좌표를 넘어가면 곤란하다... if (InvenX >= pInventory->getWidth() || InvenY >= pInventory->getHeight()) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } Item* pItem = pInventory->getItem(InvenX, InvenY); Item* pExtraSlotItem = pPC->getExtraInventorySlotItem(); if (pPC->getStore()->hasItem(pItem ) ) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } // 더하고자 하는 아이템이 없거나, 이미 마우스에 뭔가가 붙어있다면 // 들 수 없다. if (pItem == NULL || pExtraSlotItem != NULL) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } // 일반적인 아이템 마우스 더하기 루틴 if (ItemOID != 0) { // OID가 일치하지 않으면 곤란하다... if (pItem->getObjectID() != ItemOID) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } pInventory->deleteItem(pItem->getObjectID()); pPC->addItemToExtraInventorySlot(pItem); //pItem->save(pPC->getName(), STORAGE_EXTRASLOT, 0, 0, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Storage=%d, StorageID=0", STORAGE_EXTRASLOT); pItem->tinysave(pField); TradeManager* pTradeManager = pZone->getTradeManager(); TradeInfo* pInfo = pTradeManager->getTradeInfo(pCreature->getName()); if (pInfo != NULL && pInfo->getStatus() == TRADE_FINISH) { GCTradeVerify gcTradeVerify; gcTradeVerify.setCode(GC_TRADE_VERIFY_CODE_INVENTORY_TO_MOUSE_OK); pPlayer->sendPacket(&gcTradeVerify); } } // 겹치는 아이템 분리하기 루틴 else { // 겹치는 아이템이 아니거나, 현재 숫자가 2 미만이라면 분리할 수 없다. if (!isStackable(pItem) || pItem->getNum() < 2 || (pItem->getItemClass() == Item::ITEM_CLASS_MOON_CARD && pItem->getItemType() == 2 && pItem->getNum() == 99) || pPC->getStore()->hasItem(pItem) ) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } // 기존의 아이템을 바탕으로 같은 아이템을 생성한다. Item::ItemClass IClass = pItem->getItemClass(); ItemType_t IType = pItem->getItemType(); const list<OptionType_t>& OType = pItem->getOptionTypeList(); Item* pNewItem = g_pItemFactoryManager->createItem(IClass, IType, OType); Assert(pNewItem != NULL); // 마우스에다 더할 아이템은 기존의 OID를 가져가고, // 인벤토리에 남을 아이템은 새로운 OID를 받아야 한다. Zone* pZone = pPC->getZone(); Assert(pZone != NULL); ObjectRegistry& OR = pZone->getObjectRegistry(); OR.registerObject(pNewItem); // 인벤토리에 남아있는 아이템의 숫자는 원래 숫자에서 1을 뺀 숫자가 된다. // 기존의 아이템은 마우스로 옮겨졌으므로, 숫자가 1이 된다. // 인벤토리에서 마우스로 옮겨진 아이템을 삭제하고, // 새로 생성된 아이템을 더한다. pInventory->deleteItem(pItem->getObjectID()); pPC->addItemToExtraInventorySlot(pItem); int NewNum = pItem->getNum() - 1; pNewItem->setNum(NewNum); pItem->setNum(1); pInventory->addItem(InvenX, InvenY, pNewItem); // 달라진 위치 정보를 세이브한다... //pItem->save(pPC->getName(), STORAGE_EXTRASLOT, 0, 0, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Num=%d, Storage=%d, StorageID=0", 1, STORAGE_EXTRASLOT); pItem->tinysave(pField); pNewItem->create(pPC->getName(), STORAGE_INVENTORY, invenID, InvenX, InvenY); //pNewItem->setNum(NewNum); // 위에서 했는데 또 하네. -_-; //pNewItem->save(pPC->getName(), STORAGE_INVENTORY, 0, InvenX, InvenY); // item저장 최적화. by sigi. 2002.5.13 sprintf(pField, "Num=%d, Storage=%d, StorageID=%u", NewNum, STORAGE_INVENTORY, invenID); pNewItem->tinysave(pField); // 클라이언트에게는 GCCreateItem 패킷을 이용해 // 인벤토리에 새로이(?) 생성된 아이템에 대한 정보를 보내준다. GCCreateItem gcCreateItem; gcCreateItem.setObjectID(pNewItem->getObjectID()); gcCreateItem.setItemClass((BYTE)pNewItem->getItemClass()); gcCreateItem.setItemType(pNewItem->getItemType()); gcCreateItem.setOptionType(pNewItem->getOptionTypeList()); gcCreateItem.setDurability(pNewItem->getDurability()); gcCreateItem.setSilver(pNewItem->getSilver()); gcCreateItem.setEnchantLevel(pNewItem->getEnchantLevel()); gcCreateItem.setItemNum(pNewItem->getNum()); gcCreateItem.setInvenX(InvenX); gcCreateItem.setInvenY(InvenY); pPlayer->sendPacket(&gcCreateItem); } #endif // __GAME_SERVER__ __END_DEBUG_EX __END_CATCH }
void CGAddMouseToInventoryHandler::execute(CGAddMouseToInventory* pPacket , Player* pPlayer) throw(ProtocolException, Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ Assert(pPacket != NULL); Assert(pPlayer != NULL); try { GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); Creature* pCreature = pGamePlayer->getCreature(); Assert(pCreature != NULL); Assert(pCreature->isPC()); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPC != NULL); Zone* pZone = pPC->getZone(); Assert(pZone != NULL); Inventory* pInventory = pPC->getInventory(); Assert(pInventory != NULL); Item* pItem = pPC->getExtraInventorySlot()->getItem(); bool Success = false; if (pItem == NULL) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } int invenID = 0; /* Commenting the SubInventory stuff, since it's not supported by the client we use SubInventory* pInventoryItem = NULL; int invenID = 0; if (pPacket->getInventoryItemObjectID() != 0 ) { // cout << "서브 인벤토리에 넣기 : " << pPacket->getInventoryItemObjectID() << endl; CoordInven_t X, Y; pInventoryItem = dynamic_cast<SubInventory*>(pInventory->findItemOID(pPacket->getInventoryItemObjectID(), X, Y )); TradeManager* pTradeManager = pZone->getTradeManager(); Assert(pTradeManager != NULL); if (pInventoryItem == NULL || pItem->getItemClass() == Item::ITEM_CLASS_SUB_INVENTORY || pTradeManager->hasTradeInfo(pPC->getName()) ) { // cout << "근데 서브 인벤토리가 없다." <<endl; GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } pInventory = pInventoryItem->getInventory(); invenID = pInventoryItem->getItemID(); } */ //Item::ItemClass itemClass = pItem->getItemClass(); //ItemType_t itemType = pItem->getItemType(); ObjectID_t itemObjectID = pItem->getObjectID(); CoordInven_t InvenX = pPacket->getInvenX(); CoordInven_t InvenY = pPacket->getInvenY(); if (InvenX >= pInventory->getWidth() || InvenY >= pInventory->getHeight() || itemObjectID != pPacket->getObjectID() || !pInventory->canAdding(InvenX, InvenY, pItem)) { GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); return; } TPOINT pt; pt.x = 99; pt.y = 99; // 넣을려는 Inventory Slot의 Item을 받아온다. Item* pPrevItem = pInventory->searchItem(InvenX, InvenY , pItem, pt); // 그 장소에 아이템이 있다면 if (pPrevItem != NULL) { bool bisSame = true; // 아이템 클래스가 같을때 숫자를 올려 주고 마우스에 있는 것은 없앤다. if (canStack(pItem, pPrevItem)) { int MaxStack = ItemMaxStack[pItem->getItemClass()]; VolumeWidth_t ItemWidth = pItem->getVolumeWidth(); VolumeHeight_t ItemHeight = pItem->getVolumeHeight(); VolumeWidth_t InvenWidth = pInventory->getWidth(); VolumeWidth_t InvenHeight= pInventory->getHeight(); if ((InvenX + ItemWidth <= InvenWidth) && (InvenY + ItemHeight <= InvenHeight)) { for (int x = InvenX; x < (InvenX + ItemWidth); x++) { for (int y = InvenY; y < (InvenY + ItemHeight); y++) { if (pInventory->hasItem(x, y)) { if(pInventory->getItem(x,y) != pPrevItem ) { bisSame = false; break; } } else { bisSame = false; break; } } } } // 들어갈 아이템과 들어있는 아이템의 좌표가 꼭 일치 한다면? if(bisSame) { // 숫자가 9개를 넘으면 9개 될때까지만 Add 하고 나머지는 마우스에 달아둔다. if (pItem->getNum() + pPrevItem->getNum() > MaxStack) { ItemNum_t CurrentNum = pPrevItem->getNum(); ItemNum_t AddNum = pItem->getNum(); ItemNum_t NewNum = AddNum + CurrentNum - MaxStack; pPrevItem->setNum(MaxStack); pItem->setNum(NewNum); pInventory->increaseNum(MaxStack - CurrentNum); pInventory->increaseWeight(pItem->getWeight()* (MaxStack - CurrentNum)); //pPrevItem->save(pPC->getName(), STORAGE_INVENTORY, 0, InvenX, InvenY); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Num=%d, Storage=%d, StorageID=%d, X=%d, Y=%d", MaxStack, STORAGE_INVENTORY, invenID, InvenX, InvenY); pPrevItem->tinysave(pField); //pItem->save(pPC->getName(), STORAGE_EXTRASLOT, 0, 0, 0); // item저장 최적화. by sigi. 2002.5.13 sprintf(pField, "Num=%d, Storage=%d", NewNum, STORAGE_EXTRASLOT); pItem->tinysave(pField); Success = true; } else { pPC->deleteItemFromExtraInventorySlot(); pPrevItem->setNum(pPrevItem->getNum() + pItem->getNum()); pInventory->increaseNum(pItem->getNum()); pInventory->increaseWeight(pItem->getWeight()* pItem->getNum()); //pPrevItem->save(pPC->getName(), STORAGE_INVENTORY, 0, InvenX, InvenY); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Num=%d, Storage=%d, StorageID=%u, X=%d, Y=%d", pPrevItem->getNum(), STORAGE_INVENTORY, invenID, InvenX, InvenY); pPrevItem->tinysave(pField); pItem->destroy(); SAFE_DELETE(pItem); Success = true; } if (g_pVariableManager->getVariable(NETMARBLE_CARD_EVENT) != 0 && pPrevItem->getItemClass() == Item::ITEM_CLASS_MOON_CARD && pPrevItem->getItemType() == 2 && pPrevItem->getNum() == 99) { GCNoticeEvent gcNE; gcNE.setCode(NOTICE_EVENT_NETMARBLE_CARD_FULL); pGamePlayer->sendPacket(&gcNE); //cout << "gcNE sent" << endl; } if (pPrevItem->getItemClass() == Item::ITEM_CLASS_LUCKY_BAG && pPrevItem->getItemType() == 3 && pPrevItem->getNum() == 50 ) { GCDeleteInventoryItem gcDI; gcDI.setObjectID(pPrevItem->getObjectID()); pGamePlayer->sendPacket(&gcDI); pInventory->deleteItem(pPrevItem->getObjectID()); pPrevItem->destroy(); SAFE_DELETE(pPrevItem); Item* pNewItem = g_pItemFactoryManager->createItem(Item::ITEM_CLASS_EVENT_ITEM, 28, list<OptionType_t>()); pZone->registerObject(pNewItem); if (!pInventory->addItem(pt.x, pt.y, pNewItem) ) return; pNewItem->create(pPC->getName(), STORAGE_INVENTORY, 0, pt.x, pt.y); if (pNewItem != NULL ) { GCCreateItem gcCI; makeGCCreateItem(&gcCI, pNewItem, pt.x, pt.y); pGamePlayer->sendPacket(&gcCI); } } } else { pInventory->deleteItem(pPrevItem->getObjectID()); pPC->deleteItemFromExtraInventorySlot(); pPC->addItemToExtraInventorySlot(pPrevItem); pInventory->addItem(InvenX , InvenY , pItem); //pPrevItem->save(pPC->getName(), STORAGE_EXTRASLOT, 0, 0, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Storage=%d", STORAGE_EXTRASLOT); pPrevItem->tinysave(pField); //pItem->save(pPC->getName(), STORAGE_INVENTORY, 0, InvenX, InvenY); // item저장 최적화. by sigi. 2002.5.13 sprintf(pField, "Storage=%d, StorageID=%u, X=%d, Y=%d", STORAGE_INVENTORY, invenID, InvenX, InvenY); pItem->tinysave(pField); Success = true; } } else {// 아이템 클래스가 다르거나, 쌓이는 아이템이 아니라면. pInventory->deleteItem(pPrevItem->getObjectID()); pPC->deleteItemFromExtraInventorySlot(); pPC->addItemToExtraInventorySlot(pPrevItem); pInventory->addItem(InvenX , InvenY , pItem); //pPrevItem->save(pPC->getName(), STORAGE_EXTRASLOT, 0, 0, 0); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Storage=%d", STORAGE_EXTRASLOT); pPrevItem->tinysave(pField); //pItem->save(pPC->getName(), STORAGE_INVENTORY, 0, InvenX, InvenY); // item저장 최적화. by sigi. 2002.5.13 sprintf(pField, "Storage=%d, StorageID=%u, X=%d, Y=%d", STORAGE_INVENTORY, invenID, InvenX, InvenY); pItem->tinysave(pField); Success = true; } } else { // 그 장소에 아이템이 없다면. //cout << "prevItem is NULL" << endl; // Inventory에 특정 아이템을 넣는다. pInventory->addItem(InvenX , InvenY , pItem); // 넣기에 성공하면 마우스에 달려있는 아이템을 없앤다. pPC->deleteItemFromExtraInventorySlot(); //pItem->save(pPC->getName(), STORAGE_INVENTORY, 0, InvenX, InvenY); // item저장 최적화. by sigi. 2002.5.13 char pField[80]; sprintf(pField, "Storage=%d, StorageID=%u, X=%d, Y=%d", STORAGE_INVENTORY, invenID, InvenX, InvenY); pItem->tinysave(pField); Success = true; } if (Success) { TradeManager* pTradeManager = pZone->getTradeManager(); TradeInfo* pInfo = pTradeManager->getTradeInfo(pCreature->getName()); if (pInfo != NULL && pInfo->getStatus() == TRADE_FINISH) { GCTradeVerify gcTradeVerify; gcTradeVerify.setCode(GC_TRADE_VERIFY_CODE_MOUSE_TO_INVENTORY_OK); pPlayer->sendPacket(&gcTradeVerify); } // 트리 조각일 경우 if (pItem != NULL && pItem->getItemClass() == Item::ITEM_CLASS_EVENT_TREE) { ItemType_t itemtype = pItem->getItemType(); // 크리스마스 트리 조각이면 if (itemtype <= 11) { // 크리스마스 트리 조각이 맞춰지는지 본다. TPOINT pt = checkEventPuzzle(pPC, InvenX, InvenY, 0); if (pt.x != -1 && pt.y != -1 ) { // 맞춰진 트리 조각을 지운다. deleteInventoryItem(pInventory, pt.x, pt.y, pt.x + 2, pt.y + 3); // 트리를 생성한다. list<OptionType_t> optionType; Item* pTreeItem = g_pItemFactoryManager->createItem(Item::ITEM_CLASS_EVENT_TREE, 12, optionType); pZone->getObjectRegistry().registerObject(pTreeItem); pInventory->addItem(pt.x, pt.y, pTreeItem); pTreeItem->create(pPC->getName(), STORAGE_INVENTORY, invenID, pt.x, pt.y); // 클라이언트에 트리가 만들어졌다는 걸 알린다. GCCreateItem gcCreateItem; makeGCCreateItem(&gcCreateItem, pTreeItem, pt.x, pt.y); pGamePlayer->sendPacket(&gcCreateItem); } } // 크리스마스 트리 조각이면 else if (itemtype > 12 && itemtype <= 24) { // 크리스마스 트리 조각이 맞춰지는지 본다. TPOINT pt = checkEventPuzzle(pPC, InvenX, InvenY, 13); if (pt.x != -1 && pt.y != -1) { // 맞춰진 트리 조각을 지운다. deleteInventoryItem(pInventory, pt.x, pt.y, pt.x + 2, pt.y + 3); // 트리를 생성한다. list<OptionType_t> optionType; Item* pTreeItem = g_pItemFactoryManager->createItem(Item::ITEM_CLASS_EVENT_TREE, 25, optionType); pTreeItem->setQuestItem(); pZone->getObjectRegistry().registerObject(pTreeItem); pInventory->addItem(pt.x, pt.y, pTreeItem); pTreeItem->create(pPC->getName(), STORAGE_INVENTORY, invenID, pt.x, pt.y); // 클라이언트에 트리가 만들어졌다는 걸 알린다. GCCreateItem gcCreateItem; makeGCCreateItem(&gcCreateItem, pTreeItem, pt.x, pt.y); pGamePlayer->sendPacket(&gcCreateItem); } } // 크리스마스 트리 조각이면 else if (itemtype > 28 && itemtype <= 40) { // 크리스마스 트리 조각이 맞춰지는지 본다. TPOINT pt = checkEventPuzzle(pPC, InvenX, InvenY, 29); if (pt.x != -1 && pt.y != -1) { // 맞춰진 트리 조각을 지운다. deleteInventoryItem(pInventory, pt.x, pt.y, pt.x + 2, pt.y + 3); // 트리를 생성한다. list<OptionType_t> optionType; Item* pTreeItem = g_pItemFactoryManager->createItem(Item::ITEM_CLASS_EVENT_TREE, 41, optionType); pTreeItem->setQuestItem(); pZone->getObjectRegistry().registerObject(pTreeItem); pInventory->addItem(pt.x, pt.y, pTreeItem); pTreeItem->create(pPC->getName(), STORAGE_INVENTORY, invenID, pt.x, pt.y); // 클라이언트에 트리가 만들어졌다는 걸 알린다. GCCreateItem gcCreateItem; makeGCCreateItem(&gcCreateItem, pTreeItem, pt.x, pt.y); pGamePlayer->sendPacket(&gcCreateItem); } } } } else { //cout << "cannot add" << endl; GCCannotAdd _GCCannotAdd; _GCCannotAdd.setObjectID(pPacket->getObjectID()); pPlayer->sendPacket(&_GCCannotAdd); } } catch (Throwable & t) {} #endif // __GAME_SERVER__ __END_DEBUG_EX __END_CATCH }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionGiveEventItem::execute(Creature * pCreature1 , Creature * pCreature2) throw(Error) { __BEGIN_TRY Assert(pCreature1 != NULL); Assert(pCreature2 != NULL); Assert(pCreature1->isNPC()); Assert(pCreature2->isPC()); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature2); Assert(pPC != NULL); Player* pPlayer = pPC->getPlayer(); Assert(pPlayer != NULL); Inventory* pInventory = pPC->getInventory(); Assert(pInventory != NULL); Zone* pZone = pPC->getZone(); Assert(pZone != NULL); FlagSet* pFlagSet = pPC->getFlagSet(); Item::ItemClass ItemClass; ItemType_t ItemType; OptionType_t OptionType; OptionType_t OptionType2; Item* pItem; // 이벤트 진행 기간이 아닌 경우 if (!g_pVariableManager->isActiveGiveEventItem()) { GCNPCResponse response; response.setCode(NPC_RESPONSE_GIVE_EVENT_ITEM_FAIL_NOW); pPlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } // 이 값과 관련해서 // 캐릭터 생성시에 FlagSet을 바꿔줘야한다. (default ON 으로) // 이미 선물을 교환해 갔다면 if (pFlagSet->isOn(m_FlagSetType ) ) { GCNPCResponse response; response.setCode(NPC_RESPONSE_GIVE_EVENT_ITEM_FAIL); pPlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } LuaSelectItem* pLuaSelectItem = NULL; string luaFileName; if (pPC->isSlayer() ) { // 루아에 슬레이어 능력치의 합을 set한다. Slayer* pSlayer = dynamic_cast<Slayer*>(pPC); Assert(pSlayer != NULL); Attr_t sum = pSlayer->getSTR(ATTR_BASIC ) + pSlayer->getDEX(ATTR_BASIC ) + pSlayer->getINT(ATTR_BASIC); m_pLuaSlayerItem->setSum(sum); pLuaSelectItem = m_pLuaSlayerItem; luaFileName = m_SlayerFilename; } else if (pPC->isVampire() ) { // 루아에 뱀파이어의 레벨을 set한다. Vampire* pVampire = dynamic_cast<Vampire*>(pPC); Assert(pVampire != NULL); int level = pVampire->getLevel(); m_pLuaVampireItem->setLevel(level); pLuaSelectItem = m_pLuaVampireItem; luaFileName = m_VampireFilename; } //-------------------------------------------------------- // 속도 체크를 위해서 1000번 돌려보는 코드 // 결과는.. 0.07초 정도 나왔다. 감덩~ -_-; /* Timeval beforeTime; getCurrentTime(beforeTime); for (int i=0; i<1000; i++) { // 루아의 계산 결과를 받아 아이템을 생성한다. pLuaSelectItem->prepare(); int result = pLuaSelectItem->executeFile(luaFileName); LuaState::logError(result); pLuaSelectItem->clear(); } Timeval afterTime; getCurrentTime(afterTime); cout << "luaExecute time before : " << beforeTime.tv_sec << "." << beforeTime.tv_usec << endl; cout << "luaExecute time after : " << afterTime.tv_sec << "." << afterTime.tv_usec << endl; */ //-------------------------------------------------------- // 루아의 계산 결과를 받아 아이템을 생성한다. pLuaSelectItem->prepare(); int result = pLuaSelectItem->executeFile(luaFileName); LuaState::logError(result); ItemClass = pLuaSelectItem->getItemClass(); ItemType = pLuaSelectItem->getItemType(); OptionType = pLuaSelectItem->getOptionType(); OptionType2 = pLuaSelectItem->getOptionType2(); pLuaSelectItem->clear(); if(ItemClass >= Item::ITEM_CLASS_MAX ) //|| ItemType >= ITEM_TYPE_MAX || ItemType < 0 // || OptionType == 0) { filelog("GiveEventItemError.txt", "[ ItemInfo Error ] : ItemClass = %d , ItemType = %d , OptionType = %d", ItemClass, ItemType, OptionType); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } // 선물(Item)을 만든다. list<OptionType_t> optionTypeList; if (OptionType != 0 ) optionTypeList.push_back(OptionType); if (OptionType2 != 0 ) optionTypeList.push_back(OptionType2); pItem = g_pItemFactoryManager->createItem(ItemClass, ItemType, optionTypeList); Assert(pItem != NULL); _TPOINT pt; if (!pInventory->getEmptySlot(pItem, pt)) { SAFE_DELETE(pItem); GCNPCResponse response; response.setCode(NPC_RESPONSE_NO_EMPTY_SLOT); pPlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); return; } CoordInven_t X = pt.x; CoordInven_t Y = pt.y; // 선물을 인벤토리에 추가한다. pZone->getObjectRegistry().registerObject(pItem); pInventory->addItem(X, Y, pItem); pItem->create(pPC->getName(), STORAGE_INVENTORY, 0, X, Y); // ItemTraceLog 를 남긴다 if (pItem != NULL && pItem->isTraceItem() ) { remainTraceLog(pItem, pCreature1->getName(), pCreature2->getName(), ITEM_LOG_CREATE, DETAIL_EVENTNPC); remainTraceLogNew(pItem, pCreature2->getName(), ITL_GET, ITLD_EVENTNPC, pCreature1->getZone()->getZoneID(), pCreature1->getX(), pCreature1->getY()); } // 클라이언트에 선물이 추가되었음을 알린다. GCCreateItem gcCreateItem; makeGCCreateItem(&gcCreateItem, pItem, X, Y); pPlayer->sendPacket(&gcCreateItem); // Flag을 켠다. pFlagSet->turnOn(m_FlagSetType); // Flag을 저장한다. pFlagSet->save(pPC->getName()); // 아이템 교환이 이루어 졌다고 클라이언트에 알린다. GCNPCResponse response; response.setCode(NPC_RESPONSE_GIVE_EVENT_ITEM_OK); pPlayer->sendPacket(&response); GCNPCResponse quit; quit.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pPlayer->sendPacket(&quit); __END_CATCH }