void EffectSpiritGuard::affect(Creature* pCastCreature) throw(Error) { __BEGIN_TRY Assert(pCastCreature != NULL); if (!pCastCreature->isSlayer() ) return; Player* pPlayer = dynamic_cast<Player*>(pCastCreature->getPlayer()); Assert(pPlayer != NULL); Slayer* pSlayer = dynamic_cast<Slayer*>(pCastCreature); Assert(pSlayer != NULL); SkillInfo* pSkillInfo = g_pSkillInfoManager->getSkillInfo(SKILL_SPIRIT_GUARD); if (pSkillInfo == NULL ) { return; } GCModifyInformation gcAttackerMI; Zone* pZone = pCastCreature->getZone(); Assert(pZone != NULL); VSRect rect(0, 0, pZone->getWidth()-1, pZone->getHeight()-1); ZoneCoord_t Cx = pCastCreature->getX(); ZoneCoord_t Cy = pCastCreature->getY(); bool isHit = false; Level_t maxEnemyLevel = 0; uint EnemyNum = 0; for (int x=-1; x<=1; x++ ) { for (int y=-1; y<=1; y++ ) { if (x == 0 && y == 0 ) continue; int X = Cx + x; int Y = Cy + y; if (!rect.ptInRect(X, Y ) ) continue; // 타일안에 존재하는 오브젝트를 가져온다. Tile& tile = pZone->getTile(X, Y); if(tile.hasCreature(Creature::MOVE_MODE_WALKING) ) { Creature* pCreature = tile.getCreature(Creature::MOVE_MODE_WALKING); Assert(pCreature != NULL); // 자신은 맞지 않는다. 무적도 안 맞는다. 슬레이어도 안 맞느다. // 안전지대 체크 // 2003.1.10 by bezz, Sequoia if (pCreature == m_pTarget || !canAttack(pCastCreature, pCreature ) || pCreature->isFlag(Effect::EFFECT_CLASS_COMA ) || pCreature->isSlayer() || pCreature->isNPC() || !checkZoneLevelToHitTarget(pCreature) ) { continue; } isHit = true; if (maxEnemyLevel < pCreature->getLevel() ) maxEnemyLevel = pCreature->getLevel(); EnemyNum++; if (pCreature->isVampire() || pCreature->isOusters() ) { // Vampire* pVampire = dynamic_cast<Vampire*>(pCreature); GCModifyInformation gcMI; ::setDamage(pCreature, m_Damage, pCastCreature, SKILL_SPIRIT_GUARD, &gcMI, &gcAttackerMI); pCreature->getPlayer()->sendPacket(&gcMI); // 맞는 동작을 보여준다. GCSkillToObjectOK2 gcSkillToObjectOK2; gcSkillToObjectOK2.setObjectID(1); // 의미 없다. gcSkillToObjectOK2.setSkillType(SKILL_ATTACK_MELEE); gcSkillToObjectOK2.setDuration(0); pCreature->getPlayer()->sendPacket(&gcSkillToObjectOK2); } else if (pCreature->isMonster() ) { Monster* pMonster = dynamic_cast<Monster*>(pCreature); ::setDamage(pMonster, m_Damage, pCastCreature, SKILL_SPIRIT_GUARD, NULL, &gcAttackerMI); pMonster->addEnemy(pCastCreature); } else Assert(false); GCSkillToObjectOK4 gcSkillToObjectOK4; gcSkillToObjectOK4.setSkillType(SKILL_ATTACK_MELEE); gcSkillToObjectOK4.setTargetObjectID(pCreature->getObjectID()); gcSkillToObjectOK4.setDuration(0); pZone->broadcastPacket(X, Y, &gcSkillToObjectOK4, pCreature); } } } if (isHit ) { SkillDomainType_t DomainType = pSkillInfo->getDomainType(); SkillSlot* pSkillSlot = pSlayer->getSkill(SKILL_SPIRIT_GUARD); if (pSkillSlot != NULL ) { increaseDomainExp(pSlayer, DomainType, pSkillInfo->getPoint(), gcAttackerMI, maxEnemyLevel, EnemyNum); increaseSkillExp(pSlayer, DomainType, pSkillSlot, pSkillInfo, gcAttackerMI); } } setNextTime(m_Delay); __END_CATCH }