//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionMiniGame::execute (Creature * pCreature1 , Creature * pCreature2) throw(Error) { __BEGIN_TRY Assert(pCreature1 != NULL); Assert(pCreature2 != NULL); Assert(pCreature1->isNPC()); Assert(pCreature2->isPC()); GCNoticeEvent gcNoticeEvent; gcNoticeEvent.setCode(NOTICE_EVENT_MINI_GAME); gcNoticeEvent.setParameter((uint)m_GameType); // gcNoticeEvent.setNPCID(dynamic_cast<NPC*>(pCreature1)->getNPCID()); Player* pPlayer = pCreature2->getPlayer(); pPlayer->sendPacket(&gcNoticeEvent); __END_CATCH }
void CGSelectWayPointHandler::execute(CGSelectWayPoint* pPacket , Player* pPlayer) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ Assert(pPacket != NULL); Assert(pPlayer != NULL); static map<Level_t,Price_t> sPriceMap; try { int targetDynamicZoneType = g_pDynamicZoneInfoManager->getDynamicZoneTypeByZoneID(pPacket->getZoneID()); if (targetDynamicZoneType != DYNAMIC_ZONE_MAX) { executeEnterQuestZone(pPacket, pPlayer, targetDynamicZoneType); } // 게임 플레이어의 상태가 정상이 아니라면 걍 리턴한다. GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); if (pGamePlayer->getPlayerStatus() != GPS_NORMAL) return; // 크리쳐가 슬레이어가 아니라면 리턴한다. Creature* pCreature = pGamePlayer->getCreature(); Assert(pCreature != NULL); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPC != NULL); if (pPC->getStore()->isOpen()) return; if (pCreature->hasRelicItem()) return; // 크리쳐가 죽었으면 리턴 if (pCreature->isDead()) return; // 초보존으로 들어가는 경우엔 종족 상관없이 보내준다. if (pPacket->getZoneID() == 1122) { ZONE_COORD pos(1122); if (pCreature->isSlayer()) { pos.x = 107; pos.y = 27; } else if (pCreature->isVampire()) { pos.x = 18; pos.y = 27; } else if (pCreature->isOusters()) { pos.x = 12; pos.y = 103; } else return; if (!canEnterBeginnerZone(pCreature)) return; // 초보존이 유료존일수도 있을라나...? #if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__) ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(pos.id); // 유료존인데 유료사용자가 아니면... if (pZoneInfo == NULL || ((pZoneInfo->isPayPlay() || pZoneInfo->isPremiumZone()) && (!pGamePlayer->isPayPlaying() && !pGamePlayer->isFamilyFreePass()))) { //Statement* pStmt = NULL; string connectIP = pGamePlayer->getSocket()->getHost(); // 유료 서비스 사용이 가능한가? if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID())) { sendPayInfo(pGamePlayer); } else if (pZoneInfo->isPayPlay()) { // 유료 서비스 사용 불가인 경우 GCSystemMessage gcSystemMessage; if (g_pConfig->getPropertyInt("IsNetMarble") == 0) { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER)); } else { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER)); } pGamePlayer->sendPacket(&gcSystemMessage); return; } } #endif pPC->getGQuestManager()->illegalWarp(); transportCreature(pCreature, pos.id, pos.x, pos.y, false); return; } if (pPacket->getZoneID() == 1131) { if (g_pVariableManager->getVariable(ACTIVE_LEVEL_WAR) == 0) { GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER)); pGamePlayer->sendPacket(&gcSystemMessage); return; } /* if (g_pConfig->getPropertyInt("ServerID" ) != 0 ) { GCNoticeEvent gcNoticeEvent; gcNoticeEvent.setCode(NOTICE_EVENT_NOT_FIRST_SERVER); pGamePlayer->sendPacket(&gcNoticeEvent); // GCSystemMessage gcSystemMessage; // gcSystemMessage.setMessage(g_pStringPool->getString(STRID_LEVEL_WAR_ONLY_FIRST_SERVER )); // pGamePlayer->sendPacket (&gcSystemMessage); return; } */ // 크리쳐 정보 보고 알아서 튕겨주자 =_=;; ZONE_COORD pos(g_pLevelWarZoneInfoManager->getCreatureZoneID(pCreature )); if (g_pSweeperBonusManager->isAble(g_pLevelWarZoneInfoManager->getCreatureZoneID(pCreature))) { GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NO_WAR_IN_ACTIVE )); pGamePlayer->sendPacket (&gcSystemMessage); return; } if (pCreature->isSlayer()) { pos.x = 12; pos.y = 9; } else if (pCreature->isVampire()) { pos.x = 117; pos.y = 8; } else if (pCreature->isOusters()) { pos.x = 9; pos.y = 111; } #if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__) Zone* pZone = getZoneByZoneID(pos.id); Assert(pZone != NULL); LevelWarManager* pLevelWarManager = pZone->getLevelWarManager(); Assert(pLevelWarManager != NULL); if (!pLevelWarManager->hasWar() && !g_pVariableManager->canEnterLevelWarZoneFree() && !pGamePlayer->isPayPlaying() && pGamePlayer->isFamilyFreePass() && !pLevelWarManager->canEnterFreeUser()) { GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_LEVEL_WAR_ZONE)); pGamePlayer->sendPacket(&gcSystemMessage); return; } #endif pPC->getGQuestManager()->illegalWarp(); transportCreature(pCreature, pos.id, pos.x, pos.y, false); return; } if (pPacket->getZoneID() == 72) { if (!g_pWarSystem->hasActiveRaceWar()) { GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NO_WAR_IN_ACTIVE)); pGamePlayer->sendPacket (&gcSystemMessage); return; } /* if (g_pConfig->getPropertyInt("ServerID" ) != 0 ) { GCNoticeEvent gcNoticeEvent; gcNoticeEvent.setCode(NOTICE_EVENT_NOT_FIRST_SERVER); pGamePlayer->sendPacket(&gcNoticeEvent); // GCSystemMessage gcSystemMessage; // gcSystemMessage.setMessage(g_pStringPool->getString(STRID_LEVEL_WAR_ONLY_FIRST_SERVER )); // pGamePlayer->sendPacket (&gcSystemMessage); return; } */ // 크리쳐 정보 보고 알아서 튕겨주자 =_=;; ZONE_COORD pos; if (pCreature->isSlayer()) { pos.id = 73; pos.x = 30; pos.y = 124; } else if (pCreature->isVampire()) { pos.id = 71; pos.x = 104; pos.y = 128; } else if (pCreature->isOusters()) { pos.id = 72; pos.x = 67; pos.y = 165; } /*#if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__) ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(pos.id); // 유료존인데 유료사용자가 아니면... if (pZoneInfo==NULL || (pZoneInfo->isPayPlay() || pZoneInfo->isPremiumZone()) && (!pGamePlayer->isPayPlaying() && !pGamePlayer->isFamilyFreePass() )) { //Statement* pStmt = NULL; string connectIP = pGamePlayer->getSocket()->getHost(); // 유료 서비스 사용이 가능한가? if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID())) { sendPayInfo(pGamePlayer); } else if (pZoneInfo->isPayPlay()) { // 유료 서비스 사용 불가인 경우 GCSystemMessage gcSystemMessage; if (g_pConfig->getPropertyInt("IsNetMarble")==0) { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER )); } else { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER )); } pGamePlayer->sendPacket (&gcSystemMessage); return; } } #endif*/ if (!g_pVariableManager->isActiveRaceWarLimiter() || pCreature->isFlag(Effect::EFFECT_CLASS_RACE_WAR_JOIN_TICKET)) { pPC->getGQuestManager()->illegalWarp(); transportCreature(pCreature, pos.id, pos.x, pos.y, false); return; } else { GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_DURING_RACE_WAR)); pGamePlayer->sendPacket(&gcSystemMessage); return; } } if (!pCreature->isSlayer() && !pCreature->isOusters()) { // 뭔가를 해야하지 않을까? return; } if (pCreature->isFlag(Effect::EFFECT_CLASS_HAS_FLAG)) { // 뭔가를 해야하지 않을까? return; } if (pCreature->isFlag(Effect::EFFECT_CLASS_HAS_SWEEPER)) { // 뭔가를 해야하지 않을까? return; } //Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature); //Assert(pSlayer != NULL); bool bCancel = false; // 이펙트가 걸려있어야 정상적인 이동이다. if (pCreature->isOusters() || (pCreature->isSlayer() && pCreature->isFlag(Effect::EFFECT_CLASS_SLAYER_PORTAL))) { ZoneID_t id = pPacket->getZoneID(); ZoneCoord_t x = pPacket->getX(); ZoneCoord_t y = pPacket->getY(); if (id == 0 && x == 0 && y == 0) { bCancel = true; } else { // 석화 상태일 경우 생깐다. if (pCreature->isFlag(Effect::EFFECT_CLASS_PARALYZE)) { bCancel = true; } // 웨이포인트 매니저를 통해서 클라이언트가 보내온 // 웨이포인트가 정상적인 웨이포인트인지를 검증한다. if (!g_pWayPointManager->isValidWayPoint(id, x, y, pCreature->getRace())) { // 뭔가를 해야하지 않을까? bCancel = true; //return; } try { if (!bCancel) { #if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__) ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(id); // 유료존인데 유료사용자가 아니면... if (pZoneInfo==NULL || ((pZoneInfo->isPayPlay() || pZoneInfo->isPremiumZone()) && (!pGamePlayer->isPayPlaying() && !pGamePlayer->isFamilyFreePass()))) { //Statement* pStmt = NULL; string connectIP = pGamePlayer->getSocket()->getHost(); // 유료 서비스 사용이 가능한가? if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID())) { sendPayInfo(pGamePlayer); } else if (pZoneInfo->isPayPlay()) { // 유료 서비스 사용 불가인 경우 GCSystemMessage gcSystemMessage; if (g_pConfig->getPropertyInt("IsNetMarble") == 0) { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER)); } else { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER)); } pGamePlayer->sendPacket (&gcSystemMessage); bCancel = true; } } #endif if (!bCancel) { // 이동시키기 전에 이펙트를 삭제한다. if (pCreature->isSlayer()) pCreature->removeFlag(Effect::EFFECT_CLASS_SLAYER_PORTAL); if (pCreature->isOusters()) { Ousters* pOusters = dynamic_cast<Ousters*>(pCreature); Assert(pOusters != NULL); GCNoticeEvent gcNoticeEvent; // 대지정령의 뿔을 사용할라면 시오람과 계약을 맺었어야 한다. if (!pOusters->getFlagSet()->isOn(FLAGSET_GNOMES_HORN)) { gcNoticeEvent.setCode(NOTICE_EVENT_CONTRACT_GNOMES_HORN); pPlayer->sendPacket(&gcNoticeEvent); return; } Level_t level = pOusters->getLevel(); Price_t price = sPriceMap[level]; if (price == 0) { price = (Price_t)(pow((double)level, 1.3) * 100) / 2; sPriceMap[level] = price; } /*if (g_pFlagManager->hasFlagWar() && pPacket->getZoneID() == 32 && pPacket->getX() == 124 && pPacket->getY() == 144 ) price = 0;*/ if (pOusters->getGold() < price) { gcNoticeEvent.setCode(NOTICE_EVENT_NOT_ENOUGH_MONEY); pPlayer->sendPacket(&gcNoticeEvent); return; } else { pOusters->decreaseGoldEx(price); GCModifyInformation gcMI; gcMI.addLongData(MODIFY_GOLD, pOusters->getGold()); pPlayer->sendPacket(&gcMI); } } // 올바른 웨이포인트라면 슬레이어를 이동시켜준다. pPC->getGQuestManager()->illegalWarp(); transportCreature(pCreature, id, x, y, false); } } } catch (NoSuchElementException&) { bCancel = true; } } } if (bCancel && pCreature->isSlayer()) { Zone* pZone = pCreature->getZone(); Assert(pZone != NULL); // id, x, y가 모두 0일 경우 이동을 취소한다는 뜻이다. pCreature->removeFlag(Effect::EFFECT_CLASS_SLAYER_PORTAL); // 헬기를 제거하라고 뿌려준다. GCAddHelicopter gcAddHelicopter; gcAddHelicopter.setObjectID(pCreature->getObjectID()); gcAddHelicopter.setCode(1); pZone->broadcastPacket(pCreature->getX(), pCreature->getY(), &gcAddHelicopter); } } catch (Throwable & t) { cerr << t.toString() << endl; } #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 CGDisplayItemHandler::execute (CGDisplayItem* pPacket , Player* pPlayer) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ //#ifndef __TEST_SERVER__ // return; //#endif Assert(pPacket != NULL); Assert(pPlayer != NULL); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pGamePlayer->getCreature()); Assert(pPC != NULL); Inventory* pInventory = pPC->getInventory(); Assert(pInventory != NULL); Store* pStore = pPC->getStore(); Assert(pStore != NULL); GCSystemMessage errorMsg; GCNoticeEvent errorNotice; if (pPacket->getIndex() > MAX_ITEM_NUM ) { filelog("Store.log", "[%s:%s] (%u) 잘못된 인덱스입니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str(), pPacket->getIndex()); return; } if (pPacket->getX() >= pInventory->getWidth() || pPacket->getY() >= pInventory->getHeight() ) { filelog("Store.log", "[%s:%s] (%u,%u) 인벤토리 좌표를 잘못 보내줬습니다..", pGamePlayer->getID().c_str(), pPC->getName().c_str(), pPacket->getX(), pPacket->getY()); return; } Item* pItem = pInventory->getItem(pPacket->getX(), pPacket->getY()); if (pItem == NULL || pItem->getObjectID() != pPacket->getItemObjectID() ) { filelog("Store.log", "[%s:%s] (%u, %u) : %u 아이템 좌표가 잘못되었거나 오브젝트 아이디가 잘못되었습니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str(), pPacket->getX(), pPacket->getY(), pPacket->getItemObjectID()); return; } if (pPC->getZone()->getTradeManager()->getTradeInfo(pPC->getName() ) != NULL ) { filelog("Store.log", "[%s:%s] : 거래중에는 물건을 올려놓을 수 없습니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str()); return; } if (pStore->hasItem(pItem ) ) { filelog("Store.log", "[%s:%s] (%u, %u) 이미 아이템이 상점에 있습니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str(), pItem->getObjectID(), pPacket->getIndex()); // errorMsg.setMessage("이미 진열된 아이템입니다."); errorNotice.setCode(NOTICE_EVENT_ALREADY_DISPLAYED); pGamePlayer->sendPacket(&errorNotice); return; } if (pItem->isTimeLimitItem() || !canSell(pItem ) || !canTrade(pItem ) || !canTradeInventoryItem(pItem ) ) { filelog("Store.log", "[%s:%s] (%s) 팔 수 없는 아이템입니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str(), pItem->toString().c_str()); // errorMsg.setMessage("판매할 수 없는 아이템입니다."); errorNotice.setCode(NOTICE_EVENT_CANNOT_SELL); pGamePlayer->sendPacket(&errorNotice); return; } BYTE result = pStore->setStoreItem(pPacket->getIndex(), pItem, pPacket->getPrice()); if ( result != 0 ) { filelog("Store.log", "[%s:%s] (%u) 아이템을 놓을 수 없습니다.", pGamePlayer->getID().c_str(), pPC->getName().c_str(), result); return; } GCMyStoreInfo gcInfo; gcInfo.setStoreInfo(&(pStore->getStoreInfo())); pGamePlayer->sendPacket(&gcInfo); if (pStore->isOpen() ) { GCAddStoreItem gcAdd; gcAdd.setOwnerObjectID(pPC->getObjectID()); gcAdd.setIndex(pPacket->getIndex()); pStore->getStoreItem(pPacket->getIndex() ).makeStoreItemInfo(gcAdd.getItem()); pPC->getZone()->broadcastPacket(pPC->getX(), pPC->getY(), &gcAdd, pPC); } #endif // __GAME_SERVER__ __END_DEBUG_EX __END_CATCH }
void CGLotterySelectHandler::execute (CGLotterySelect* pPacket , Player* pPlayer) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ GamePlayer* pGP = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGP != NULL); Creature* pCreature = pGP->getCreature(); Assert(pCreature != NULL); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPC != NULL); filelog("EventQuest.log", "CGLotterySelectHandler : got [%d:%d:%d] from %s", pPacket->getType(), pPacket->getGiftID(), pPacket->getQuestLevel(), pPC->getName().c_str()); switch (pPacket->getType() ) { case TYPE_SELECT_LOTTERY: { // 인벤에서 퀘스트 아이템 삭제 QuestID_t qID; EventQuestAdvance::Status status = pPC->getQuestManager()->getEventQuestAdvanceManager()->getStatus(pPacket->getQuestLevel()); int ownerQuestLevel = pPC->getQuestManager()->getEventQuestAdvanceManager()->getQuestLevel(); if ( (ownerQuestLevel > pPacket->getQuestLevel() && status == EventQuestAdvance::EVENT_QUEST_ADVANCED ) || (pPacket->getQuestLevel() == 4 && ownerQuestLevel== -1 ) || pPC->getQuestManager()->successEventQuest(pPacket->getQuestLevel(), qID ) ) { pPC->getQuestManager()->getEventQuestAdvanceManager()->rewarded(pPacket->getQuestLevel()); pPC->getQuestManager()->getEventQuestAdvanceManager()->save(); pPC->getQuestManager()->questRewarded(qID); pPC->sendCurrentQuestInfo(); list<Item*> iList; pPC->getInventory()->clearQuestItem(iList); list<Item*>::iterator itr = iList.begin(); list<Item*>::iterator endItr = iList.end(); for (; itr != endItr ; ++itr ) { GCDeleteInventoryItem gcDII; gcDII.setObjectID((*itr)->getObjectID()); pPC->getPlayer()->sendPacket(&gcDII); (*itr)->destroy(); SAFE_DELETE(*itr); } iList.clear(); } else { filelog("EventBug.txt", "CGLotterySelectHandler : 복권 선택이 날라왔는데 완료한 퀘스트가 없다. -_-; %s[%d:%d]", pPC->getName().c_str(), pPacket->getQuestLevel(), pPacket->getGiftID()); return; } GCNoticeEvent gcNE; gcNE.setCode(NOTICE_EVENT_RESULT_LOTTERY); if (bWinPrize(pPacket->getGiftID(), pPacket->getQuestLevel() ) ) { // PlayerCreature 에 정보를 저장한다 pPC->setLotto(true); pPC->setLottoRewardID(pPacket->getGiftID()); pPC->setLottoQuestLevel(pPacket->getQuestLevel()); gcNE.setParameter((uint)1); } else { // PlayerCreature 에 정보를 저장한다 pPC->setLotto(false); pPC->setLottoRewardID(pPacket->getGiftID()); pPC->setLottoQuestLevel(pPacket->getQuestLevel()); gcNE.setParameter((uint)0); } pGP->sendPacket(&gcNE); filelog("EventQuest.log", "CGLotterySelectHandler : %d to %s", gcNE.getParameter(), pPC->getName().c_str()); } break; case TYPE_FINISH_SCRATCH: { // 당첨된 경우 디비에 저장 if (pPC->isLotto() ) { // 다시 false 로 만들어줘야함. // 아님 담번 퀘스트에서 무조건 당첨으로 처리되니 ;; pPC->setLotto(false); Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("INSERT INTO EventQuestRewardRecord (PlayerID, RewardID, Time, RealPlayerID) VALUES ('%s', %d, now(), '%s' )", pCreature->getName().c_str(), pPC->getLottoRewardID(), pPC->getPlayer()->getID().c_str()); SAFE_DELETE(pStmt); } END_DB(pStmt) // 이쪽 서버에 브로드 캐스트 하고 (allworld 는 해당 서버는 처리 안함) GCNotifyWin gcNW; gcNW.setGiftID(pPC->getLottoRewardID()); gcNW.setName(pCreature->getName()); g_pZoneGroupManager->broadcast(&gcNW); // 전 월드에 브로드캐스트해준다 char sCommand[200]; string worldName = g_pGameWorldInfoManager->getGameWorldInfo(g_pConfig->getPropertyInt("WorldID" ))->getName(); sprintf(sCommand, "*allworld *command NotifyWin %s(%s) %lu", pCreature->getName().c_str(), worldName.c_str(), pPC->getLottoRewardID()); CGSayHandler::opworld(NULL, sCommand, 0, false); } else { // 아니면 그냥 퀘스트 아이템만 인벤에 넣어주면 되는듯 Item::ItemClass iClass; ItemType_t iType; list<OptionType_t> oList; bool isTimeLimit = false; bool isLairItem = false; bool isUnique = false; MonsterType_t masterType; switch(pPC->getLottoQuestLevel() ) // switch(pPC->getQuestManager()->getEventQuestAdvanceManager()->getQuestLevel() ) { case 0: { static const string options1[] = { "STR+2", "DEX+2", "INT+2", "ASPD+2", "HP+2" }; static const string options2[] = { "STR+3", "DEX+3", "INT+3", "ASPD+3", "HP+3" }; if (pPC->isSlayer() ) { Slayer* pSlayer = dynamic_cast<Slayer*>(pPC); QuestGrade_t qGrade = pSlayer->getTotalAttr(ATTR_BASIC); iClass = Item::ITEM_CLASS_RING; if (qGrade < 131 ) { iType = 1; makeOptionList(options1[ rand()%5 ], oList); } else if (qGrade < 211 ) { iType = 2; makeOptionList(options1[ rand()%5 ], oList); } else if (qGrade < 271 ) { iType = 3; makeOptionList(options2[ rand()%5 ], oList); } else if (qGrade < 300 ) { iType = 4; makeOptionList(options2[ rand()%5 ], oList); } else { iType = 5; makeOptionList(options2[ rand()%5 ], oList); } } else if (pPC->isVampire() ) { Vampire* pVampire = dynamic_cast<Vampire*>(pPC); Level_t level = pVampire->getLevel(); iClass = Item::ITEM_CLASS_VAMPIRE_RING; if (level < 31 ) { iType = 1; makeOptionList(options1[ rand()%5 ], oList); } else if (level < 51 ) { iType = 2; makeOptionList(options1[ rand()%5 ], oList); } else if (level < 71 ) { iType = 3; makeOptionList(options2[ rand()%5 ], oList); } else if (level < 91 ) { iType = 4; makeOptionList(options2[ rand()%5 ], oList); } else { iType = 5; makeOptionList(options2[ rand()%5 ], oList); } } else if (pPC->isOusters() ) { Ousters* pOusters = dynamic_cast<Ousters*>(pPC); Level_t level = pOusters->getLevel(); iClass = Item::ITEM_CLASS_OUSTERS_RING; if (level < 31 ) { iType = 1; makeOptionList(options1[ rand()%5 ], oList); } else if (level < 51 ) { iType = 2; makeOptionList(options1[ rand()%5 ], oList); } else if (level < 71 ) { iType = 3; makeOptionList(options2[ rand()%5 ], oList); } else if (level < 91 ) { iType = 4; makeOptionList(options2[ rand()%5 ], oList); } else { iType = 5; makeOptionList(options2[ rand()%5 ], oList); } } } break; case 1: { static const string oSlayer1[] = { "DAM+2", "VIS+3", "MP+2", "LUCK+1", "HP+2" }; static const string oSlayer2[] = { "DAM+3", "VIS+3", "MP+3", "LUCK+2", "HP+3" }; static const string oVampire1[] = { "DAM+2", "VIS+3", "ASPD+2", "LUCK+1", "HP+2" }; static const string oVampire2[] = { "DAM+3", "VIS+3", "ASPD+3", "LUCK+2", "HP+3" }; if (pPC->isSlayer() ) { Slayer* pSlayer = dynamic_cast<Slayer*>(pPC); QuestGrade_t qGrade = pSlayer->getTotalAttr(ATTR_BASIC); iClass = Item::ITEM_CLASS_RING; if (qGrade < 131 ) { iType = 2; makeOptionList(oSlayer1[ rand()%5 ], oList); } else if (qGrade < 211 ) { iType = 3; makeOptionList(oSlayer1[ rand()%5 ], oList); } else if (qGrade < 271 ) { iType = 4; makeOptionList(oSlayer2[ rand()%5 ], oList); } else if (qGrade < 300 ) { iType = 5; makeOptionList(oSlayer2[ rand()%5 ], oList); } else { iType = 6; makeOptionList(oSlayer2[ rand()%5 ], oList); } } else if (pPC->isVampire() ) { Vampire* pVampire = dynamic_cast<Vampire*>(pPC); Level_t level = pVampire->getLevel(); iClass = Item::ITEM_CLASS_VAMPIRE_RING; if (level < 31 ) { iType = 2; makeOptionList(oVampire1[ rand()%5 ], oList); } else if (level < 51 ) { iType = 3; makeOptionList(oVampire1[ rand()%5 ], oList); } else if (level < 71 ) { iType = 4; makeOptionList(oVampire2[ rand()%5 ], oList); } else if (level < 91 ) { iType = 5; makeOptionList(oVampire2[ rand()%5 ], oList); } else { iType = 6; makeOptionList(oVampire2[ rand()%5 ], oList); } } else if (pPC->isOusters() ) { Ousters* pOusters = dynamic_cast<Ousters*>(pPC); Level_t level = pOusters->getLevel(); iClass = Item::ITEM_CLASS_OUSTERS_RING; if (level < 31 ) { iType = 2; makeOptionList(oVampire1[ rand()%5 ], oList); } else if (level < 51 ) { iType = 3; makeOptionList(oVampire1[ rand()%5 ], oList); } else if (level < 71 ) { iType = 4; makeOptionList(oVampire2[ rand()%5 ], oList); } else if (level < 91 ) { iType = 5; makeOptionList(oVampire2[ rand()%5 ], oList); } else { iType = 6; makeOptionList(oVampire2[ rand()%5 ], oList); } } } break; case 2: { isLairItem = true; masterType = 432; } break; case 3: { isLairItem = true; masterType = 433; } break; case 4: { isTimeLimit = true; if (pPC->isSlayer() ) { isUnique = true; static const Item::ItemClass iClasses[] = { Item::ITEM_CLASS_COAT, Item::ITEM_CLASS_TROUSER, Item::ITEM_CLASS_GLOVE, Item::ITEM_CLASS_HELM, Item::ITEM_CLASS_SHOES, // Item::ITEM_CLASS_BELT, Item::ITEM_CLASS_NECKLACE, Item::ITEM_CLASS_BRACELET }; static const ItemType_t iTypes[] = { 16, 16, 8, 9, 7, // 4, 10, 10 }; int index = rand() % 7; iClass = iClasses[index]; iType = iTypes[index]; } else if (pPC->isVampire() ) { isUnique = true; static const Item::ItemClass iClasses[] = { Item::ITEM_CLASS_VAMPIRE_COAT, Item::ITEM_CLASS_VAMPIRE_WEAPON, Item::ITEM_CLASS_VAMPIRE_RING, Item::ITEM_CLASS_VAMPIRE_NECKLACE, Item::ITEM_CLASS_VAMPIRE_BRACELET, Item::ITEM_CLASS_VAMPIRE_AMULET, Item::ITEM_CLASS_VAMPIRE_EARRING }; static const ItemType_t iTypes[] = { 12, 15, 10, 10, 9, 10, 10 }; int index = rand() % 7; iClass = iClasses[index]; iType = iTypes[index]; } else if (pPC->isOusters() ) { static const Item::ItemClass iClasses[] = { Item::ITEM_CLASS_OUSTERS_COAT, Item::ITEM_CLASS_OUSTERS_CIRCLET, Item::ITEM_CLASS_OUSTERS_ARMSBAND, Item::ITEM_CLASS_OUSTERS_BOOTS, Item::ITEM_CLASS_OUSTERS_PENDENT, Item::ITEM_CLASS_OUSTERS_RING }; static const ItemType_t iTypes[] = { 7, 9, 9, 7, 9, 9 }; static const string options[] = { "DAM+3", "ASPD+3", "LUCK+2", "HP+9", "STR+3", "DEX+3", "INT+3", "ATTR+2", "RES+3", "MP+4" }; int index = rand() % 6; iClass = iClasses[index]; iType = iTypes[index]; int option1 = rand()%10; int option2 = rand()%10; while (option1 == option2 ) option2 = rand()%10; makeOptionList(options[ option1 ] + "," + options[ option2 ], oList); } } break; default: break; } Item* pItem; if (isLairItem ) { const MonsterInfo* pMonsterInfo = g_pMonsterInfoManager->getMonsterInfo(masterType); TreasureList *pTreasureList = NULL; if (pPC->isSlayer()) pTreasureList = pMonsterInfo->getSlayerTreasureList(); else if (pPC->isVampire() ) pTreasureList = pMonsterInfo->getVampireTreasureList(); else if (pPC->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; it.NextOptionRatio = 0; //cout << "TradeLairItem: BonusRatio = " << it.NextOptionRatio << endl; if (pTreasure->getRandomItem(&it) ) { pItem = g_pItemFactoryManager->createItem(it.ItemClass, it.ItemType, it.OptionType); Assert(pItem != NULL); } } } else { pItem = g_pItemFactoryManager->createItem(iClass, iType, oList); } GenderRestriction gender = GENDER_BOTH; switch(pPC->getSex() ) { case MALE: gender = GENDER_MALE; break; case FEMALE: gender = GENDER_FEMALE; break; default: break; } setItemGender(pItem, gender); _TPOINT tp; if (pItem != NULL && pPC->getInventory()->addItem(pItem, tp ) ) { pPC->getZone()->registerObject(pItem); pItem->create(pPC->getName(), STORAGE_INVENTORY, 0, tp.x, tp.y); if (isTimeLimit ) { pPC->addTimeLimitItem(pItem, 604800); pPC->sendTimeLimitItemInfo(); } GCCreateItem gcCreateItem; makeGCCreateItem(&gcCreateItem, pItem, tp.x, tp.y); pPC->getPlayer()->sendPacket(&gcCreateItem); remainTraceLog(pItem, "GOD", pCreature->getName(), ITEM_LOG_CREATE, DETAIL_EVENTNPC); } else { if (isUnique ) pItem->setUnique(); if (isTimeLimit ) pItem->setTimeLimitItem(); pPC->setQuestItem(pItem); remainTraceLog(pItem, "GOD", pCreature->getName(), ITEM_LOG_CREATE, DETAIL_EVENTNPC); } } if (pPC->getLottoQuestLevel() == 4 ) { pPC->getQuestManager()->cancelQuest(); GCNoticeEvent gcNE; gcNE.setCode(NOTICE_EVENT_START_QUEST_ENDING); pPC->getPlayer()->sendPacket(&gcNE); } }