GQuestElement::ResultType GQuestGiveQuestItemElement::checkCondition(PlayerCreature* pPC ) const { GQuestInventory& inventory = pPC->getGQuestManager()->getGQuestInventory(); inventory.getItems().push_back(m_ItemType); pPC->getPlayer()->sendPacket(inventory.getInventoryPacket()); GCSystemMessage gcSM; gcSM.setMessage("퀘스트 아이템을 획득했습니다."); pPC->getPlayer()->sendPacket(&gcSM); if (m_bSave ) { Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("INSERT INTO GQuestItemObject(ItemType, OwnerID) VALUES (%u, '%s')", m_ItemType, pPC->getName().c_str()); SAFE_DELETE(pStmt); } END_DB(pStmt) } return OK; }
//---------------------------------------------------------------------- // affect //---------------------------------------------------------------------- void EventKick::sendMessage() throw(Error) { __BEGIN_TRY Assert(m_pGamePlayer != NULL); Creature * pCreature = m_pGamePlayer->getCreature(); Timeval currentTime; getCurrentTime(currentTime); Turn_t RemainTime = max(0, (int)(m_Deadline.tv_sec-currentTime.tv_sec)); char msg[50]; sprintf(msg, g_pStringPool->c_str(STRID_DISCONNECT_COUNT_DOWN ), (int)RemainTime); string sMsg(msg); GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(sMsg); pCreature->getPlayer()->sendPacket(&gcSystemMessage); __END_CATCH }
//---------------------------------------------------------------------- // affect //---------------------------------------------------------------------- void EffectTransportCreature::affect(Creature* pCreature) throw(Error) { __BEGIN_TRY Timeval nextTime = getNextTime(); Timeval deadLine = getDeadline(); Turn_t RemainTime = deadLine.tv_sec - nextTime.tv_sec; // StringStream msg; // msg << (int)RemainTime << "초 후에 " << m_ZoneName << "로 이동됩니다."; char msg[50]; sprintf(msg, g_pStringPool->c_str(STRID_TRANSPORT_CREATURE ), (int)RemainTime, m_ZoneName.c_str()); string sMsg(msg); GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(sMsg); pCreature->getPlayer()->sendPacket(&gcSystemMessage); setNextTime(m_MessageTick); __END_CATCH }
void EffectVampireRelic::affect(Creature* pCreature) throw(Error) { __BEGIN_TRY //Timeval nextTime = getNextTime(); //Timeval deadLine = getDeadline(); //Turn_t RemainTime = deadLine.tv_sec - nextTime.tv_sec; /* StringStream msg; if (pCreature->isSlayer()) { Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature); msg << pSlayer->getName(); } else { Vampire* pVampire = dynamic_cast<Vampire*>(pCreature); msg << pVampire->getName(); } msg << " 님이 뱀파이어 성물을 가졌습니다."; */ char msg[50]; sprintf(msg, g_pStringPool->c_str(STRID_TAKE_VAMPIRE_RELIC ), pCreature->getName().c_str()); string sMsg(msg); GCSystemMessage gcSystemMessage; gcSystemMessage.setType(SYSTEM_MESSAGE_COMBAT); gcSystemMessage.setMessage(sMsg); g_pZoneGroupManager->broadcast(&gcSystemMessage); // Effect붙인다. GCAddEffect gcAddEffect; gcAddEffect.setObjectID(pCreature->getObjectID()); gcAddEffect.setEffectID(getSendEffectClass()); gcAddEffect.setDuration(65000); pCreature->getZone()->broadcastPacket(pCreature->getX(), pCreature->getY(), &gcAddEffect); setNextTime(m_Tick); __END_CATCH }
void CGRangerSayHandler::execute (CGRangerSay* pPacket , Player* pPlayer) throw(ProtocolException , Error) { __BEGIN_TRY #ifdef __GAME_SERVER__ Assert(pPacket != NULL); Assert(pPlayer != NULL); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); Creature* pCreature = pGamePlayer->getCreature(); Assert(pCreature != NULL); // 크리쳐 이름과 메시지를 패킷에 넣는다. StringStream msg; msg << pCreature->getName() << " " << pPacket->getMessage(); Race_t race = pCreature->getRace(); // 패킷 생성 GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(msg.toString()); gcSystemMessage.setType(SYSTEM_MESSAGE_RANGER_SAY); // 필터 생성 BroadcastFilterRace filter(race); // 모든 사용자에게 뿌리기 g_pZoneGroupManager->pushBroadcastPacket(&gcSystemMessage, &filter); /* map<ZoneGroupID_t, ZoneGroup*>::const_iterator itr = g_pZoneGroupManager->getZoneGroups().begin(); map<ZoneGroupID_t, ZoneGroup*>::const_iterator endItr = g_pZoneGroupManager->getZoneGroups().end(); for (; itr != endItr; ++itr ) { GCSystemMessage* pSystemMessage = new GCSystemMessage(); pSystemMessage->setMessage(msg.toString()); pSystemMessage->setType(SYSTEM_MESSAGE_RANGER_SAY); pSystemMessage->setRace(race); itr->second->getZonePlayerManager()->pushBroadcastPacket(pSystemMessage); } */ #endif __END_CATCH }
GQuestElement::ResultType GQuestGiveVampireExpElement::checkCondition(PlayerCreature* pPC ) const { if (!pPC->isVampire() ) return FAIL; GCModifyInformation gcMI; Vampire* pVampire = dynamic_cast<Vampire*>(pPC); increaseVampExp(pVampire, m_Amount, gcMI); pVampire->getPlayer()->sendPacket(&gcMI); GCSystemMessage gcSM; gcSM.setMessage("경험치를 획득했습니다."); pPC->getPlayer()->sendPacket(&gcSM); return OK; }
GQuestElement::ResultType GQuestGiveDomainExpElement::checkCondition(PlayerCreature* pPC ) const { if (!pPC->isSlayer() ) return FAIL; GCModifyInformation gcMI; Slayer* pSlayer = dynamic_cast<Slayer*>(pPC); increaseDomainExp(pSlayer, pSlayer->getHighestSkillDomain(), m_Amount, gcMI); pSlayer->getPlayer()->sendPacket(&gcMI); GCSystemMessage gcSM; gcSM.setMessage("도메인 경험치를 획득했습니다."); pSlayer->getPlayer()->sendPacket(&gcSM); return OK; }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionSetResurrectZone::execute (Creature * pCreature1 , Creature * pCreature2) throw(Error) { __BEGIN_TRY Assert(pCreature1 != NULL); Assert(pCreature2 != NULL); Assert(pCreature1->isNPC()); Assert(pCreature2->isPC()); // 일단 클라이언트를 위해서 OK 패킷을 함 날린다. GCNPCResponse okpkt; Player* pPlayer = pCreature2->getPlayer(); Assert(pPlayer != NULL); pPlayer->sendPacket(&okpkt); if (pCreature2->isSlayer()) { Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature2); pSlayer->setResurrectZoneIDEx(m_ZoneID); } else if (pCreature2->isVampire()) { Vampire* pVampire = dynamic_cast<Vampire*>(pCreature2); pVampire->setResurrectZoneIDEx(m_ZoneID); } else if (pCreature2->isOusters()) { Ousters* pOusters = dynamic_cast<Ousters*>(pCreature2); pOusters->setResurrectZoneIDEx(m_ZoneID); } GCSystemMessage msg; msg.setMessage(g_pStringPool->getString(STRID_SET_RESURRECTION_POSITION )); pPlayer->sendPacket(&msg); __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 CGModifyGuildMemberHandler::execute (CGModifyGuildMember* pPacket , Player* pPlayer) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ //cout << "CGModifyGuildMember received." << endl; Assert(pPacket != NULL); Assert(pPlayer != NULL); SYSTEM_ASSERT(SYSTEM_GUILD); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); Creature* pCreature = pGamePlayer->getCreature(); Assert(pCreature != NULL); PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPlayerCreature != NULL); // 길드를 가져온다. Guild* pGuild = g_pGuildManager->getGuild(pPlayerCreature->getGuildID()); //try { Assert(pGuild != NULL); } catch (Throwable& t ) { return; } if (pGuild==NULL) return; // 길드 멤버 정보를 가져온다. GuildMember* pGuildMember = pGuild->getMember(pPlayerCreature->getName()); //try { Assert(pGuild != NULL); } catch (Throwable& t ) { return; } if (pGuildMember==NULL) return; //cout << "get guild" << endl; if (pPacket->getGuildMemberRank() == GuildMember::GUILDMEMBER_RANK_DENY ) { //////////////////////////////////////////////////////// // 길드 멤버를 추방한다. //////////////////////////////////////////////////////// // 마스터가 아니면 추방할 수 없다. if (pGuildMember->getRank() != GuildMember::GUILDMEMBER_RANK_MASTER ) return; if (g_pGuildManager->hasActiveWar(pGuild->getID() ) ) { GCSystemMessage msg; msg.setMessage(g_pStringPool->getString(STRID_CANNOT_KICK_DURING_WAR )); pPlayer->sendPacket(&msg); return; } GSExpelGuildMember gsExpelGuildMember; gsExpelGuildMember.setGuildID(pGuild->getID()); gsExpelGuildMember.setName(pPacket->getName()); gsExpelGuildMember.setSender(pPlayerCreature->getName()); //cout << "send GSExpelGuildMember" << endl; g_pSharedServerManager->sendPacket(&gsExpelGuildMember); } else { if (pGuild->getActiveMemberCount() >= MAX_GUILDMEMBER_ACTIVE_COUNT ) { GCSystemMessage msg; msg.setMessage(g_pStringPool->getString(STRID_CANNOT_ACCEPT_MORE_JOIN )); pPlayer->sendPacket(&msg); return; } /////////////////////////////////////////////////////// // 길드 가입을 승인한다. /////////////////////////////////////////////////////// // 마스터나 서브마스터 이어야 한다. if (pGuildMember->getRank() != GuildMember::GUILDMEMBER_RANK_MASTER && pGuildMember->getRank() != GuildMember::GUILDMEMBER_RANK_SUBMASTER ) return; if (g_pGuildManager->hasActiveWar(pGuild->getID() ) ) { GCSystemMessage msg; msg.setMessage(g_pStringPool->getString(STRID_CANNOT_ACCEPT_DURING_WAR )); pPlayer->sendPacket(&msg); return; } GSModifyGuildMember gsModifyGuildMember; gsModifyGuildMember.setGuildID(pGuild->getID()); gsModifyGuildMember.setName(pPacket->getName()); gsModifyGuildMember.setGuildMemberRank(pPacket->getGuildMemberRank()); gsModifyGuildMember.setSender(pPlayerCreature->getName()); //cout << "send GSModifyGuildMember" << endl; g_pSharedServerManager->sendPacket(&gsModifyGuildMember); } #endif // __GAME_SERVER__ __END_DEBUG_EX __END_CATCH }
void CGQuitUnionAcceptHandler::execute (CGQuitUnionAccept* pPacket , Player* pPlayer) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ Assert(pPacket != NULL); Assert(pPlayer != NULL); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pGamePlayer->getCreature()); Assert(pPlayerCreature != NULL); #ifdef __OLD_GUILD_WAR__ GCSystemMessage gcSM; gcSM.setMessage("아직 지원되지 않는 기능입니다."); pGamePlayer->sendPacket(&gcSM); return; #endif SYSTEM_ASSERT(SYSTEM_GUILD); GCGuildResponse gcGuildResponse; GuildUnion *pUnion = GuildUnionManager::Instance().getGuildUnion(pPlayerCreature->getGuildID()); if(pUnion == NULL) { gcGuildResponse.setCode(GuildUnionOfferManager::NOT_IN_UNION); pPlayer->sendPacket(&gcGuildResponse); return; } // 요청한놈이 지가 속한 길드의 마스터인가? || 연합의 마스터길드가 내 길드가 맞나? if(!g_pGuildManager->isGuildMaster (pPlayerCreature->getGuildID(), pPlayerCreature ) || pUnion->getMasterGuildID() != pPlayerCreature->getGuildID() ) { // GC_GUILD_RESPONSE 날려준다. // 내용 : 길드 마스터가 아니자녀 -.-+ gcGuildResponse.setCode(GuildUnionOfferManager::SOURCE_IS_NOT_MASTER); pPlayer->sendPacket(&gcGuildResponse); return; } uint result = GuildUnionOfferManager::Instance().acceptQuit(pPacket->getGuildID()); gcGuildResponse.setCode(result); pPlayer->sendPacket(&gcGuildResponse); //////////////////// if(result == GuildUnionOfferManager::OK) { Guild* pGuild = g_pGuildManager->getGuild(pPacket->getGuildID()); if(pGuild == NULL) { return; } string TargetGuildMaster = pGuild->getMaster(); //cout << "연합탈퇴가 수락되었다. 통보받을 유저는 : " << TargetGuildMaster.c_str() << endl; Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN" )->createStatement(); pStmt->executeQuery("INSERT INTO Messages (Receiver, Message) values('%s','%s')", TargetGuildMaster.c_str(), g_pStringPool->c_str(375 )); // 탈퇴수락한뒤에 나 혼자 남아있다면? Result *pResult = pStmt->executeQuery("SELECT count(*) FROM GuildUnionMember WHERE UnionID='%u'", pUnion->getUnionID()); pResult->next(); if(pResult->getInt(1) == 0) { //cout << "연합탈퇴가 수락된후..남아있는 멤버가 없으면..연합장이면 안되니까..지워버린다" << endl; pStmt->executeQuery("DELETE FROM GuildUnionInfo WHERE UnionID='%u'", pUnion->getUnionID()); GuildUnionManager::Instance().reload(); } SAFE_DELETE(pStmt); } END_DB(pStmt) // 연합탈퇴하면 연합정보가 바뀌었을 수도 있다. 갱신된 정보를 다시 보내준다. Creature *pCreature = NULL; pCreature = pGamePlayer->getCreature(); if(pCreature == NULL) return; GCModifyInformation gcModifyInformation; makeGCModifyInfoGuildUnion(&gcModifyInformation, pCreature); pPlayer->sendPacket(&gcModifyInformation); // 통보받을 유저에게 길드Union정보를 다시 보낸다 Creature *pTargetCreature = NULL; __ENTER_CRITICAL_SECTION((*g_pPCFinder)) pTargetCreature = g_pPCFinder->getCreature_LOCKED(TargetGuildMaster); if (pTargetCreature==NULL) { g_pPCFinder->unlock(); return; } GCModifyInformation gcModifyInformation; makeGCModifyInfoGuildUnion(&gcModifyInformation, pTargetCreature); pTargetCreature->getPlayer()->sendPacket(&gcModifyInformation); __LEAVE_CRITICAL_SECTION((*g_pPCFinder)) sendGCOtherModifyInfoGuildUnion(pTargetCreature); sendGCOtherModifyInfoGuildUnion(pCreature); // 다른 서버에 있는 놈들에게 변경사항을 알린다. GuildUnionManager::Instance().sendModifyUnionInfo(dynamic_cast<PlayerCreature*>(pTargetCreature)->getGuildID()); GuildUnionManager::Instance().sendModifyUnionInfo(dynamic_cast<PlayerCreature*>(pCreature)->getGuildID()); }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionEnterQuestZone::execute (Creature * pNPC , Creature * pCreature) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG Assert(pCreature != NULL); Assert(pCreature->isPC()); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pCreature->getPlayer()); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPC != NULL); bool bTransport = true; #if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__) try { ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(m_ZoneID); // 유료존인데 유료사용자가 아니면... if (pZoneInfo==NULL || pZoneInfo->isPayPlay() && !(pGamePlayer->isPayPlaying() || pGamePlayer->isFamilyFreePass())) { string connectIP = pGamePlayer->getSocket()->getHost(); // 유료 서비스 사용이 가능한가? if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID())) { sendPayInfo(pGamePlayer); } else { // 유료 서비스 사용 불가인 경우 GCSystemMessage gcSystemMessage; if (g_pConfig->getPropertyInt("IsNetMarble")==0) { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_PAY_ZONE )); } else { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER )); } pGamePlayer->sendPacket (&gcSystemMessage); bTransport = false; } } } catch (NoSuchElementException&) { } #endif if (bTransport) { // Dynamic 존인지 확인. int targetDynamicZoneType = g_pDynamicZoneInfoManager->getDynamicZoneTypeByZoneID(m_ZoneID); if (targetDynamicZoneType != DYNAMIC_ZONE_MAX ) { // Dynamic 존일 경우 DynamicZoneGroup* pDynamicZoneGroup = g_pDynamicZoneManager->getDynamicZoneGroup(targetDynamicZoneType); Assert(pDynamicZoneGroup != NULL); DynamicZone* pDynamicZone = pDynamicZoneGroup->getAvailableDynamicZone(); Assert(pDynamicZone != NULL); transportCreature(pCreature, pDynamicZone->getZoneID(), m_X, m_Y, true); if (targetDynamicZoneType == DYNAMIC_ZONE_ALTER_OF_BLOOD ) { DynamicZoneAlterOfBlood* pAlterOfBlood = dynamic_cast<DynamicZoneAlterOfBlood*>(pDynamicZone); Assert(pAlterOfBlood != NULL); pAlterOfBlood->setRace(pPC->getRace()); } } else { // Dynamic 존이 아닐 경우 transportCreature(pCreature, m_ZoneID, m_X, m_Y, true); } } else { GCNPCResponse response; response.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pGamePlayer->sendPacket(&response); } __END_DEBUG __END_CATCH }
//---------------------------------------------------------------------- // // SGAddGuildMemberOKHandler::execute() // //---------------------------------------------------------------------- void SGAddGuildMemberOKHandler::execute (SGAddGuildMemberOK* pPacket ) throw(ProtocolException , Error ) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ // 길드 멤버 object 를 만든다. GuildMember* pGuildMember = new GuildMember(); pGuildMember->setGuildID(pPacket->getGuildID()); pGuildMember->setName(pPacket->getName()); pGuildMember->setRank(pPacket->getGuildMemberRank()); // 길드에 추가한다. Guild* pGuild = g_pGuildManager->getGuild(pGuildMember->getGuildID()); pGuild->addMember(pGuildMember); // 멤버에게 메세지를 보낸다. __ENTER_CRITICAL_SECTION((*g_pPCFinder)) Creature* pCreature = g_pPCFinder->getCreature_LOCKED(pGuildMember->getName()); if (pCreature != NULL && pCreature->isPC() ) { Player* pPlayer = pCreature->getPlayer(); Assert(pPlayer != NULL); if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_MASTER || pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_SUBMASTER ) // 길드마스터나 서브마스터일 경우 { PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPlayerCreature != NULL); Gold_t Fee; if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_MASTER ) Fee = REQUIRE_SLAYER_MASTER_GOLD; else if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_SUBMASTER ) Fee = REQUIRE_SLAYER_SUBMASTER_GOLD; else Fee = 0; Gold_t CurMoney = pPlayerCreature->getGold(); if (CurMoney < Fee ) { // 큰일났군 CurMoney = 0; } else CurMoney -= Fee; pPlayerCreature->setGoldEx(CurMoney); if (Fee != 0 ) { GCModifyInformation gcModifyInformation; gcModifyInformation.addLongData(MODIFY_GOLD, CurMoney); // 바뀐정보를 클라이언트에 보내준다. pPlayer->sendPacket(&gcModifyInformation); } // 길드 가입 메시지를 보여준다. GCSystemMessage gcSystemMessage; if (pGuild->getRace() == Guild::GUILD_RACE_SLAYER ) gcSystemMessage.setMessage(g_pStringPool->getString(STRID_TEAM_JOIN_ACCEPTED )); else if (pGuild->getRace() == Guild::GUILD_RACE_VAMPIRE ) gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CLAN_JOIN_ACCEPTED )); else if (pGuild->getRace() == Guild::GUILD_RACE_OUSTERS ) gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CLAN_JOIN_ACCEPTED )); pPlayer->sendPacket(&gcSystemMessage); } else if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_WAIT ) { // 길드 가입 신청 메시지를 보낸다. GCSystemMessage gcSystemMessage; if (pGuild->getRace() == Guild::GUILD_RACE_SLAYER ) gcSystemMessage.setMessage(g_pStringPool->getString(STRID_TEAM_JOIN_TRY )); else if (pGuild->getRace() == Guild::GUILD_RACE_VAMPIRE ) gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CLAN_JOIN_TRY )); else if (pGuild->getRace() == Guild::GUILD_RACE_OUSTERS ) gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CLAN_JOIN_TRY )); pPlayer->sendPacket(&gcSystemMessage); } } else { // 접속이 안되어 있다. // 마스터나 서브마스터일 경우 // DB 에서 돈을 까도록 한다. if ((pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_MASTER || pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_SUBMASTER ) // 길드마스터나 서브마스터일 경우 && pPacket->getServerGroupID() == g_pConfig->getPropertyInt("ServerID" ) ) // 이 게임 서버에서 추가한 길드원인가? { Gold_t Fee; if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_MASTER ) Fee = REQUIRE_SLAYER_MASTER_GOLD; else if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_SUBMASTER ) Fee = REQUIRE_SLAYER_SUBMASTER_GOLD; else Fee = 0; string table = ""; if (pGuild->getRace() == Guild::GUILD_RACE_SLAYER ) { table = "Slayer"; } else if (pGuild->getRace() == Guild::GUILD_RACE_VAMPIRE ) { table = "Vampire"; } else if (pGuild->getRace() == Guild::GUILD_RACE_OUSTERS ) { table = "Ousters"; } if (table != "" && Fee != 0 ) { Statement* pStmt = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN")->createStatement(); pStmt->executeQuery("UPDATE %s SET Gold = IF (%u > Gold , 0, Gold - %u ) WHERE Name = '%s'", table.c_str(), Fee, Fee, pGuildMember->getName().c_str()); } END_DB(pStmt) } }
//---------------------------------------------------------------------- // // SGModifyGuildOKHandler::execute() // //---------------------------------------------------------------------- void SGModifyGuildOKHandler::execute (SGModifyGuildOK* pPacket ) throw(ProtocolException , Error ) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ Guild* pGuild = g_pGuildManager->getGuild(pPacket->getGuildID()); Assert(pGuild != NULL); if (pGuild->getState() == Guild::GUILD_STATE_WAIT && pPacket->getGuildState() == Guild::GUILD_STATE_ACTIVE ) { ///////////////////////////////////////////////////////////// // 존 추가 ///////////////////////////////////////////////////////////// /* if (pGuild->getServerGroupID() == g_pConfig->getPropertyInt("ServerID" ) ) { // 이 게임 서버에 길드 아지트를 만든다. ////////////// // Zone Info ////////////// ZoneInfo* pZoneInfo = new ZoneInfo(); pZoneInfo->setZoneID(pGuild->getZoneID()); pZoneInfo->setZoneGroupID(2); pZoneInfo->setZoneType("NPC_SHOP"); pZoneInfo->setZoneLevel(0); pZoneInfo->setZoneAccessMode("PUBLIC"); pZoneInfo->setZoneOwnerID(""); pZoneInfo->setPayPlay(""); if (pGuild->getRace() == Guild::GUILD_RACE_SLAYER ) { pZoneInfo->setSMPFilename("team_hdqrs.smp"); pZoneInfo->setSSIFilename("team_hdqrs.ssi"); string Name = "team - " + pGuild->getName(); pZoneInfo->setFullName(Name); pZoneInfo->setShortName(Name); } else if (pGuild->getRace() == Guild::GUILD_RACE_VAMPIRE ) { pZoneInfo->setSMPFilename("clan_hdqrs.smp"); pZoneInfo->setSSIFilename("clan_hdqrs.ssi"); string Name = "clan - " + pGuild->getName(); pZoneInfo->setFullName(Name); pZoneInfo->setShortName(Name); } g_pZoneInfoManager->addZoneInfo(pZoneInfo); ///////// // Zone ///////// Zone* pZone = new Zone(pGuild->getZoneID()); Assert(pZone != NULL); ZoneGroup* pZoneGroup = g_pZoneGroupManager->getZoneGroup(2); Assert(pZoneGroup != NULL); pZone->setZoneGroup(pZoneGroup); pZoneGroup->addZone(pZone); pZone->init(); } */ // 정식 길드로 변경 pGuild->setState(Guild::GUILD_STATE_ACTIVE); HashMapGuildMember& Members = pGuild->getMembers(); HashMapGuildMemberItor itr = Members.begin(); for (; itr != Members.end(); itr++ ) { GuildMember* pGuildMember = itr->second; // 멤버가 접속해 있다면 __ENTER_CRITICAL_SECTION((*g_pPCFinder)) Creature* pCreature = g_pPCFinder->getCreature_LOCKED(pGuildMember->getName()); if (pCreature != NULL && pCreature->isPC() ) { Player* pPlayer = pCreature->getPlayer(); Assert(pPlayer != NULL); PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPlayerCreature != NULL); // 길드 아이디를 바꿔준다. pPlayerCreature->setGuildID(pGuild->getID()); // 클라이언트에 길드 아이디가 바꼈음을 알려준다. GCModifyGuildMemberInfo gcModifyGuildMemberInfo; gcModifyGuildMemberInfo.setGuildID(pGuild->getID()); gcModifyGuildMemberInfo.setGuildName(pGuild->getName()); gcModifyGuildMemberInfo.setGuildMemberRank(pGuildMember->getRank()); pPlayer->sendPacket(&gcModifyGuildMemberInfo); // 주위에 알린다. Zone* pZone = pCreature->getZone(); Assert(pZone != NULL); GCOtherModifyInfo gcOtherModifyInfo; gcOtherModifyInfo.setObjectID(pCreature->getObjectID()); gcOtherModifyInfo.addShortData(MODIFY_GUILDID, pPlayerCreature->getGuildID()); pZone->broadcastPacket(pCreature->getX(), pCreature->getY(), &gcOtherModifyInfo, pCreature); // 정식 길드가 되었음을 알림 Statement* pStmt = NULL; Result* pResult = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN" )->createStatement(); pResult = pStmt->executeQuery("SELECT Message FROM Messages WHERE Receiver = '%s'", pGuildMember->getName().c_str()); while (pResult->next() ) { GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(pResult->getString(1)); pPlayer->sendPacket(&gcSystemMessage); } pStmt->executeQuery("DELETE FROM Messages WHERE Receiver = '%s'", pGuildMember->getName().c_str()); SAFE_DELETE(pStmt); } END_DB(pStmt) } __LEAVE_CRITICAL_SECTION((*g_pPCFinder)) }
//---------------------------------------------------------------------- // // SGDeleteGuildOKHandler::execute() // //---------------------------------------------------------------------- void SGDeleteGuildOKHandler::execute (SGDeleteGuildOK* pPacket ) throw(ProtocolException , Error ) { __BEGIN_TRY #ifdef __GAME_SERVER__ // 길드 아지트에 있는 멤버를 warp 시킨다. // 길드 아지트를 삭제한다. // 멤버 warp와 길드 아지트 삭제 시 다른 쓰레드에서 ZoneGroup Thread 내부에서 일어나게 해야 별탈이 없을 듯 하다. // 일단은 걍 둔다. Portal 이 막히므로 다시 들어갈 수 없을 것이다. Assert(pPacket != NULL); // 길드를 가져온다. Guild* pGuild = g_pGuildManager->getGuild(pPacket->getGuildID()); try { Assert(pGuild != NULL); } catch (Throwable& ) { return; } // 길드 활동 중인 상태에서의 해체인지 대기 중인 상태에서의 해체인지 구별한다. if (pGuild->getState() == Guild::GUILD_STATE_ACTIVE ) { HashMapGuildMember& Members = pGuild->getMembers(); HashMapGuildMemberItor itr = Members.begin(); for (; itr != Members.end(); itr++ ) { GuildMember* pGuildMember = itr->second; // 접속해 있으면 __ENTER_CRITICAL_SECTION((*g_pPCFinder)) Creature* pCreature = g_pPCFinder->getCreature_LOCKED(pGuildMember->getName()); if (pCreature != NULL && pCreature->isPC() ) { Player* pPlayer = pCreature->getPlayer(); Assert(pPlayer != NULL); PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPlayerCreature != NULL); // Slayer, Vampire 의 길드 아이디를 바꾼다. if (pPlayerCreature->isSlayer() ) { pPlayerCreature->setGuildID(99); // 슬레이어 가입안한 상태의 길드 ID // 클라이언트에 길드 아이디가 바꼈음을 알린다. GCModifyGuildMemberInfo gcModifyGuildMemberInfo; gcModifyGuildMemberInfo.setGuildID(pPlayerCreature->getGuildID()); gcModifyGuildMemberInfo.setGuildName(""); gcModifyGuildMemberInfo.setGuildMemberRank(GuildMember::GUILDMEMBER_RANK_DENY); pPlayer->sendPacket(&gcModifyGuildMemberInfo); } else if (pPlayerCreature->isVampire() ) { pPlayerCreature->setGuildID(0); // 뱀파이어 가입안한 상태의 길드 ID // 클라이언트에 길드 아이디가 바꼈음을 알린다. GCModifyGuildMemberInfo gcModifyGuildMemberInfo; gcModifyGuildMemberInfo.setGuildID(pPlayerCreature->getGuildID()); gcModifyGuildMemberInfo.setGuildName(""); gcModifyGuildMemberInfo.setGuildMemberRank(GuildMember::GUILDMEMBER_RANK_DENY); pPlayer->sendPacket(&gcModifyGuildMemberInfo); } else if (pPlayerCreature->isOusters() ) { pPlayerCreature->setGuildID(66); // 아우스터즈 가입안한 상태의 길드 ID // 클라이언트에 길드 아이디가 바꼈음을 알린다. GCModifyGuildMemberInfo gcModifyGuildMemberInfo; gcModifyGuildMemberInfo.setGuildID(pPlayerCreature->getGuildID()); gcModifyGuildMemberInfo.setGuildName(""); gcModifyGuildMemberInfo.setGuildMemberRank(GuildMember::GUILDMEMBER_RANK_DENY); pPlayer->sendPacket(&gcModifyGuildMemberInfo); } // 주위에 클라이언트에 길드 아이디가 바꼈음을 알린다. GCOtherModifyInfo gcOtherModifyInfo; gcOtherModifyInfo.setObjectID(pCreature->getObjectID()); gcOtherModifyInfo.addShortData(MODIFY_GUILDID, pPlayerCreature->getGuildID()); Zone* pZone = pCreature->getZone(); Assert(pZone != NULL); pZone->broadcastPacket(pCreature->getX(), pCreature->getY(), &gcOtherModifyInfo, pCreature); } __LEAVE_CRITICAL_SECTION((*g_pPCFinder)) // Guild Member 객체를 삭제한다. SAFE_DELETE(pGuildMember); } // 길드 멤버 맵을 삭제한다. Members.clear(); // 길드 매니저에서 길드를 삭제한다. g_pGuildManager->deleteGuild(pGuild->getID()); // 길드 객체를 삭제한다. SAFE_DELETE(pGuild); } else if (pGuild->getState() == Guild::GUILD_STATE_WAIT ) { HashMapGuildMember& Members = pGuild->getMembers(); HashMapGuildMemberItor itr = Members.begin(); Statement* pStmt = NULL; Result* pResult = NULL; BEGIN_DB { pStmt = g_pDatabaseManager->getConnection("DARKEDEN" )->createStatement(); for (; itr != Members.end(); itr++ ) { GuildMember* pGuildMember = itr->second; // 접속해 있으면 __ENTER_CRITICAL_SECTION((*g_pPCFinder)) Creature* pCreature = g_pPCFinder->getCreature_LOCKED(pGuildMember->getName()); if (pCreature != NULL && pCreature->isPC() ) { Player* pPlayer = pCreature->getPlayer(); Assert(pPlayer != NULL); PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPlayerCreature != NULL); // 등록비를 환불한다. Gold_t Gold = pPlayerCreature->getGold(); if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_MASTER ) { Gold = min((uint64_t)(Gold + RETURN_SLAYER_MASTER_GOLD), (uint64_t)2000000000); } else if (pGuildMember->getRank() == GuildMember::GUILDMEMBER_RANK_SUBMASTER ) { Gold = min((uint64_t)(Gold + RETURN_SLAYER_SUBMASTER_GOLD), (uint64_t)2000000000); } pPlayerCreature->setGoldEx(Gold); GCModifyInformation gcModifyInformation; gcModifyInformation.addLongData(MODIFY_GOLD, Gold); pPlayer->sendPacket(&gcModifyInformation); // 메시지를 보낸다. pResult = pStmt->executeQuery("SELECT Message FROM Messages WHERE Receiver = '%s'", pCreature->getName().c_str()); while (pResult->next() ) { GCSystemMessage message; message.setMessage(pResult->getString(1)); pPlayer->sendPacket(&message); } pStmt->executeQuery("DELETE FROM Messages WHERE Receiver = '%s'", pCreature->getName().c_str()); } __LEAVE_CRITICAL_SECTION((*g_pPCFinder)) // 길드 멤버 객체를 삭제한다. SAFE_DELETE(pGuildMember); } // 길드 멤버 해쉬 맵을 지운다. Members.clear(); // 길드 매니저에서 길드를 삭제한다. g_pGuildManager->deleteGuild(pGuild->getID()); GuildUnionManager::Instance().removeMasterGuild(pGuild->getID()); // 길드 객체를 삭제한다. SAFE_DELETE(pGuild); SAFE_DELETE(pStmt); } END_DB(pStmt) }
void CGRequestUnionInfoHandler::execute (CGRequestUnionInfo* pPacket , Player* pPlayer) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ Assert(pPacket != NULL); Assert(pPlayer != NULL); SYSTEM_ASSERT(SYSTEM_GUILD); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); PlayerCreature* pPlayerCreature = dynamic_cast<PlayerCreature*>(pGamePlayer->getCreature()); Assert(pPlayerCreature != NULL); #ifdef __OLD_GUILD_WAR__ GCSystemMessage gcSM; gcSM.setMessage("아직 지원되지 않는 기능입니다."); pGamePlayer->sendPacket(&gcSM); return; #endif GCGuildResponse gcGuildResponse; GuildUnion *pGuildUnion = GuildUnionManager::Instance().getGuildUnion(pPlayerCreature->getGuildID()); // 자기가 속한 길드가 연합에 가입되어있는지 찾는다 if (pGuildUnion == NULL) { gcGuildResponse.setCode(GuildUnionOfferManager::NOT_IN_UNION); pPlayer->sendPacket(&gcGuildResponse); return; } // Master 길드의 정보를 가져온다. Guild* pGuild = g_pGuildManager->getGuild(pGuildUnion->getMasterGuildID()); if (pGuild == NULL) { gcGuildResponse.setCode(GuildUnionOfferManager::NO_TARGET_UNION); pPlayer->sendPacket(&gcGuildResponse); return; } GCShowUnionInfo gcShowUnionInfo; if (pGuild->getState() == Guild::GUILD_STATE_ACTIVE ) { gcShowUnionInfo.getMasterGuildInfo().setGuildID(pGuild->getID()); gcShowUnionInfo.getMasterGuildInfo().setGuildName(pGuild->getName()); gcShowUnionInfo.getMasterGuildInfo().setGuildState(pGuild->getState()); gcShowUnionInfo.getMasterGuildInfo().setGuildMaster(pGuild->getMaster()); gcShowUnionInfo.getMasterGuildInfo().setGuildMemberCount(pGuild->getActiveMemberCount()); gcShowUnionInfo.getMasterGuildInfo().setGuildIntro(pGuild->getIntro()); gcShowUnionInfo.getMasterGuildInfo().setJoinFee(0); } list<GuildID_t> gList = pGuildUnion->getGuildList(); list<GuildID_t>::iterator itr = gList.begin(); for (; itr != gList.end() ; ++itr ) { Guild* pGuild2 = g_pGuildManager->getGuild(*itr); if(pGuild2 != NULL) { SingleGuildInfo *GuildInfo = new SingleGuildInfo; GuildInfo->setGuildID(pGuild2->getID()); GuildInfo->setGuildName(pGuild2->getName()); GuildInfo->setGuildState(pGuild2->getState()); GuildInfo->setGuildMaster(pGuild2->getMaster()); GuildInfo->setGuildMemberCount(pGuild2->getActiveMemberCount()); GuildInfo->setGuildIntro(pGuild2->getIntro()); GuildInfo->setJoinFee(0); gcShowUnionInfo.addGuildInfoList(GuildInfo); } } pPlayer->sendPacket(&gcShowUnionInfo); #endif // __GAME_SERVER__ __END_DEBUG_EX __END_CATCH }
void EffectRelicPosition::affect(Item* pItem) throw(Error) { __BEGIN_TRY // 존 정보를 얻는다. ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(m_ZoneID); Assert(pZoneInfo != NULL); if (pItem->getItemClass() == Item::ITEM_CLASS_RELIC) { // 성물의 정보를 얻는다. ItemType_t relicIndex = pItem->getItemType(); const RelicInfo* pRelicInfo = dynamic_cast<RelicInfo*>(g_pRelicInfoManager->getItemInfo(relicIndex)); Assert(pRelicInfo != NULL); // StringStream msg; /* // 위치를 알린다. msg << "성물(" << pRelicInfo->getName() << ")이 " << pZoneInfo->getFullName() << "(" << (int)m_X << ", " << (int)m_Y << ")에 떨어져 있습니다."; */ char msg[100]; sprintf(msg, g_pStringPool->c_str(STRID_RELIC_IN_ZONE ), pRelicInfo->getName().c_str(), pZoneInfo->getFullName().c_str(), (int)m_X, (int)m_Y ); GCSystemMessage gcSystemMessage; gcSystemMessage.setType(SYSTEM_MESSAGE_COMBAT); gcSystemMessage.setMessage(msg); g_pHolyLandManager->broadcast(&gcSystemMessage); setNextTime(m_Tick); } else if (pItem->getItemClass() == Item::ITEM_CLASS_BLOOD_BIBLE) { ShrineSet* pShrineSet = g_pShrineInfoManager->getShrineSet(m_Part); Assert(pShrineSet!=NULL); GCBloodBibleStatus* pGCBBS = new GCBloodBibleStatus; pGCBBS->setItemType(m_Part); pGCBBS->setZoneID(m_ZoneID); pGCBBS->setStorage(STORAGE_ZONE); //pGCBBS->setRace(pShrineSet->getOwnerRace()); pGCBBS->setShrineRace(pShrineSet->getOwnerRace()); pGCBBS->setX(m_X); pGCBBS->setY(m_Y); // g_pHolyLandManager->broadcast(pGCBBS); g_pZoneGroupManager->broadcast(pGCBBS); g_pShrineInfoManager->registerBloodBibleStatus(m_Part, pGCBBS); /* msg << "피의 성서 조각이 " << pZoneInfo->getFullName() << "(" << (int)m_X << ", " << (int)m_Y << ")에 떨어져 있습니다."; g_pZoneGroupManager->broadcast(&gcSystemMessage); */ setNextTime(999999); } else if (pItem->getItemClass() == Item::ITEM_CLASS_CASTLE_SYMBOL) { // StringStream msg; // msg << "성의 상징이 " // << pZoneInfo->getFullName() << "(" << (int)m_X << ", " << (int)m_Y << ")에 떨어져 있습니다."; char msg[200]; sprintf(msg, g_pStringPool->c_str(STRID_BROADCAST_CASTLE_SYMBOL_POSITION_3 ), pZoneInfo->getFullName().c_str(), (int)m_X, (int)m_Y); GCSystemMessage gcSystemMessage; gcSystemMessage.setType(SYSTEM_MESSAGE_HOLY_LAND); gcSystemMessage.setMessage(msg); g_pCastleInfoManager->broadcastShrinePacket(m_Part, &gcSystemMessage); setNextTime(m_Tick); // g_pZoneGroupManager->broadcast(&gcSystemMessage); } else { return; } __END_CATCH }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionWarpToNoviceZone::execute (Creature * pNPC , Creature * pCreature) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG Assert(pCreature != NULL); Assert(pCreature->isPC()); if (!pCreature->isSlayer() ) return; Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature); ZoneID_t ZoneID = pSlayer->getZoneID(); ZoneCoord_t X = pSlayer->getX(); ZoneCoord_t Y = pSlayer->getY(); Attr_t totalAttr = pSlayer->getTotalAttr(ATTR_BASIC); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pCreature->getPlayer()); bool bTransport = true; if (totalAttr <= 40 ) { ZoneID = m_NoviceZoneID; X = m_NoviceX; Y = m_NoviceY; } else if (totalAttr <= 60 ) { ZoneID = m_BeginnerZoneID; X = m_BeginnerX; Y = m_BeginnerY; } else { GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_NOT_BEGINNER )); pGamePlayer->sendPacket (&gcSystemMessage); bTransport = false; } //Zone* pZone = pCreature->getZone(); #if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__) try { ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(ZoneID); // 유료존인데 유료사용자가 아니면... if (pZoneInfo==NULL || pZoneInfo->isPayPlay() && !pGamePlayer->isPayPlaying()) { string connectIP = pGamePlayer->getSocket()->getHost(); // 유료 서비스 사용이 가능한가? if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID())) { sendPayInfo(pGamePlayer); } else { // 유료 서비스 사용 불가인 경우 GCSystemMessage gcSystemMessage; if (g_pConfig->getPropertyInt("IsNetMarble")==0) { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_PAY_ZONE)); } else { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER)); } pGamePlayer->sendPacket (&gcSystemMessage); bTransport = false; } } } catch (NoSuchElementException&) { } #endif if (bTransport) { transportCreature(pCreature, ZoneID, X, Y, true); } else { if (pNPC != NULL ) { GCNPCResponse response; response.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pGamePlayer->sendPacket(&response); } } __END_DEBUG __END_CATCH }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionActivatePortal::execute (Creature * pNPC , Creature * pCreature) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG Assert(pCreature != NULL); Assert(pCreature->isPC()); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pCreature->getPlayer()); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature); //Zone* pZone = pCreature->getZone(); bool bTransport = true; #if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__) try { ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(m_ZoneID); // 유료존인데 유료사용자가 아니면... if (pZoneInfo==NULL || pZoneInfo->isPayPlay() && !pGamePlayer->isPayPlaying()) { string connectIP = pGamePlayer->getSocket()->getHost(); // 유료 서비스 사용이 가능한가? if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID())) { sendPayInfo(pGamePlayer); } else if (!pGamePlayer->isFamilyFreePass() ) // 패밀리 프리 패스는 유료존으로 갈 수 있다. { // 유료 서비스 사용 불가인 경우 GCSystemMessage gcSystemMessage; if (g_pConfig->getPropertyInt("IsNetMarble")==0) { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_PAY_ZONE)); } else { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER)); } pGamePlayer->sendPacket (&gcSystemMessage); bTransport = false; } } } catch (NoSuchElementException&) { } #endif if (bTransport) { if (m_ZoneID == 1410 ) { if (pCreature->isFlag(Effect::EFFECT_CLASS_CAN_ENTER_GDR_LAIR ) ) { Effect* pEffect = pCreature->findEffect(Effect::EFFECT_CLASS_CAN_ENTER_GDR_LAIR); if (pEffect != NULL ) pEffect->setDeadline(0); } if (pCreature->isSlayer() ) { Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature); Assert(pSlayer != NULL); // 오토바이를 타고 있으면 오토바이에서 내린다. if (pSlayer->hasRideMotorcycle() ) { pSlayer->getOffMotorcycle(); } } if (pCreature->isOusters() ) { Ousters* pOusters = dynamic_cast<Ousters*>(pCreature); Assert(pOusters != NULL); // 실프 타고 있으면 내려준다 if (pOusters->isFlag(Effect::EFFECT_CLASS_SUMMON_SYLPH) ) { Effect* pEffect = pOusters->findEffect(Effect::EFFECT_CLASS_SUMMON_SYLPH); if (pEffect != NULL ) pEffect->setDeadline(0); } } if (pCreature->isVampire() ) { Vampire* pVampire = dynamic_cast<Vampire*>(pCreature); Assert(pVampire != NULL); if (pVampire->isFlag(Effect::EFFECT_CLASS_TRANSFORM_TO_BAT) ) { addUntransformCreature(pVampire->getZone(), pVampire, true); } } } if (pNPC != NULL ) { pPC->getGQuestManager()->illegalWarp(); } transportCreature(pCreature, m_ZoneID, m_X, m_Y, true); } else { GCNPCResponse response; response.setCode(NPC_RESPONSE_QUIT_DIALOGUE); pGamePlayer->sendPacket(&response); } __END_DEBUG __END_CATCH }
void CGModifyTaxRatioHandler::execute (CGModifyTaxRatio* pPacket , Player* pPlayer) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ 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); #ifdef __OLD_GUILD_WAR__ GCSystemMessage gcSM; gcSM.setMessage("아직 지원되지 않는 기능입니다."); pGamePlayer->sendPacket(&gcSM); return; #endif GuildID_t guildID = pPC->getGuildID(); list<CastleInfo*> pCastleInfoList = g_pCastleInfoManager->getGuildCastleInfos(guildID); if (pCastleInfoList.empty() ) { GCNPCResponse fail; fail.setCode(NPC_RESPONSE_MODIFY_TAX_RATIO_FAIL); pGamePlayer->sendPacket(&fail); return; } bool bOwner = false; list<CastleInfo*>::iterator itr = pCastleInfoList.begin(); CastleInfo* pCastleInfo = NULL; for (; itr != pCastleInfoList.end() ; itr++ ) { if ((*itr)->getZoneID() == pPC->getZoneID() ) { pCastleInfo = (*itr); bOwner = true; break; } } if (!g_pGuildManager->isGuildMaster(guildID, pPC ) // 길드 마스터가 아니다. || !bOwner // 이 플레이어의 길드가 점령한 성이 아니다. || pPacket->getRatio() > 10 ) { GCNPCResponse fail; fail.setCode(NPC_RESPONSE_MODIFY_TAX_RATIO_FAIL); pGamePlayer->sendPacket(&fail); return; } g_pCastleInfoManager->setItemTaxRatio(pPC->getZone(), pPacket->getRatio()+100); GCNPCResponse ok; ok.setCode(NPC_RESPONSE_MODIFY_TAX_RATIO_OK); pGamePlayer->sendPacket(&ok); #endif // __GAME_SERVER__ __END_DEBUG_EX __END_CATCH }
void EffectHasVampireRelic::affect(Creature* pCreature) throw(Error) { __BEGIN_TRY //Timeval nextTime = getNextTime(); //Timeval deadLine = getDeadline(); //Turn_t RemainTime = deadLine.tv_sec - nextTime.tv_sec; /* StringStream msg; if (pCreature->isSlayer()) { Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature); msg << pSlayer->getName(); } else { Vampire* pVampire = dynamic_cast<Vampire*>(pCreature); msg << pVampire->getName(); } msg << " 님이 뱀파이어 성물을 가졌습니다."; GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(msg.toString()); g_pZoneGroupManager->broadcast(&gcSystemMessage); */ // 존 정보를 얻는다. Zone* pZone = pCreature->getZone(); Assert(pZone!=NULL); ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(pZone->getZoneID()); Assert(pZoneInfo != NULL); // 위치를 알린다. char msg[100]; const char* race; if (pCreature->isSlayer() ) { race = g_pStringPool->c_str(STRID_SLAYER); } else if (pCreature->isVampire() ) { race = g_pStringPool->c_str(STRID_VAMPIRE); } else if (pCreature->isOusters() ) { race = g_pStringPool->c_str(STRID_OUSTERS); } sprintf(msg, g_pStringPool->c_str(STRID_HAVING_VAMPIRE_RELIC ), pCreature->getName().c_str(), race, // (pCreature->isSlayer() ? g_pStringPool->c_str(STRID_SLAYER ) : g_pStringPool->c_str(STRID_VAMPIRE ) ), (int)pCreature->getX(), (int)pCreature->getY() ); /* // 위치를 알린다. StringStream msg; msg << pCreature->getName() << " 님(" << (pCreature->isSlayer() ? "슬레이어" : "뱀파이어" ) << ")이 " << pZoneInfo->getFullName() << "(" << (int)pCreature->getX() << ", " << (int)pCreature->getY() << ")에서 뱀파이어 성물을 가지고 있습니다."; */ GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(msg); g_pZoneGroupManager->broadcast(&gcSystemMessage); setNextTime(m_Tick); __END_CATCH }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionEnterGDRLair::execute (Creature * pNPC , Creature * pCreature) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG Assert(pCreature != NULL); Assert(pCreature->isPC()); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pCreature->getPlayer()); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPC != NULL); ZoneID_t zoneID; ZoneCoord_t X, Y; if (m_PortalID == GDRLairManager::Instance().getCorrectPortal() ) { zoneID = 1412; X = 142; Y = 169; } else { zoneID = 1411; X = 125; Y = 58; } bool bTransport = true; #if defined(__PAY_SYSTEM_ZONE__) || defined(__PAY_SYSTEM_FREE_LIMIT__) try { ZoneInfo* pZoneInfo = g_pZoneInfoManager->getZoneInfo(zoneID); // 유료존인데 유료사용자가 아니면... if (pZoneInfo==NULL || pZoneInfo->isPayPlay() && !pGamePlayer->isPayPlaying()) { string connectIP = pGamePlayer->getSocket()->getHost(); // 유료 서비스 사용이 가능한가? if (pGamePlayer->loginPayPlay(connectIP, pGamePlayer->getID())) { sendPayInfo(pGamePlayer); } else { // 유료 서비스 사용 불가인 경우 GCSystemMessage gcSystemMessage; if (g_pConfig->getPropertyInt("IsNetMarble")==0) { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER_PAY_ZONE )); } else { gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER )); } pGamePlayer->sendPacket (&gcSystemMessage); bTransport = false; return; } } } catch (NoSuchElementException&) { } #endif if (bTransport) { if (pPC->isSlayer() ) { Slayer* pSlayer = dynamic_cast<Slayer*>(pPC); Assert(pSlayer != NULL); // 오토바이를 타고 있으면 오토바이에서 내린다. if (pSlayer->hasRideMotorcycle() ) { pSlayer->getOffMotorcycle(); } } if (pPC->isOusters() ) { Ousters* pOusters = dynamic_cast<Ousters*>(pPC); Assert(pOusters != NULL); // 실프 타고 있으면 내려준다 if (pOusters->isFlag(Effect::EFFECT_CLASS_SUMMON_SYLPH) ) { Effect* pEffect = pOusters->findEffect(Effect::EFFECT_CLASS_SUMMON_SYLPH); if (pEffect != NULL ) pEffect->setDeadline(0); } } if (pPC->isVampire() ) { Vampire* pVampire = dynamic_cast<Vampire*>(pPC); Assert(pVampire != NULL); if (pVampire->isFlag(Effect::EFFECT_CLASS_TRANSFORM_TO_BAT) ) { addUntransformCreature(pVampire->getZone(), pVampire, true); } } Effect* pEffect = pPC->findEffect(Effect::EFFECT_CLASS_CAN_ENTER_GDR_LAIR); if (pEffect != NULL ) pEffect->setDeadline(0); transportCreature(pCreature, zoneID, X, Y, true); } else { GCSystemMessage gcSystemMessage; gcSystemMessage.setMessage(g_pStringPool->getString(STRID_CANNOT_ENTER )); pGamePlayer->sendPacket (&gcSystemMessage); } __END_DEBUG __END_CATCH }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionEnterSiege::execute (Creature * pNPC , Creature * pCreature) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG Assert(pCreature != NULL); Assert(pCreature->isPC()); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pCreature->getPlayer()); if (!g_pWarSystem->hasCastleActiveWar(m_ZoneID ) ) { GCSystemMessage gcSM; gcSM.setMessage("공선전 중에만 입장하실 수 있습니다."); pGamePlayer->sendPacket(&gcSM); return; } PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature); Assert(pPC != NULL); Zone* pZone = getZoneByZoneID(m_ZoneID); Assert(pZone != NULL); WarScheduler* pWS = pZone->getWarScheduler(); Assert(pWS != NULL); ZoneID_t siegeZoneID = SiegeManager::Instance().getSiegeZoneID(m_ZoneID); Assert(siegeZoneID != 0); /* WarSchedule* pSchedule = dynamic_cast<WarSchedule*>(pWS->getRecentSchedule()); if (pSchedule == NULL ) { return; }*/ SiegeWar* pSiegeWar = dynamic_cast<SiegeWar*>(g_pWarSystem->getActiveWar(m_ZoneID )); if (pSiegeWar == NULL ) { GCSystemMessage gcSM; gcSM.setMessage("타입 1 서버 오류입니다. 운영팀에 문의하세요."); pGamePlayer->sendPacket(&gcSM); return; } int side = pSiegeWar->getGuildSide(pPC->getGuildID()); if (side == 0 ) { GCSystemMessage gcSM; gcSM.setMessage("전쟁에 참가한 길드가 아닙니다."); pGamePlayer->sendPacket(&gcSM); return; } if (!g_pGuildManager->isGuildMaster(pPC->getGuildID(), pPC ) ) { GCSystemMessage gcSM; gcSM.setMessage("길드 마스터만 가능합니다."); pGamePlayer->sendPacket(&gcSM); return; } static TPOINT targetPos[7] = { {172, 38}, {172, 38}, {20, 232}, {20, 232}, {20, 232}, {20, 232}, {20, 232} }; // 소환자의 존과 좌표. ZoneID_t ZoneNum = siegeZoneID; Coord_t ZoneX = targetPos[side-1].x; Coord_t ZoneY = targetPos[side-1].y; for (int i=0; i<7; ++i ) { deleteCreatureEffect(pPC, (Effect::EffectClass)(Effect::EFFECT_CLASS_SIEGE_DEFENDER + i)); } if (side < 8 && side > 0 ) { //cout << "side : " << side << endl; addSimpleCreatureEffect(pPC, (Effect::EffectClass)(Effect::EFFECT_CLASS_SIEGE_DEFENDER + side - 1)); } EventTransport* pEvent = dynamic_cast<EventTransport*>(pGamePlayer->getEvent(Event::EVENT_CLASS_TRANSPORT)); bool newEvent = false; if (pEvent==NULL) { pEvent = new EventTransport(pGamePlayer); newEvent = true; } // pEvent = new EventTransport(pGamePlayer); pEvent->setTargetZone(ZoneNum, ZoneX, ZoneY); pEvent->setDeadline(0); if (newEvent ) pGamePlayer->addEvent(pEvent); __END_DEBUG __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 }