void giveMemberReward(PlayerCreature* pPC, uint type ) { Exp_t exp = ExpRewardTable[pPC->getRace()][pPC->getLevel()]; Gold_t gold = GoldRewardTable[pPC->getRace()][type]; pPC->increaseGoldEx(gold); GCModifyInformation gcMI; gcMI.addLongData(MODIFY_GOLD, pPC->getGold()); if (pPC->isSlayer() ) { Slayer* pSlayer = dynamic_cast<Slayer*>(pPC); increaseDomainExp(pSlayer, pSlayer->getHighestSkillDomain(), exp, gcMI); pSlayer->getPlayer()->sendPacket(&gcMI); } else if (pPC->isVampire() ) { Vampire* pVampire = dynamic_cast<Vampire*>(pPC); increaseVampExp(pVampire, exp, gcMI); pVampire->getPlayer()->sendPacket(&gcMI); } else if (pPC->isOusters() ) { GCModifyInformation gcMI; Ousters* pOusters = dynamic_cast<Ousters*>(pPC); increaseOustersExp(pOusters, exp, gcMI); } }
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 EffectDecreaseHP::unaffect(Creature* pCreature) throw(Error) { __BEGIN_TRY __BEGIN_DEBUG Assert(pCreature != NULL); Zone* pZone = pCreature->getZone(); Assert(pZone != NULL); pCreature->removeFlag(Effect::EFFECT_CLASS_DECREASE_HP); Damage_t decreaseHP = m_Point; if (!(pZone->getZoneLevel() & COMPLETE_SAFE_ZONE) && !pCreature->isDead() && !pCreature->isFlag(Effect::EFFECT_CLASS_COMA) // 무적상태 체크. by sigi. 2002.9.5 && canAttack(NULL, pCreature ) ) { if (pCreature->isSlayer()) { Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature); HP_t CurrentHP = pSlayer->getHP(ATTR_CURRENT); if (CurrentHP > 0) { HP_t RemainHP = max(0, CurrentHP -(int)decreaseHP); pSlayer->setHP(RemainHP, ATTR_CURRENT); GCModifyInformation gcMI; gcMI.addShortData(MODIFY_CURRENT_HP, RemainHP); pSlayer->getPlayer()->sendPacket(&gcMI); // 변한 HP를 브로드캐스팅해준다. GCStatusCurrentHP pkt; pkt.setObjectID(pSlayer->getObjectID()); pkt.setCurrentHP(RemainHP); pZone->broadcastPacket(pSlayer->getX(), pSlayer->getY(), &pkt); } } else if (pCreature->isVampire()) { Vampire* pVampire = dynamic_cast<Vampire*>(pCreature); HP_t CurrentHP = pVampire->getHP(ATTR_CURRENT); if (CurrentHP > 0) { HP_t RemainHP = max(0, CurrentHP -(int)decreaseHP); pVampire->setHP(RemainHP, ATTR_CURRENT); GCModifyInformation gcMI; gcMI.addShortData(MODIFY_CURRENT_HP, RemainHP); pVampire->getPlayer()->sendPacket(&gcMI); // 공격(흡혈) 당하는 경우에는 공격자의 성향이 바뀜 by sigi. 2002.12.27 Creature* pAttacker = pZone->getCreature(m_UserObjectID); if (pAttacker!=NULL && pAttacker->isVampire()) { Vampire* pAttackVampire = dynamic_cast<Vampire*>(pAttacker); GCModifyInformation gcAttackerMI; computeAlignmentChange(pVampire, decreaseHP, pAttackVampire, NULL, &gcAttackerMI); // 뭔가 변한 정보가 있다면 보내준다. if (gcAttackerMI.getShortCount()+gcAttackerMI.getLongCount() > 0) { pAttackVampire->getPlayer()->sendPacket(&gcAttackerMI); } } // 변한 HP를 브로드캐스팅해준다. GCStatusCurrentHP pkt; pkt.setObjectID(pVampire->getObjectID()); pkt.setCurrentHP(RemainHP); pZone->broadcastPacket(pVampire->getX(), pVampire->getY(), &pkt); } } else if (pCreature->isOusters()) { Ousters* pOusters = dynamic_cast<Ousters*>(pCreature); HP_t CurrentHP = pOusters->getHP(ATTR_CURRENT); if (CurrentHP > 0) { HP_t RemainHP = max(0, CurrentHP -(int)decreaseHP); pOusters->setHP(RemainHP, ATTR_CURRENT); GCModifyInformation gcMI; gcMI.addShortData(MODIFY_CURRENT_HP, RemainHP); pOusters->getPlayer()->sendPacket(&gcMI); // 공격(흡혈) 당하는 경우에는 공격자의 성향이 바뀜 by sigi. 2002.12.27 Creature* pAttacker = pZone->getCreature(m_UserObjectID); if (pAttacker!=NULL && pAttacker->isOusters()) { Ousters* pAttackOusters = dynamic_cast<Ousters*>(pAttacker); GCModifyInformation gcAttackerMI; computeAlignmentChange(pOusters, decreaseHP, pAttackOusters, NULL, &gcAttackerMI); // 뭔가 변한 정보가 있다면 보내준다. if (gcAttackerMI.getShortCount()+gcAttackerMI.getLongCount() > 0) { pAttackOusters->getPlayer()->sendPacket(&gcAttackerMI); } } // 변한 HP를 브로드캐스팅해준다. GCStatusCurrentHP pkt; pkt.setObjectID(pOusters->getObjectID()); pkt.setCurrentHP(RemainHP); pZone->broadcastPacket(pOusters->getX(), pOusters->getY(), &pkt); } } else if (pCreature->isMonster()) { Monster* pMonster = dynamic_cast<Monster*>(pCreature); HP_t CurrentHP = pMonster->getHP(ATTR_CURRENT); if (CurrentHP > 0) { HP_t RemainHP = max(0, CurrentHP -(int)decreaseHP); pMonster->setHP(RemainHP, ATTR_CURRENT); // 변한 HP를 브로드캐스팅해준다. GCStatusCurrentHP pkt; pkt.setObjectID(pMonster->getObjectID()); pkt.setCurrentHP(RemainHP); pZone->broadcastPacket(pMonster->getX(), pMonster->getY(), &pkt); if (RemainHP == 0 ) { Creature* pAttacker = pZone->getCreature(m_UserObjectID); if (pAttacker != NULL && pAttacker->isVampire() ) { Vampire* pAttackVampire = dynamic_cast<Vampire*>(pAttacker); GCModifyInformation gcMI; increaseAlignment(pAttackVampire, pCreature, gcMI); if (gcMI.getShortCount() > 0 || gcMI.getLongCount() > 0 ) pAttackVampire->getPlayer()->sendPacket(&gcMI); } } } } // m_CasterName이 pCreature를 죽인 경우의 KillCount 처리 // by sigi. 2002.9.9 if (pCreature->isDead()) { Creature* pAttacker = pZone->getCreature(m_UserObjectID); if (pAttacker!=NULL) { if (pAttacker->isVampire()) { Vampire* pVampire = dynamic_cast<Vampire*>(pAttacker); // 죽일때 경험치를 준다. GCModifyInformation mi; int exp = computeCreatureExp(pCreature, KILL_EXP); shareVampExp(pVampire, exp, mi); if (pCreature->isMonster() ) { increaseFame(pVampire, decreaseHP); mi.addLongData(MODIFY_FAME, pVampire->getFame()); } pAttacker->getPlayer()->sendPacket(&mi); } else if (pAttacker->isOusters() ) { Ousters* pOusters = dynamic_cast<Ousters*>(pAttacker); GCModifyInformation mi; int exp = computeCreatureExp(pCreature, 100); shareOustersExp(pOusters, exp, mi); if (pCreature->isMonster() ) { increaseFame(pOusters, decreaseHP); mi.addLongData(MODIFY_FAME, pOusters->getFame()); } } affectKillCount(pAttacker, pCreature); } } } __END_DEBUG __END_CATCH }
void EffectAlignmentRecovery::unaffect(Creature* pCreature) throw(Error) { __BEGIN_TRY Assert(pCreature != NULL); if (pCreature->isSlayer()) { Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature); Assert(pSlayer != NULL); Zone* pZone = pSlayer->getZone(); Assert(pZone != NULL); if (m_Period != 0) { // 한 턴에 얼마나 회복 시킬 것인가. Alignment_t CurrentAlignment = pSlayer->getAlignment(); Alignment_t NewAlignment = min(10000, (int)(CurrentAlignment + m_AlignmentQuantity* m_Period)); pSlayer->setAlignment(NewAlignment); WORD AlignmentSaveCount = pSlayer->getAlignmentSaveCount(); if (AlignmentSaveCount == 10) { StringStream msg; msg << "Alignment = " << NewAlignment; pSlayer->tinysave(msg.toString()); AlignmentSaveCount = 0; } else AlignmentSaveCount++; pSlayer->setAlignmentSaveCount(AlignmentSaveCount); } // 현재 Alignment를 브로드캐스팅한다. // 이제 회복이 끝났나는 것을 알리도록 한다. // 자신에게 먼저 GCModifyInformation gcModifyInformation; gcModifyInformation.addLongData(MODIFY_ALIGNMENT, pSlayer->getAlignment()); pSlayer->getPlayer()->sendPacket(&gcModifyInformation); // 주변사람에게도 무언가를 날려줘야 한다. // 패킷을 새로 만들어야겠지.. pSlayer->removeFlag(Effect::EFFECT_CLASS_ALIGNMENT_RECOVERY); } else if (pCreature->isVampire()) { Vampire* pVampire = dynamic_cast<Vampire*>(pCreature); //Zone* pZone = pVampire->getZone(); if (m_Period != 0) { // 한 턴에 얼마나 회복 시킬 것인가. Alignment_t CurrentAlignment = pVampire->getAlignment(); Alignment_t NewAlignment = min(10000, (int)(CurrentAlignment + m_AlignmentQuantity* m_Period)); WORD AlignmentSaveCount = pVampire->getAlignmentSaveCount(); if (AlignmentSaveCount == 10) { StringStream msg; msg << "Alignment = " << NewAlignment; pVampire->tinysave(msg.toString()); AlignmentSaveCount = 0; } else AlignmentSaveCount++; pVampire->setAlignmentSaveCount(AlignmentSaveCount); } // 현재 Alignment를 브로드캐스팅한다. // 이제 회복이 끝났나는 것을 알리도록 한다. // 자신에게 먼저 GCModifyInformation gcModifyInformation; gcModifyInformation.addLongData(MODIFY_ALIGNMENT, pVampire->getAlignment()); pVampire->getPlayer()->sendPacket(&gcModifyInformation); // 주변사람에게도.. pVampire->removeFlag(Effect::EFFECT_CLASS_ALIGNMENT_RECOVERY); } else if (pCreature->isOusters()) { Ousters* pOusters = dynamic_cast<Ousters*>(pCreature); //Zone* pZone = pOusters->getZone(); if (m_Period != 0) { // 한 턴에 얼마나 회복 시킬 것인가. Alignment_t CurrentAlignment = pOusters->getAlignment(); Alignment_t NewAlignment = min(10000, (int)(CurrentAlignment + m_AlignmentQuantity* m_Period)); WORD AlignmentSaveCount = pOusters->getAlignmentSaveCount(); if (AlignmentSaveCount == 10) { StringStream msg; msg << "Alignment = " << NewAlignment; pOusters->tinysave(msg.toString()); AlignmentSaveCount = 0; } else AlignmentSaveCount++; pOusters->setAlignmentSaveCount(AlignmentSaveCount); } // 현재 Alignment를 브로드캐스팅한다. // 이제 회복이 끝났나는 것을 알리도록 한다. // 자신에게 먼저 GCModifyInformation gcModifyInformation; gcModifyInformation.addLongData(MODIFY_ALIGNMENT, pOusters->getAlignment()); pOusters->getPlayer()->sendPacket(&gcModifyInformation); // 주변사람에게도.. pOusters->removeFlag(Effect::EFFECT_CLASS_ALIGNMENT_RECOVERY); } __END_CATCH }
void EffectAlignmentRecovery::affect(Creature* pCreature) throw(Error) { __BEGIN_TRY Assert(pCreature != NULL); Assert(pCreature->isPC()); Timeval CurrentTime; getCurrentTime(CurrentTime); GCModifyInformation gcModifyInformation; Alignment_t CurrentAlignment = 0; Alignment_t NewAlignment = 0; if (pCreature->isSlayer()) { Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature); Assert(pSlayer != NULL); if (m_Period != 0) { // 플레그 걸귀 pSlayer->setFlag(Effect::EFFECT_CLASS_ALIGNMENT_RECOVERY); // 한 턴에 얼마나 회복 시킬 것인가. CurrentAlignment = pSlayer->getAlignment(); NewAlignment = min(10000, (int)(CurrentAlignment + m_AlignmentQuantity)); pSlayer->setAlignment(NewAlignment); gcModifyInformation.addLongData(MODIFY_ALIGNMENT, NewAlignment); pSlayer->getPlayer()->sendPacket(&gcModifyInformation); WORD AlignmentSaveCount = pSlayer->getAlignmentSaveCount(); if (AlignmentSaveCount > ALIGNMENT_SAVE_PERIOD) { StringStream msg; msg << "Alignment = " << NewAlignment; pSlayer->tinysave(msg.toString()); AlignmentSaveCount = 0; } else AlignmentSaveCount++; pSlayer->setAlignmentSaveCount(AlignmentSaveCount); } else { // unaffect하면서 패킷이 날아갈 테니까.... setDeadline(0); } m_Period--; } else if (pCreature->isVampire()) { Vampire* pVampire = dynamic_cast<Vampire*>(pCreature); Assert(pVampire != NULL); if (m_Period != 0) { // 플레그 걸귀 pVampire->setFlag(Effect::EFFECT_CLASS_ALIGNMENT_RECOVERY); // 한 턴에 얼마나 회복 시킬 것인가. CurrentAlignment = pVampire->getAlignment(); NewAlignment = min(10000, CurrentAlignment + m_AlignmentQuantity); pVampire->setAlignment(NewAlignment); gcModifyInformation.addLongData(MODIFY_ALIGNMENT, NewAlignment); pVampire->getPlayer()->sendPacket(&gcModifyInformation); WORD AlignmentSaveCount = pVampire->getAlignmentSaveCount(); if (AlignmentSaveCount > ALIGNMENT_SAVE_PERIOD) { StringStream msg; msg << "Alignment = " << NewAlignment; pVampire->tinysave(msg.toString()); AlignmentSaveCount = 0; } else AlignmentSaveCount++; pVampire->setAlignmentSaveCount(AlignmentSaveCount); } else { // unaffect하면서 패킷이 날아갈 테니까.... setDeadline(0); } m_Period--; } else if (pCreature->isOusters()) { Ousters* pOusters = dynamic_cast<Ousters*>(pCreature); Assert(pOusters != NULL); if (m_Period != 0) { // 플레그 걸귀 pOusters->setFlag(Effect::EFFECT_CLASS_ALIGNMENT_RECOVERY); // 한 턴에 얼마나 회복 시킬 것인가. CurrentAlignment = pOusters->getAlignment(); NewAlignment = min(10000, CurrentAlignment + m_AlignmentQuantity); pOusters->setAlignment(NewAlignment); gcModifyInformation.addLongData(MODIFY_ALIGNMENT, NewAlignment); pOusters->getPlayer()->sendPacket(&gcModifyInformation); WORD AlignmentSaveCount = pOusters->getAlignmentSaveCount(); if (AlignmentSaveCount > ALIGNMENT_SAVE_PERIOD) { StringStream msg; msg << "Alignment = " << NewAlignment; pOusters->tinysave(msg.toString()); AlignmentSaveCount = 0; } else AlignmentSaveCount++; pOusters->setAlignmentSaveCount(AlignmentSaveCount); } else { // unaffect하면서 패킷이 날아갈 테니까.... setDeadline(0); } m_Period--; } else { return; // 큰 의미는 없지만.. } // 성향 단계가 바뀌면 다른 사람들에게도 알려줘야 한다. by sigi. 2002.12.28 Alignment beforeAlignment = g_pAlignmentManager->getAlignmentType(CurrentAlignment); Alignment afterAlignment = g_pAlignmentManager->getAlignmentType(NewAlignment); if (beforeAlignment!=afterAlignment) { GCOtherModifyInfo gcOtherModifyInfo; gcOtherModifyInfo.setObjectID(pCreature->getObjectID()); gcOtherModifyInfo.addShortData(MODIFY_ALIGNMENT, NewAlignment); Zone* pZone = pCreature->getZone(); // 2003.1.10 Assert(pZone!=NULL); pZone->broadcastPacket(pCreature->getX(), pCreature->getY(), &gcOtherModifyInfo, pCreature); } __END_CATCH }
void EffectBloodyWallBlocked::affect() throw(Error) { __BEGIN_TRY //cout << "EffectBloodyWallBlocked" << "affect BEGIN" << endl; Assert(m_pZone != NULL); // 현재 이펙트가 붙어있는 타일을 받아온다. Tile& tile = m_pZone->getTile(m_X, m_Y); HP_t CurrentHP = 0; HP_t RemainHP = 0; // 타일 안에 존재하는 오브젝트들을 검색한다. const list<Object*>& oList = tile.getObjectList(); list<Object*>::const_iterator itr = oList.begin(); for (; itr != oList.end(); itr++) { Assert(*itr != NULL); Object* pObject = *itr; Assert(pObject != NULL); if (pObject->getObjectClass() == Object::OBJECT_CLASS_CREATURE) { Creature* pCreature = dynamic_cast<Creature*>(pObject); Assert(pCreature != NULL); // 무적상태 체크. by sigi. 2002.9.5 // 산 면역. by sigi. 2002.9.13 if (!canAttack(NULL, pCreature ) || pCreature->isFlag(Effect::EFFECT_CLASS_IMMUNE_TO_BLOOD_DRAIN) || pCreature->isFlag(Effect::EFFECT_CLASS_COMA) || pCreature->isDead()) { continue; } int AcidDamage = computeMagicDamage(pCreature, m_Damage, SKILL_BLOODY_WALL); if (pCreature->getMoveMode() != Creature::MOVE_MODE_FLYING) { if (pCreature->isSlayer()) { Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature); CurrentHP = pSlayer->getHP(ATTR_CURRENT); RemainHP = max(0, CurrentHP -(int)AcidDamage); pSlayer->setHP(RemainHP, ATTR_CURRENT); GCModifyInformation gcMI; gcMI.addShortData(MODIFY_CURRENT_HP, pSlayer->getHP(ATTR_CURRENT)); Player* pPlayer = pSlayer->getPlayer(); Assert(pPlayer != NULL); pPlayer->sendPacket(&gcMI); // 변한 HP를 브로드캐스팅해준다. GCStatusCurrentHP pkt; pkt.setObjectID(pSlayer->getObjectID()); pkt.setCurrentHP(RemainHP); m_pZone->broadcastPacket(pSlayer->getX(), pSlayer->getY(), &pkt); } /* else if (pCreature->isVampire()) { Vampire* pVampire = dynamic_cast<Vampire*>(pCreature); CurrentHP = pVampire->getHP(ATTR_CURRENT); RemainHP = max(0, CurrentHP -(int)AcidDamage); pVampire->setHP(RemainHP, ATTR_CURRENT); GCModifyInformation gcMI; gcMI.addShortData(MODIFY_CURRENT_HP, pVampire->getHP(ATTR_CURRENT)); Player* pPlayer = pVampire->getPlayer(); Assert(pPlayer != NULL); pPlayer->sendPacket(&gcMI); // 변한 HP를 브로드캐스팅해준다. GCStatusCurrentHP pkt; pkt.setObjectID(pVampire->getObjectID()); pkt.setCurrentHP(RemainHP); m_pZone->broadcastPacket(pVampire->getX(), pVampire->getY(), &pkt); } */ else if (pCreature->isOusters()) { Ousters* pOusters = dynamic_cast<Ousters*>(pCreature); CurrentHP = pOusters->getHP(ATTR_CURRENT); RemainHP = max(0, CurrentHP -(int)AcidDamage); pOusters->setHP(RemainHP, ATTR_CURRENT); GCModifyInformation gcMI; gcMI.addShortData(MODIFY_CURRENT_HP, pOusters->getHP(ATTR_CURRENT)); Player* pPlayer = pOusters->getPlayer(); Assert(pPlayer != NULL); pPlayer->sendPacket(&gcMI); // 변한 HP를 브로드캐스팅해준다. GCStatusCurrentHP pkt; pkt.setObjectID(pOusters->getObjectID()); pkt.setCurrentHP(RemainHP); m_pZone->broadcastPacket(pOusters->getX(), pOusters->getY(), &pkt); } else if (pCreature->isMonster()) { Monster* pMonster = dynamic_cast<Monster*>(pCreature); CurrentHP = pMonster->getHP(ATTR_CURRENT); RemainHP = max(0, CurrentHP -(int)AcidDamage); pMonster->setHP(RemainHP, ATTR_CURRENT); if(m_CasterName != "" ) { // 시전자의 데미지를 추가해 준다. // 맞는 놈이 몬스터이고, 공격자가 사람이라면, // 데미지에 따라서 변하는 우선권 테이블을 갱신해 주어야 한다. pMonster->addPrecedence(m_CasterName, m_PartyID, AcidDamage); pMonster->setLastHitCreatureClass(Creature::CREATURE_CLASS_VAMPIRE); } // 변한 HP를 브로드캐스팅해준다. GCStatusCurrentHP pkt; pkt.setObjectID(pMonster->getObjectID()); pkt.setCurrentHP(RemainHP); m_pZone->broadcastPacket(pMonster->getX(), pMonster->getY(), &pkt); } // m_CasterName이 pCreature를 죽인 경우의 KillCount 처리 // by sigi. 2002.8.31 if (pCreature->isDead()) { Creature* pAttacker = m_pZone->getCreature(m_CasterName); if (pAttacker!=NULL) { affectKillCount(pAttacker, pCreature); } } } } } // 한번만.. //setNextTime(m_Tick); //cout << "EffectBloodyWallBlocked" << "affect END" << endl; __END_CATCH }
void EffectCureCriticalWounds::affect(Creature* pCreature) throw(Error) { __BEGIN_TRY Zone* pZone = pCreature->getZone(); Assert(pZone != NULL); GCSkillToSelfOK1 _GCSkillToSelfOK1; GCSkillToSelfOK2 _GCSkillToSelfOK2; int X = pCreature->getX(); int Y = pCreature->getY(); Exp_t ExpUp = 0; bool bCured = false; for(int oY = -2; oY <= 2; oY++) for(int oX = -2; oX <= 2; oX++) { int tileX = X+oX; int tileY = Y+oY; if (isValidZoneCoord(pZone, tileX, tileY)) { Tile& tile = pZone->getTile(tileX, tileY); if (tile.hasCreature(Creature::MOVE_MODE_WALKING ) ) { const list<Object*>& oList = tile.getObjectList(); for(list<Object*>::const_iterator itr = oList.begin(); itr != oList.end(); itr++) { Object* pTarget = *itr; Creature* pTargetCreature = NULL; if (pTarget->getObjectClass() == Object::OBJECT_CLASS_CREATURE && (pTargetCreature = dynamic_cast<Creature*>(pTarget))->isSlayer()) { Assert(pTargetCreature != NULL); HP_t RemainHP = 0; if (pTargetCreature->isSlayer() && !pTargetCreature->isFlag(Effect::EFFECT_CLASS_COMA) ) { Slayer* pSlayer = dynamic_cast<Slayer*>(pTargetCreature); HP_t CurrentHP = pSlayer->getHP(ATTR_CURRENT); HP_t MaxHP = pSlayer->getHP(ATTR_MAX); if (pTargetCreature->isFlag(Effect::EFFECT_CLASS_BLOOD_DRAIN)) { ExpUp++; Effect* pEffect = pSlayer->findEffect(Effect::EFFECT_CLASS_BLOOD_DRAIN); EffectBloodDrain * pEffectBloodDrain = dynamic_cast<EffectBloodDrain*>(pEffect); Assert(pEffectBloodDrain != NULL); if (pEffectBloodDrain->getLevel() < CriticalBloodDrainLevel ) { // 흡혈 아르바이트를 방지하기 위한 후유증 이펙트를 붙여준다. if (pSlayer->isFlag(Effect::EFFECT_CLASS_AFTERMATH)) { Effect* pEffect = pSlayer->findEffect(Effect::EFFECT_CLASS_AFTERMATH); EffectAftermath* pEffectAftermath = dynamic_cast<EffectAftermath*>(pEffect); pEffectAftermath->setDeadline(5*600); // 5분 동안 지속된다. } else { EffectAftermath* pEffectAftermath = new EffectAftermath(pSlayer); pEffectAftermath->setDeadline(5*600); // 5분 동안 지속된다. pSlayer->addEffect(pEffectAftermath); pSlayer->setFlag(Effect::EFFECT_CLASS_AFTERMATH); pEffectAftermath->create(pSlayer->getName()); } pEffectBloodDrain->destroy(pSlayer->getName()); pSlayer->deleteEffect(Effect::EFFECT_CLASS_BLOOD_DRAIN); bCured = true; SLAYER_RECORD prev; pSlayer->getSlayerRecord(prev); pSlayer->initAllStat(); pSlayer->sendRealWearingInfo(); pSlayer->sendModifyInfo(prev); GCRemoveEffect gcRemoveEffect; gcRemoveEffect.setObjectID(pSlayer->getObjectID()); gcRemoveEffect.addEffectList((EffectID_t)Effect::EFFECT_CLASS_BLOOD_DRAIN); pZone->broadcastPacket(pSlayer->getX(), pSlayer->getY(), &gcRemoveEffect); } } if(CurrentHP < MaxHP ) { ExpUp++; bCured = true; RemainHP = min(CurrentHP + m_Point,(int)MaxHP); pSlayer->setHP(RemainHP, ATTR_CURRENT); GCModifyInformation gcMI; gcMI.addShortData(MODIFY_CURRENT_HP, RemainHP); pSlayer->getPlayer()->sendPacket(&gcMI); _GCSkillToSelfOK1.setSkillType(SKILL_CURE_EFFECT); _GCSkillToSelfOK1.setDuration(0); pSlayer->getPlayer()->sendPacket(&_GCSkillToSelfOK1); _GCSkillToSelfOK2.setObjectID(pSlayer->getObjectID()); _GCSkillToSelfOK2.setSkillType(SKILL_CURE_EFFECT); _GCSkillToSelfOK2.setDuration(0); pZone->broadcastPacket(pTargetCreature->getX(), pTargetCreature->getY(), &_GCSkillToSelfOK2, pTargetCreature); Zone* pZone = pTargetCreature->getZone(); GCStatusCurrentHP gcStatusCurrentHP; gcStatusCurrentHP.setObjectID(pTargetCreature->getObjectID()); gcStatusCurrentHP.setCurrentHP(RemainHP); pZone->broadcastPacket(pTargetCreature->getX(), pTargetCreature->getY(), &gcStatusCurrentHP); } } } } } } } SkillInfo * pSkillInfo = g_pSkillInfoManager->getSkillInfo(SKILL_CURE_CRITICAL_WOUNDS); if(pSkillInfo != NULL && bCured ) { SkillSlot * pSkillSlot = ((Slayer*)pCreature)->hasSkill(SKILL_CURE_CRITICAL_WOUNDS); if(pSkillSlot != NULL ) { Slayer * pCastSlayer = dynamic_cast<Slayer*>(pCreature); GCModifyInformation gcMI; SkillDomainType_t DomainType = pSkillInfo->getDomainType(); // 경험치를 올려준다. shareAttrExp(pCastSlayer, ExpUp, 1 , 1 , 8, gcMI); increaseDomainExp(pCastSlayer, DomainType, ExpUp, gcMI); increaseSkillExp(pCastSlayer, DomainType, pSkillSlot, pSkillInfo, gcMI); pCastSlayer->getPlayer()->sendPacket(&gcMI); } } //cout << "EffectCureCriticalWounds " << "affect BEGIN" << endl; setNextTime(m_Delay); //cout << "EffectCureCriticalWounds " << "affect END" << endl; __END_CATCH }
void ActionHeal::execute (Creature * pCreature1 , Creature * pCreature2) throw(Error) { __BEGIN_TRY Assert(pCreature1 != NULL); Assert(pCreature2 != NULL); Assert(pCreature1->isNPC()); Assert(pCreature2->isPC()); Player* pPlayer = pCreature2->getPlayer(); Zone* pZone = pCreature2->getZone(); Assert(pPlayer != NULL); // 일단 클라이언트를 위해서 OK 패킷을 함 날린다. GCNPCResponse okpkt; okpkt.setCode(NPC_RESPONSE_HEAL); pPlayer->sendPacket(&okpkt); // 죽었거나 코마 걸려있으면 안 치료해준다. if (pCreature2->isDead() || pCreature2->isFlag(Effect::EFFECT_CLASS_COMA ) ) { return; } // 슬레이어라면... if (pCreature2->isSlayer()) { Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature2); EffectManager* pEffectManager = pSlayer->getEffectManager(); GCModifyInformation modifyPkt; GCRemoveEffect removePkt; GCStatusCurrentHP hpPkt; // 먼저 HP랑 MP를 풀로 채워준다. if (pSlayer->getHP(ATTR_CURRENT) < pSlayer->getHP(ATTR_MAX)) { pSlayer->setHP(pSlayer->getHP(ATTR_MAX), ATTR_CURRENT); modifyPkt.addShortData(MODIFY_CURRENT_HP, pSlayer->getHP(ATTR_CURRENT)); hpPkt.setObjectID(pSlayer->getObjectID()); hpPkt.setCurrentHP(pSlayer->getHP(ATTR_CURRENT)); } if (pSlayer->getMP(ATTR_CURRENT) < pSlayer->getMP(ATTR_MAX)) { pSlayer->setMP(pSlayer->getMP(ATTR_MAX), ATTR_CURRENT); modifyPkt.addShortData(MODIFY_CURRENT_MP, pSlayer->getMP(ATTR_CURRENT)); } // 흡혈 이펙트를 삭제한다. Effect* pBloodDrainEffect = pEffectManager->findEffect(Effect::EFFECT_CLASS_BLOOD_DRAIN); if (pBloodDrainEffect != NULL) { // DB에서 삭제하고, 이펙트 매니저에서 삭제한다. pBloodDrainEffect->destroy(pSlayer->getName()); pEffectManager->deleteEffect(pSlayer, Effect::EFFECT_CLASS_BLOOD_DRAIN); // 흡혈 아르바이트를 방지하기 위한 후유증 이펙트를 붙여준다. if (pSlayer->isFlag(Effect::EFFECT_CLASS_AFTERMATH)) { Effect* pEffect = pEffectManager->findEffect(Effect::EFFECT_CLASS_AFTERMATH); EffectAftermath* pEffectAftermath = dynamic_cast<EffectAftermath*>(pEffect); pEffectAftermath->setDeadline(5*600); // 5분 동안 지속된다. } else { EffectAftermath* pEffectAftermath = new EffectAftermath(pSlayer); pEffectAftermath->setDeadline(5*600); // 5분 동안 지속된다. pEffectManager->addEffect(pEffectAftermath); pSlayer->setFlag(Effect::EFFECT_CLASS_AFTERMATH); pEffectAftermath->create(pSlayer->getName()); } // 패킷에다 정보를 더한다. removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_BLOOD_DRAIN); // 흡혈을 치료하면 능력치가 변화하게 된다. SLAYER_RECORD prev; pSlayer->getSlayerRecord(prev); pSlayer->initAllStat(); pSlayer->sendModifyInfo(prev); pSlayer->sendRealWearingInfo(); } // 독 이펙트를 삭제한다. Effect* pEffectPoison = pEffectManager->findEffect(Effect::EFFECT_CLASS_POISON); if (pEffectPoison != NULL) { // 이펙트 매니저에서 삭제한다. pEffectManager->deleteEffect(pSlayer, Effect::EFFECT_CLASS_POISON); // 패킷에다 정보를 더한다. removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_POISON); } // 다크블루 포이즌 이펙트를 삭제한다. Effect* pEffectDarkBluePoison = pEffectManager->findEffect(Effect::EFFECT_CLASS_DARKBLUE_POISON); if (pEffectDarkBluePoison != NULL) { // 이펙트 매니저에서 삭제한다. pEffectManager->deleteEffect(pSlayer, Effect::EFFECT_CLASS_DARKBLUE_POISON); // 패킷에다 정보를 더한다. removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_DARKBLUE_POISON); } // 패킷 날려준다. removePkt.setObjectID(pSlayer->getObjectID()); pPlayer->sendPacket(&modifyPkt); pZone->broadcastPacket(pSlayer->getX(), pSlayer->getY(), &removePkt); pZone->broadcastPacket(pSlayer->getX(), pSlayer->getY(), &hpPkt, pSlayer); //log(LOG_HEAL, pSlayer->getName(), ""); } else if (pCreature2->isVampire()) { Vampire* pVampire = dynamic_cast<Vampire*>(pCreature2); //EffectManager* pEffectManager = pVampire->getEffectManager(); GCModifyInformation modifyPkt; GCRemoveEffect removePkt; GCStatusCurrentHP hpPkt; // HP 채워주고... if (pVampire->getHP(ATTR_CURRENT) < pVampire->getHP(ATTR_MAX)) { pVampire->setHP(pVampire->getHP(ATTR_MAX), ATTR_CURRENT); modifyPkt.addShortData(MODIFY_CURRENT_HP, pVampire->getHP(ATTR_CURRENT)); hpPkt.setObjectID(pVampire->getObjectID()); hpPkt.setCurrentHP(pVampire->getHP(ATTR_CURRENT)); } // 패킷 날려준다. removePkt.setObjectID(pVampire->getObjectID()); pPlayer->sendPacket(&modifyPkt); pZone->broadcastPacket(pVampire->getX(), pVampire->getY(), &removePkt); pZone->broadcastPacket(pVampire->getX(), pVampire->getY(), &hpPkt, pVampire); //log(LOG_HEAL, pVampire->getName(), ""); } else if (pCreature2->isOusters()) { Ousters* pOusters = dynamic_cast<Ousters*>(pCreature2); EffectManager* pEffectManager = pOusters->getEffectManager(); GCModifyInformation modifyPkt; GCRemoveEffect removePkt; GCStatusCurrentHP hpPkt; // 먼저 HP랑 MP를 풀로 채워준다. if (pOusters->getHP(ATTR_CURRENT) < pOusters->getHP(ATTR_MAX) || pOusters->getSilverDamage() != 0 ) { Silver_t prev = pOusters->getSilverDamage(); if (prev != 0 ) { pOusters->setSilverDamage(0); modifyPkt.addShortData(MODIFY_SILVER_DAMAGE, pOusters->getSilverDamage()); } pOusters->setHP(pOusters->getHP(ATTR_MAX), ATTR_CURRENT); modifyPkt.addShortData(MODIFY_CURRENT_HP, pOusters->getHP(ATTR_CURRENT)); hpPkt.setObjectID(pOusters->getObjectID()); hpPkt.setCurrentHP(pOusters->getHP(ATTR_CURRENT)); } if (pOusters->getMP(ATTR_CURRENT) < pOusters->getMP(ATTR_MAX)) { pOusters->setMP(pOusters->getMP(ATTR_MAX), ATTR_CURRENT); modifyPkt.addShortData(MODIFY_CURRENT_MP, pOusters->getMP(ATTR_CURRENT)); } // 독 이펙트를 삭제한다. Effect* pEffectPoison = pEffectManager->findEffect(Effect::EFFECT_CLASS_POISON); if (pEffectPoison != NULL) { // 이펙트 매니저에서 삭제한다. pEffectManager->deleteEffect(pOusters, Effect::EFFECT_CLASS_POISON); // 패킷에다 정보를 더한다. removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_POISON); } // 다크블루 포이즌 이펙트를 삭제한다. Effect* pEffectDarkBluePoison = pEffectManager->findEffect(Effect::EFFECT_CLASS_DARKBLUE_POISON); if (pEffectDarkBluePoison != NULL) { // 이펙트 매니저에서 삭제한다. pEffectManager->deleteEffect(pOusters, Effect::EFFECT_CLASS_DARKBLUE_POISON); // 패킷에다 정보를 더한다. removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_DARKBLUE_POISON); } // 흡혈 이펙트를 삭제한다. Effect* pBloodDrainEffect = pEffectManager->findEffect(Effect::EFFECT_CLASS_BLOOD_DRAIN); if (pBloodDrainEffect != NULL) { pBloodDrainEffect->setDeadline(0); // 흡혈 아르바이트를 방지하기 위한 후유증 이펙트를 붙여준다. if (pOusters->isFlag(Effect::EFFECT_CLASS_AFTERMATH)) { Effect* pEffect = pEffectManager->findEffect(Effect::EFFECT_CLASS_AFTERMATH); EffectAftermath* pEffectAftermath = dynamic_cast<EffectAftermath*>(pEffect); pEffectAftermath->setDeadline(5*600); // 5분 동안 지속된다. } else { EffectAftermath* pEffectAftermath = new EffectAftermath(pOusters); pEffectAftermath->setDeadline(5*600); // 5분 동안 지속된다. pEffectManager->addEffect(pEffectAftermath); pOusters->setFlag(Effect::EFFECT_CLASS_AFTERMATH); pEffectAftermath->create(pOusters->getName()); } // 패킷에다 정보를 더한다. removePkt.addEffectList((EffectID_t)Effect::EFFECT_CLASS_BLOOD_DRAIN); } // 패킷 날려준다. removePkt.setObjectID(pOusters->getObjectID()); pPlayer->sendPacket(&modifyPkt); pZone->broadcastPacket(pOusters->getX(), pOusters->getY(), &removePkt); pZone->broadcastPacket(pOusters->getX(), pOusters->getY(), &hpPkt, pOusters); //log(LOG_HEAL, pOusters->getName(), ""); } __END_CATCH }
//////////////////////////////////////////////////////////////////////////////// // 액션을 실행한다. //////////////////////////////////////////////////////////////////////////////// void ActionRegisterSiege::execute (Creature * pCreature1 , Creature * pCreature2) throw(Error) { __BEGIN_TRY #ifndef __OLD_GUILD_WAR__ Assert(pCreature1 != NULL); Assert(pCreature2 != NULL); Assert(pCreature1->isNPC()); Assert(pCreature2->isPC()); SYSTEM_RETURN_IF_NOT(SYSTEM_GUILD_WAR); GCNPCResponse gcNPCResponse; PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pCreature2); GuildID_t guildID = pPC->getGuildID(); if (!g_pVariableManager->isWarActive() || !g_pVariableManager->isActiveGuildWar() ) { gcNPCResponse.setCode(NPC_RESPONSE_WAR_UNAVAILABLE); pPC->getPlayer()->sendPacket(&gcNPCResponse); return; } if (!g_pGuildManager->isGuildMaster(guildID, pPC ) ) { gcNPCResponse.setCode(NPC_RESPONSE_NOT_GUILD_MASTER); pPC->getPlayer()->sendPacket(&gcNPCResponse); return; } Gold_t warRegistrationFee = g_pVariableManager->getVariable(WAR_REGISTRATION_FEE); if (pPC->getGold() < warRegistrationFee ) { gcNPCResponse.setCode(NPC_RESPONSE_NOT_ENOUGH_MONEY); pPC->getPlayer()->sendPacket(&gcNPCResponse); return; } Zone* pZone = getZoneByZoneID(m_ZoneID); Assert(pZone != NULL); Assert(pZone->isCastle()); WarScheduler* pWarScheduler = pZone->getWarScheduler(); Assert(pWarScheduler != NULL); /* 성을 소유했어도 전쟁 신청이 되도록 수정함 (자기 성에는 신청 못하겠지 -_-;;) // 이미 성을 소유한 길드인가? if (g_pGuildManager->hasCastle(guildID ) ) { gcNPCResponse.setCode(NPC_RESPONSE_ALREADY_HAS_CASTLE); pPC->getPlayer()->sendPacket(&gcNPCResponse); return; } */ // ServerID_t serverID; // ZoneID_t zoneID; // bool bHasCastle = g_pGuildManager->hasCastle(guildID , serverID , zoneID); // if (bHasCastle && serverID == g_pConfig->getPropertyInt("ServerID" ) && zoneID == m_ZoneID ) CastleInfo* pCastleInfo = g_pCastleInfoManager->getCastleInfo(m_ZoneID); GuildID_t ownerGuildID = pCastleInfo->getGuildID(); if (guildID == ownerGuildID ) { gcNPCResponse.setCode(NPC_RESPONSE_ALREADY_HAS_CASTLE); pPC->getPlayer()->sendPacket(&gcNPCResponse); return; } // 이미 전쟁 신청을 했는가? if (g_pGuildManager->hasWarSchedule(guildID ) ) { gcNPCResponse.setCode(NPC_RESPONSE_WAR_ALREADY_REGISTERED); pPC->getPlayer()->sendPacket(&gcNPCResponse); return; } // 전쟁 스케쥴이 다 찼는가? /* if (!pWarScheduler->canAddWar(WAR_GUILD ) ) { gcNPCResponse.setCode(NPC_RESPONSE_WAR_SCHEDULE_FULL); pPC->getPlayer()->sendPacket(&gcNPCResponse); return; } GuildWar* pWar = new GuildWar(m_ZoneID, guildID, War::WAR_STATE_WAIT); pWar->setRegistrationFee(warRegistrationFee); if (!pWarScheduler->addWar(pWar ) ) { gcNPCResponse.setCode(NPC_RESPONSE_WAR_SCHEDULE_FULL); pPC->getPlayer()->sendPacket(&gcNPCResponse); SAFE_DELETE(pWar); return; }*/ Schedule* pNextSchedule = pWarScheduler->getRecentSchedule(); Work* pNextWork = NULL; if (pNextSchedule != NULL ) pNextWork = pNextSchedule->getWork(); SiegeWar* pNextWar = dynamic_cast<SiegeWar*>(pNextWork); if (pNextWar == NULL ) { pNextWar = new SiegeWar(m_ZoneID, War::WAR_STATE_WAIT); pNextWar->addRegistrationFee(warRegistrationFee); pNextWar->addChallengerGuild(guildID); if (!pWarScheduler->addWar(pNextWar ) ) { gcNPCResponse.setCode(NPC_RESPONSE_WAR_SCHEDULE_FULL); pPC->getPlayer()->sendPacket(&gcNPCResponse); SAFE_DELETE(pNextWar); return; } } else if (pNextWar->getChallengerGuildCount() < 5 ) { WarSchedule* pNextWarSchedule = dynamic_cast<WarSchedule*>(pNextSchedule); Assert(pNextWarSchedule != NULL); pNextWar->addRegistrationFee(warRegistrationFee); pNextWar->addChallengerGuild(guildID); pNextWarSchedule->save(); } else { gcNPCResponse.setCode(NPC_RESPONSE_WAR_SCHEDULE_FULL); pPC->getPlayer()->sendPacket(&gcNPCResponse); // SAFE_DELETE(pNextWar); return; } pPC->decreaseGoldEx(warRegistrationFee); GCModifyInformation gcMI; gcMI.addLongData(MODIFY_GOLD, pPC->getGold()); pPC->getPlayer()->sendPacket(&gcMI); gcNPCResponse.setCode(NPC_RESPONSE_WAR_REGISTRATION_OK); pPC->getPlayer()->sendPacket(&gcNPCResponse); return; #endif __END_CATCH }
//---------------------------------------------------------------------- // // 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 CGDownSkillHandler::execute (CGDownSkill* pPacket , Player* pPlayer) throw(ProtocolException, Error) { __BEGIN_TRY __BEGIN_DEBUG_EX #ifdef __GAME_SERVER__ Assert(pPacket != NULL); Assert(pPlayer != NULL); GamePlayer* pGamePlayer = dynamic_cast<GamePlayer*>(pPlayer); Assert(pGamePlayer != NULL); PlayerCreature* pPC = dynamic_cast<PlayerCreature*>(pGamePlayer->getCreature()); Assert(pPC != NULL); SkillType_t targetSkillType = pPacket->getSkillType(); GCDownSkillFailed failpkt; failpkt.setSkillType(targetSkillType); if (!pPC->isOusters() ) { failpkt.setDesc(NOT_OUSTERS); pPlayer->sendPacket(&failpkt); return; } Ousters* pOusters = dynamic_cast<Ousters*>(pPC); Assert(pOusters != NULL); OustersSkillSlot* pTargetSkillSlot = pOusters->getSkill(targetSkillType); if (pTargetSkillSlot == NULL ) { failpkt.setDesc(HAVE_NOT_SKILL); pPlayer->sendPacket(&failpkt); return; } SkillInfo* pTargetSkillInfo = NULL; try { pTargetSkillInfo = g_pSkillInfoManager->getSkillInfo(targetSkillType); } catch(Exception& e) { failpkt.setDesc(INVALID_SKILL); pPlayer->sendPacket(&failpkt); return; } if (pTargetSkillSlot->getExpLevel() <= 1 ) { if (!pTargetSkillInfo->canDelete() ) { failpkt.setDesc(TOO_LOW); pPlayer->sendPacket(&failpkt); return; } list<SkillType_t>& rRequiredSkills = pTargetSkillInfo->getRequiredSkills(); list<SkillType_t>::iterator itr = rRequiredSkills.begin(); for (; itr != rRequiredSkills.end(); ++itr ) { if (pOusters->hasSkill(*itr) != NULL ) { bool canDrop = false; SkillInfo* pFollowingSkillInfo = g_pSkillInfoManager->getSkillInfo(*itr); list<SkillType_t>& rRequireSkills = pFollowingSkillInfo->getRequireSkills(); list<SkillType_t>::iterator itr2 = rRequireSkills.begin(); for (; itr2 != rRequireSkills.end(); ++itr2 ) { if ((*itr2) != targetSkillType && pOusters->hasSkill(*itr2) != NULL ) { SkillInfo* pAlternativeSkillInfo = g_pSkillInfoManager->getSkillInfo(*itr2); if (getSkillMapID((ElementalDomain)pAlternativeSkillInfo->getElementalDomain()) == getSkillMapID((ElementalDomain)pTargetSkillInfo->getElementalDomain()) ) canDrop = true; } } if (!canDrop ) { failpkt.setDesc(CANNOT_DROP_SKILL); pPlayer->sendPacket(&failpkt); return; } } } } /* if (pTargetSkillSlot->getExpLevel() >= 30 ) { failpkt.setDesc(TOO_HIGH); pPlayer->sendPacket(&failpkt); return; }*/ Assert(pTargetSkillInfo != NULL); int backPoint = pTargetSkillInfo->getLevelUpPoint(); Price_t downPrice = (int)(backPoint * pow(pOusters->getLevel(),1.3) * 200); if (pTargetSkillSlot->getExpLevel() <= 1 ) { downPrice *= 5; if (downPrice == 0 ) downPrice = 1000000; } if (pOusters->getGold() < downPrice ) { failpkt.setDesc(NOT_ENOUGH_MONEY); pPlayer->sendPacket(&failpkt); return; } pOusters->decreaseGoldEx(downPrice); pTargetSkillSlot->setExpLevel(pTargetSkillSlot->getExpLevel() - 1); pTargetSkillSlot->save(); if (pTargetSkillSlot->getExpLevel() <= 0 ) { pTargetSkillSlot->destroy(pOusters->getName()); backPoint = pTargetSkillInfo->getSkillPoint(); pOusters->removeSkill(targetSkillType); } pOusters->setSkillBonus(pOusters->getSkillBonus() + backPoint); char query[50]; sprintf(query, "SkillBonus=%d", pOusters->getSkillBonus()); pOusters->tinysave(query); GCDownSkillOK okpkt; okpkt.setSkillType(targetSkillType); pPlayer->sendPacket(&okpkt); GCModifyInformation gcMI; gcMI.addLongData(MODIFY_GOLD, pOusters->getGold()); gcMI.addShortData(MODIFY_SKILL_BONUS_POINT, pOusters->getSkillBonus()); switch (targetSkillType ) { case SKILL_HIDE_SIGHT: { OUSTERS_RECORD prev; pOusters->getOustersRecord(prev); pOusters->initAllStat(); pOusters->sendRealWearingInfo(); pOusters->addModifyInfo(prev, gcMI); } break; default : break; } pPlayer->sendPacket(&gcMI); #endif // __GAME_SERVER__ __END_DEBUG_EX __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) } }