本文整理汇总了C++中Zone::getTile方法的典型用法代码示例。如果您正苦于以下问题:C++ Zone::getTile方法的具体用法?C++ Zone::getTile怎么用?C++ Zone::getTile使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Zone
的用法示例。
在下文中一共展示了Zone::getTile方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: unaffect
//----------------------------------------------------------------------
// remove effect from target
//----------------------------------------------------------------------
void EffectCallMotorcycle::unaffect (Motorcycle* pMotorcycle, Slayer* pSlayer)
throw(Error)
{
__BEGIN_TRY
// Slayer의 정보(Zone, x, y)를 구한다.
Zone* pZone = pSlayer->getZone();
Coord_t x = pSlayer->getX();
Coord_t y = pSlayer->getY();
// Slayer의 정보가 유효한지 검사한다.
// 존의 타일 정보를 가져온다.
Tile & tile = pZone->getTile(x, y);
// 만약 해당 존에 아이템이 있다면??
if(tile.hasItem())
{
}
else
{
pZone->addItem(pMotorcycle, x, y);
// 아이템이 이동했다는 패킷을 날린다.
}
__END_CATCH
}
示例2: affect
void EffectDestinies::affect()
throw(Error)
{
__BEGIN_TRY
setDeadline(0);
Creature* pCaster = dynamic_cast<Creature*>(m_pTarget);
int cx = pCaster->getX();
int cy = pCaster->getY();
Zone* pZone = pCaster->getZone();
for (int i=-8; i<=8; ++i )
for (int j=-8; j<=8; ++j )
{
int tx = cx + i;
int ty = cy + j;
if (tx < 0 || ty < 0 ) continue;
if (!isValidZoneCoord(pZone, tx, ty ) ) continue;
list<Object*>& olist = pZone->getTile(tx, ty).getObjectList();
list<Object*>::iterator itr = olist.begin();
for (; itr != olist.end() ; ++itr )
{
Object* pObject = *itr;
if (pObject == NULL || pObject->getObjectClass() != Object::OBJECT_CLASS_CREATURE ) continue;
Creature* pCreature = dynamic_cast<Creature*>(pObject);
if (pCreature == NULL ) continue;
bool isTarget = false;
if (pCreature->getCreatureClass() == m_TargetClass )
{
isTarget = true;
if (m_TargetClass == Creature::CREATURE_CLASS_MONSTER )
{
Monster* pTargetMonster = dynamic_cast<Monster*>(pCreature);
if (pTargetMonster->getSpriteType() != m_TargetSpriteType ) isTarget = false;
}
}
if (isTarget ) affect(pCreature);
}
}
//cout << "EffectDestinies" << "affect BEGIN" << endl;
__END_CATCH
}
示例3: execute
void Mephisto::execute(Vampire* pVampire)
throw(Error)
{
__BEGIN_TRY
//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " Begin(slayerself)" << endl;
Assert(pVampire != NULL);
if(!pVampire->hasSkill(SKILL_MEPHISTO) ) return;
try
{
Player* pPlayer = pVampire->getPlayer();
Zone* pZone = pVampire->getZone();
Assert(pPlayer != NULL);
Assert(pZone != NULL);
GCSkillToObjectOK1 _GCSkillToObjectOK1;
GCSkillToObjectOK2 _GCSkillToObjectOK2;
GCSkillToObjectOK3 _GCSkillToObjectOK3;
ZoneCoord_t myX = pVampire->getX();
ZoneCoord_t myY = pVampire->getY();
int oX, oY;
VSRect rect(0, 0, pZone->getWidth()-1, pZone->getHeight()-1);
for(oX = -4; oX <= 4; oX++)
for(oY = -4; oY <= 4; oY++)
{
int tileX = myX+oX;
int tileY = myY+oY;
if (!rect.ptInRect(tileX, tileY)) continue;
// 타일 위에! 뱀파이어가 있는지 본다!
Tile& tile = pZone->getTile(tileX, tileY);
Creature * pTargetCreature = NULL;
if(tile.hasCreature(Creature::MOVE_MODE_WALKING)) pTargetCreature = tile.getCreature(Creature::MOVE_MODE_WALKING);
if(pTargetCreature != NULL && pTargetCreature != pVampire && pTargetCreature->isVampire() ) {
bool bEffected = pTargetCreature->isFlag(Effect::EFFECT_CLASS_MEPHISTO);
if(bEffected ) continue;
Vampire* pTargetVampire= dynamic_cast<Vampire*>(pTargetCreature);
// 스킬 레벨에 따라 데미지 보너스가 달라진다.
SkillInput input(pVampire);
SkillOutput output;
input.SkillLevel = pVampire->getSTR()+pVampire->getDEX()+pVampire->getINT();
input.DomainLevel = pVampire->getLevel();
computeOutput(input, output);
// 이펙트 클래스를 만들어 붙인다.
EffectMephisto* pEffect = new EffectMephisto(pTargetVampire);
pEffect->setDeadline(output.Duration);
pEffect->setBonus(output.Damage);
pTargetVampire->addEffect(pEffect);
pTargetVampire->setFlag(Effect::EFFECT_CLASS_MEPHISTO);
// 이로 인하여 바뀌는 능력치를 보낸다.
VAMPIRE_RECORD prev;
pTargetVampire->getVampireRecord(prev);
pTargetVampire->initAllStat();
pTargetVampire->sendRealWearingInfo();
pTargetVampire->sendModifyInfo(prev);
if (pTargetCreature->isPC())
{
Player* pTargetPlayer = pTargetCreature->getPlayer();
Assert(pTargetPlayer != NULL);
pTargetPlayer->sendPacket(&_GCSkillToObjectOK2);
}
else
{
Assert(false);
}
// 이펙트가 붙었다고 알려준다.
GCAddEffect gcAddEffect;
gcAddEffect.setObjectID(pTargetVampire->getObjectID());
gcAddEffect.setEffectID(Effect::EFFECT_CLASS_MEPHISTO);
gcAddEffect.setDuration(output.Duration);
pZone->broadcastPacket(pTargetVampire->getX(), pTargetVampire->getY(), &gcAddEffect);
}
}
}
catch (Throwable & t)
{
executeSkillFailException(pVampire, getSkillType());
}
//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End(slayerself)" << endl;
__END_CATCH
//.........这里部分代码省略.........
示例4: execute
//////////////////////////////////////////////////////////////////////////////
// 뱀파이어 타일 핸들러
//////////////////////////////////////////////////////////////////////////////
void IceField::execute(Ousters* pOusters, ZoneCoord_t X, ZoneCoord_t Y, OustersSkillSlot* pOustersSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
__BEGIN_TRY
//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " Begin" << endl;
Assert(pOusters != NULL);
Assert(pOustersSkillSlot != NULL);
try
{
Player* pPlayer = pOusters->getPlayer();
Zone* pZone = pOusters->getZone();
Assert(pPlayer != NULL);
Assert(pZone != NULL);
Item* pWeapon = pOusters->getWearItem(Ousters::WEAR_RIGHTHAND);
if (pWeapon == NULL || pWeapon->getItemClass() != Item::ITEM_CLASS_OUSTERS_WRISTLET || !pOusters->isRealWearingEx(Ousters::WEAR_RIGHTHAND))
{
executeSkillFailException(pOusters, pOustersSkillSlot->getSkillType());
return;
}
GCSkillToTileOK1 _GCSkillToTileOK1;
GCSkillToTileOK2 _GCSkillToTileOK2;
GCSkillToTileOK3 _GCSkillToTileOK3;
GCSkillToTileOK4 _GCSkillToTileOK4;
GCSkillToTileOK5 _GCSkillToTileOK5;
GCSkillToTileOK6 _GCSkillToTileOK6;
SkillType_t SkillType = pOustersSkillSlot->getSkillType();
SkillInfo* pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType);
ZoneCoord_t myX = pOusters->getX();
ZoneCoord_t myY = pOusters->getY();
// 이펙트의 지속시간을 계산한다.
SkillInput input(pOusters, pOustersSkillSlot);
SkillOutput output;
computeOutput(input, output);
int RequiredMP = (int)pSkillInfo->getConsumeMP() + pOustersSkillSlot->getExpLevel();
bool bManaCheck = hasEnoughMana(pOusters, RequiredMP);
bool bTimeCheck = verifyRunTime(pOustersSkillSlot);
bool bRangeCheck = verifyDistance(pOusters, X, Y, pSkillInfo->getRange());
bool bHitRoll = HitRoll::isSuccessMagic(pOusters, pSkillInfo, pOustersSkillSlot);
bool bSatisfyRequire = pOusters->satisfySkillRequire(pSkillInfo);
bool bTileCheck = false;
VSRect rect(0, 0, pZone->getWidth()-1, pZone->getHeight()-1);
if (rect.ptInRect(X, Y)) bTileCheck = true;
if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll && bTileCheck && bSatisfyRequire)
{
decreaseMana(pOusters, RequiredMP, _GCSkillToTileOK1);
int grade = 0;
if (input.SkillLevel <= 10 ) grade = 0;
else if (input.SkillLevel <= 20 ) grade = 1;
else if (input.SkillLevel < 30 ) grade = 2;
else grade = 3;
list<Creature*> cList; // denier list
for (int i=0; i<m_MaskNum[grade]; i++)
{
POINT& pt = m_IceFieldMask[grade][i];
int tileX = X+pt.x;
int tileY = Y+pt.y;
if (rect.ptInRect(tileX, tileY))
{
Tile& tile = pZone->getTile(tileX, tileY);
if (tile.getEffect(Effect::EFFECT_CLASS_TRYING_POSITION) ) continue;
// 현재 타일에다 이펙트를 추가할 수 있다면...
if (tile.canAddEffect())
{
// 같은 effect가 있으면 지운다.
Effect* pOldEffect = tile.getEffect(Effect::EFFECT_CLASS_ICE_FIELD);
if (pOldEffect != NULL)
{
ObjectID_t effectID = pOldEffect->getObjectID();
pZone->deleteEffect(effectID);// fix me
}
// 이펙트 클래스를 생성한다.
EffectIceField* pEffect = new EffectIceField(pZone , tileX, tileY);
pEffect->setCasterName(pOusters->getName());
pEffect->setCasterID(pOusters->getObjectID());
pEffect->setDeadline(output.Duration);
pEffect->setDuration(output.Range);
pEffect->setNextTime(0);
//.........这里部分代码省略.........
示例5: affect
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);
}
//.........这里部分代码省略.........
示例6: executeNormal
//.........这里部分代码省略.........
Creature* pNearCreature = NULL;
Player* pNearPlayer = NULL;
GCShopBought boughtpkt;
boughtpkt.setObjectID(NPCID);
if (!pItem->getOptionTypeList().empty()) {
boughtpkt.setShopVersion(pNPC->getShopVersion(SHOP_RACK_SPECIAL));
boughtpkt.setShopType(SHOP_RACK_SPECIAL);
} else {
boughtpkt.setShopVersion(pNPC->getShopVersion(SHOP_RACK_NORMAL));
boughtpkt.setShopType(SHOP_RACK_NORMAL);
}
boughtpkt.setShopIndex(index);
boughtpkt.setItemObjectID(ITEMOID);
boughtpkt.setItemClass(pItem->getItemClass());
boughtpkt.setItemType(pItem->getItemType());
boughtpkt.setOptionType(pItem->getOptionTypeList());
boughtpkt.setDurability(pItem->getDurability());
boughtpkt.setSilver(pItem->getSilver());
boughtpkt.setGrade(pItem->getGrade());
boughtpkt.setEnchantLevel(pItem->getEnchantLevel());
//pZone->broadcastPacket(pNPC->getX(), pNPC->getY(), &boughtpkt, pPC);
try
{
for (int zx=CenterX-5; zx<=CenterX+5; zx++)
{
for (int zy=CenterY-5; zy<=CenterY+5; zy++)
{
// 바운드를 넘어가지 않는가를 체크
if (!isValidZoneCoord(pZone, zx, zy)) continue;
Tile & tile = pZone->getTile(zx, zy);
// 걸어다니는 크리쳐를 검색
if (tile.hasCreature(Creature::MOVE_MODE_WALKING))
{
pNearCreature = tile.getCreature(Creature::MOVE_MODE_WALKING);
if (pNearCreature == NULL) continue;
// 방금 물건을 판 플레이어라면 생략
if (pNearCreature->getObjectID() == pPC->getObjectID()) continue;
// 만약 플레이어라면 패킷을 보내준다.
if (pNearCreature->isPC())
{
pNearPlayer = pNearCreature->getPlayer();
if (pNearPlayer == NULL) continue;
pNearPlayer->sendPacket(&boughtpkt);
}
}
// 날아다니는 크리쳐를 검색
if (tile.hasCreature(Creature::MOVE_MODE_FLYING))
{
pNearCreature = tile.getCreature(Creature::MOVE_MODE_FLYING);
if (pNearCreature == NULL) continue;
// 방금 물건을 판 플레이어라면 생략
if (pNearCreature->getObjectID() == pPC->getObjectID()) continue;
// 만약 플레이어라면 패킷을 보내준다.
if (pNearCreature->isPC())
{
pNearPlayer = pNearCreature->getPlayer();
if (pNearPlayer == NULL) continue;
示例7: affect
void EffectPlasmaRocketLauncher::affect(Creature* pCreature)
throw(Error)
{
__BEGIN_TRY
__BEGIN_DEBUG
Assert(pCreature != NULL);
Zone* pZone = pCreature->getZone();
Assert(pZone != NULL);
Creature* pAttacker = pZone->getCreature(m_UserObjectID);
VSRect rect(0, 0, pZone->getWidth()-1, pZone->getHeight()-1);
int cX = pCreature->getX();
int cY = pCreature->getY();
for(int x = -1; x <= 1; x++)
{
for(int y= -1; y <= 1; y++)
{
int X = cX + x;
int Y = cY + y;
if(!rect.ptInRect(X, Y)) continue;
Tile& tile = pZone->getTile(X, Y);
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* pCreature2 = dynamic_cast<Creature*>(pObject);
Assert(pCreature2 != NULL);
if (pCreature2 != pCreature && pCreature2->isSlayer() ) continue;
if (!(pZone->getZoneLevel() & COMPLETE_SAFE_ZONE)
&& !pCreature2->isDead()
&& !pCreature2->isFlag(Effect::EFFECT_CLASS_COMA)
// 무적상태 체크. by sigi. 2002.9.5
&& canAttack(pAttacker, pCreature2 )
)
{
GCModifyInformation gcMI, gcAttackerMI;
setDamage(pCreature2, m_Point, pAttacker, SKILL_PLASMA_ROCKET_LAUNCHER, &gcMI, &gcAttackerMI);
if (pCreature2->isPC() ) pCreature2->getPlayer()->sendPacket(&gcMI);
if (pAttacker!=NULL)
{
computeAlignmentChange(pCreature2, m_Point, pAttacker, &gcMI, &gcAttackerMI);
if (pAttacker->isPC() )
{
if (pAttacker->isSlayer() && !pCreature2->isSlayer() )
{
Slayer* pSlayer = dynamic_cast<Slayer*>(pAttacker);
if (pSlayer != NULL )
{
GCModifyInformation gcMI;
shareAttrExp(pSlayer, m_Point, 1, 8, 1, gcAttackerMI);
}
}
if (pAttacker->isPC() ) pAttacker->getPlayer()->sendPacket(&gcAttackerMI);
}
}
}
}
}
}
}
setDeadline(0);
__END_DEBUG
__END_CATCH
}
示例8: execute
//////////////////////////////////////////////////////////////////////////////
// 뱀파이어 타일 핸들러
//////////////////////////////////////////////////////////////////////////////
void BloodyWall::execute(Vampire* pVampire, ZoneCoord_t X, ZoneCoord_t Y, VampireSkillSlot* pVampireSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
__BEGIN_TRY
//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " Begin" << endl;
Assert(pVampire != NULL);
Assert(pVampireSkillSlot != NULL);
try
{
Player* pPlayer = pVampire->getPlayer();
Zone* pZone = pVampire->getZone();
Assert(pPlayer != NULL);
Assert(pZone != NULL);
GCSkillToTileOK1 _GCSkillToTileOK1;
GCSkillToTileOK2 _GCSkillToTileOK2;
GCSkillToTileOK3 _GCSkillToTileOK3;
GCSkillToTileOK4 _GCSkillToTileOK4;
GCSkillToTileOK5 _GCSkillToTileOK5;
GCSkillToTileOK6 _GCSkillToTileOK6;
SkillType_t SkillType = pVampireSkillSlot->getSkillType();
SkillInfo* pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType);
ZoneCoord_t myX = pVampire->getX();
ZoneCoord_t myY = pVampire->getY();
// Knowledge of Blood 가 있다면 hit bonus 10
int HitBonus = 0;
if (pVampire->hasRankBonus(RankBonus::RANK_BONUS_KNOWLEDGE_OF_BLOOD ) )
{
RankBonus* pRankBonus = pVampire->getRankBonus(RankBonus::RANK_BONUS_KNOWLEDGE_OF_BLOOD);
Assert(pRankBonus != NULL);
HitBonus = pRankBonus->getPoint();
}
int RequiredMP = decreaseConsumeMP(pVampire, pSkillInfo);
bool bManaCheck = hasEnoughMana(pVampire, RequiredMP);
bool bTimeCheck = verifyRunTime(pVampireSkillSlot);
bool bRangeCheck = verifyDistance(pVampire, X, Y, pSkillInfo->getRange());
bool bHitRoll = HitRoll::isSuccessMagic(pVampire, pSkillInfo, pVampireSkillSlot, HitBonus);
bool bTileCheck = false;
VSRect rect(0, 0, pZone->getWidth()-1, pZone->getHeight()-1);
if (rect.ptInRect(X, Y)) bTileCheck = true;
if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll && bTileCheck)
{
decreaseMana(pVampire, RequiredMP, _GCSkillToTileOK1);
// 이펙트의 지속시간을 계산한다.
SkillInput input(pVampire);
SkillOutput output;
computeOutput(input, output);
Dir_t Dir = getDirectionToPosition(myX, myY, X, Y);
list<Creature*> cList; // denier list
for (int i=0; i<5; i++)
{
POINT& pt = m_BloodyWallMask[Dir][i];
int tileX = X+pt.x;
int tileY = Y+pt.y;
if (rect.ptInRect(tileX, tileY))
{
Tile& tile = pZone->getTile(tileX, tileY);
if (tile.getEffect(Effect::EFFECT_CLASS_TRYING_POSITION )!=NULL ) continue;
// 현재 타일에다 이펙트를 추가할 수 있다면...
if (tile.canAddEffect())
{
// 같은 effect가 있으면 지운다.
Effect* pOldEffect = tile.getEffect(Effect::EFFECT_CLASS_BLOODY_WALL);
if (pOldEffect != NULL)
{
ObjectID_t effectID = pOldEffect->getObjectID();
pZone->deleteEffect(effectID);// fix me
}
// 이펙트 클래스를 생성한다.
EffectBloodyWall* pEffect = new EffectBloodyWall(pZone , tileX, tileY);
pEffect->setCasterName(pVampire->getName());
pEffect->setCasterID(pVampire->getObjectID());
pEffect->setClan(Creature::CREATURE_CLASS_VAMPIRE, pVampire->getClanType());
pEffect->setDamage(output.Damage);
pEffect->setDeadline(output.Duration);
pEffect->setLevel(pVampire->getINT());
pEffect->setNextTime(0);
pEffect->setTick(output.Tick);
//.........这里部分代码省略.........
示例9: execute
//////////////////////////////////////////////////////////////////////////////
// 아우스터즈 타일 핸들러
//////////////////////////////////////////////////////////////////////////////
void SummonGroundElemental::execute(Ousters* pOusters, ZoneCoord_t X, ZoneCoord_t Y, OustersSkillSlot* pOustersSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
__BEGIN_TRY
//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << "begin " << endl;
Assert(pOusters != NULL);
Assert(pOustersSkillSlot != NULL);
BYTE Grade = 0;
if (pOustersSkillSlot->getExpLevel() < 15 ) Grade = 0;
else if (pOustersSkillSlot->getExpLevel() < 30 ) Grade = 1;
else Grade = 2;
try
{
Player* pPlayer = pOusters->getPlayer();
Zone* pZone = pOusters->getZone();
Assert(pPlayer != NULL);
Assert(pZone != NULL);
Item* pWeapon = pOusters->getWearItem(Ousters::WEAR_RIGHTHAND);
if (pWeapon == NULL || pWeapon->getItemClass() != Item::ITEM_CLASS_OUSTERS_WRISTLET || !pOusters->isRealWearingEx(Ousters::WEAR_RIGHTHAND))
{
executeSkillFailException(pOusters, pOustersSkillSlot->getSkillType(), Grade);
return;
}
GCSkillToTileOK1 _GCSkillToTileOK1;
GCSkillToTileOK2 _GCSkillToTileOK2;
GCSkillToTileOK3 _GCSkillToTileOK3;
GCSkillToTileOK4 _GCSkillToTileOK4;
GCSkillToTileOK5 _GCSkillToTileOK5;
GCSkillToTileOK6 _GCSkillToTileOK6;
SkillType_t SkillType = pOustersSkillSlot->getSkillType();
SkillInfo* pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType);
// 데미지와 지속 시간을 계산한다.
SkillInput input(pOusters, pOustersSkillSlot);
SkillOutput output;
computeOutput(input, output);
int RequiredMP = (int)pSkillInfo->getConsumeMP() + pOustersSkillSlot->getExpLevel()/3;
bool bManaCheck = hasEnoughMana(pOusters, RequiredMP);
bool bTimeCheck = verifyRunTime(pOustersSkillSlot);
bool bRangeCheck = verifyDistance(pOusters, X, Y, pSkillInfo->getRange());
bool bHitRoll = HitRoll::isSuccessMagic(pOusters, pSkillInfo, pOustersSkillSlot);
bool bSatisfyRequire = pOusters->satisfySkillRequire(pSkillInfo);
bool bTileCheck = false;
VSRect rect(0, 0, pZone->getWidth()-1, pZone->getHeight()-1);
// if (rect.ptInRect(X, Y))
// {
// Tile& tile = pZone->getTile(X, Y);
// if (tile.canAddEffect()) bTileCheck = true;
// }
TPOINT pt = findSuitablePosition(pZone, X, Y, Creature::MOVE_MODE_WALKING);
if (pt.x == -1 )
{
bTileCheck = false;
}
else
{
bTileCheck = true;
for (int oX = pt.x - 2 ; oX <= pt.x + 2 ; ++oX )
for (int oY = pt.y - 2 ; oY <= pt.y + 2 ; ++oY )
{
if (!rect.ptInRect(oX, oY ) ) continue;
if (pZone->getTile(oX, oY).getEffect(Effect::EFFECT_CLASS_GROUND_ELEMENTAL_AURA ) != NULL )
{
bTileCheck = false;
break;
}
}
}
if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll && bTileCheck && bSatisfyRequire)
{
decreaseMana(pOusters, RequiredMP, _GCSkillToTileOK1);
int oX, oY;
/*
HP = 200 + (S_level * 10)
Defense = 50 + (S_level * 2)
Protection = 20 + (S_level * 2)
Poison Resistance = 70%
Acid Resistance = 60%
Curse Resistance = 100%
Blood Resistance = 50%
Regen = 1 HP per 1 sec
//.........这里部分代码省略.........
示例10: execute
//////////////////////////////////////////////////////////////////////////////
// 뱀파이어 오브젝트 핸들러
//////////////////////////////////////////////////////////////////////////////
void Paralyze::execute(Vampire* pVampire, ObjectID_t TargetObjectID, VampireSkillSlot* pVampireSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
__BEGIN_TRY
//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << "begin " << endl;
Assert(pVampire != NULL);
Assert(pVampireSkillSlot != NULL);
try
{
Player* pPlayer = pVampire->getPlayer();
Zone* pZone = pVampire->getZone();
Assert(pPlayer != NULL);
Assert(pZone != NULL);
Creature* pTargetCreature = pZone->getCreature(TargetObjectID);
SkillType_t SkillType = pVampireSkillSlot->getSkillType();
// NPC는 공격할 수가 없다.
// 면역이거나. by sigi. 2002.9.13
// NoSuch제거. by sigi. 2002.5.2
if (pTargetCreature==NULL
|| pTargetCreature->isFlag(Effect::EFFECT_CLASS_IMMUNE_TO_PARALYZE)
|| !canAttack(pVampire, pTargetCreature )
|| pTargetCreature->isNPC())
{
executeSkillFailException(pVampire, getSkillType());
//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " end " << endl;
return;
}
GCSkillToObjectOK1 _GCSkillToObjectOK1;
GCSkillToObjectOK2 _GCSkillToObjectOK2;
GCSkillToObjectOK3 _GCSkillToObjectOK3;
GCSkillToObjectOK4 _GCSkillToObjectOK4;
GCSkillToObjectOK5 _GCSkillToObjectOK5;
GCSkillToObjectOK6 _GCSkillToObjectOK6;
SkillInfo* pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType);
// Knowledge of Curse 가 있다면 hit bonus 10
int HitBonus = 0;
if (pVampire->hasRankBonus(RankBonus::RANK_BONUS_KNOWLEDGE_OF_CURSE ) )
{
RankBonus* pRankBonus = pVampire->getRankBonus(RankBonus::RANK_BONUS_KNOWLEDGE_OF_CURSE);
Assert(pRankBonus != NULL);
HitBonus = pRankBonus->getPoint();
}
Tile& rTile = pZone->getTile(pTargetCreature->getX(), pTargetCreature->getY());
int RequiredMP = decreaseConsumeMP(pVampire, pSkillInfo);
bool bManaCheck = hasEnoughMana(pVampire, RequiredMP);
bool bTimeCheck = verifyRunTime(pVampireSkillSlot);
bool bRangeCheck = verifyDistance(pVampire, pTargetCreature, pSkillInfo->getRange());
bool bHitRoll = HitRoll::isSuccessVampireCurse(pSkillInfo->getLevel(), pTargetCreature->getResist(MAGIC_DOMAIN_CURSE));
bool bHitRoll2 = HitRoll::isSuccessMagic(pVampire, pSkillInfo, pVampireSkillSlot, HitBonus);
bool bCanHit = canHit(pVampire, pTargetCreature, SkillType);
bool bEffected = pTargetCreature->isFlag(Effect::EFFECT_CLASS_PARALYZE) || rTile.getEffect(Effect::EFFECT_CLASS_TRYING_POSITION)!=NULL;
bool bPK = verifyPK(pVampire, pTargetCreature);
ZoneCoord_t vampX = pVampire->getX();
ZoneCoord_t vampY = pVampire->getY();
ZoneCoord_t targetX = pTargetCreature->getX();
ZoneCoord_t targetY = pTargetCreature->getY();
//if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll && bHitRoll2 && bCanHit && !bEffected && bPK)
if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll && bHitRoll2 && bCanHit && !bEffected && bPK && pTargetCreature->getCompetence() == 3)
{
decreaseMana(pVampire, RequiredMP, _GCSkillToObjectOK1);
bool bCanSeeCaster = canSee(pTargetCreature, pVampire);
SkillInput input(pVampire);
SkillOutput output;
computeOutput(input, output);
// Wisdom of Silence 이 있다면 지속시간 20% 증가
if (pVampire->hasRankBonus(RankBonus::RANK_BONUS_WISDOM_OF_SILENCE ) )
{
RankBonus* pRankBonus = pVampire->getRankBonus(RankBonus::RANK_BONUS_WISDOM_OF_SILENCE);
Assert(pRankBonus != NULL);
output.Duration += getPercentValue(output.Duration, pRankBonus->getPoint());
}
// pTargetCreature가 저주마법을 반사하는 경우
if (CheckReflection(pVampire, pTargetCreature, getSkillType()))
{
pTargetCreature = (Creature*)pVampire;
TargetObjectID = pVampire->getObjectID();
}
Resist_t resist = pTargetCreature->getResist(MAGIC_DOMAIN_CURSE);
//.........这里部分代码省略.........
示例11: execute
void SwordOfThor::execute(Slayer * pSlayer, ZoneCoord_t X, ZoneCoord_t Y, SkillSlot * pSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
__BEGIN_TRY
// cout << "(x,y)=" << X << "," << Y << endl;
Zone* pZone = pSlayer->getZone();
Assert(pZone!=NULL);
SkillInput input(pSlayer, pSkillSlot);
SkillOutput output;
computeOutput(input, output);
SIMPLE_SKILL_INPUT param;
param.SkillType = getSkillType();
param.SkillDamage = output.Damage;
param.Delay = output.Delay;
param.ItemClass = Item::ITEM_CLASS_SWORD;
param.STRMultiplier = 8;
param.DEXMultiplier = 1;
param.INTMultiplier = 1;
param.bMagicHitRoll = false;
param.bMagicDamage = false;
param.bAdd = false;
param.bExpForTotalDamage = false;
for (int i=-2; i<=2; ++i )
for (int j=-2; j<=2; ++j )
{
param.addMask(i, j, 100);
}
SIMPLE_SKILL_OUTPUT result;
// 목표위치+4방향
/* param.addMask(0 + dir_advance[dir][0], 0 + dir_advance[dir][1], 100);
param.addMask(-1 + dir_advance[dir][0], -1 + dir_advance[dir][1], 100);
param.addMask(0 + dir_advance[dir][0], -1 + dir_advance[dir][1], 100);
param.addMask(1 + dir_advance[dir][0], -1 + dir_advance[dir][1], 100);
param.addMask(-1 + dir_advance[dir][0], 0 + dir_advance[dir][1], 100);
param.addMask(1 + dir_advance[dir][0], 0 + dir_advance[dir][1], 100);
param.addMask(-1 + dir_advance[dir][0], 1 + dir_advance[dir][1], 100);
param.addMask(0 + dir_advance[dir][0], 1 + dir_advance[dir][1], 100);
param.addMask(1 + dir_advance[dir][0], 1 + dir_advance[dir][1], 100);*/
g_SimpleTileMissileSkill.execute(pSlayer, X, Y, pSkillSlot, param, result);
if (result.bSuccess )
{
for (int i=-2; i<=2; ++i )
for (int j=-2; j<=2; ++j )
{
ZoneCoord_t tx = X+i;
ZoneCoord_t ty = Y+j;
if (!isValidZoneCoord(pZone, tx, ty) ) continue;
Tile& rTile = pZone->getTile(tx, ty);
if (!rTile.canAddEffect() ) continue;
EffectSwordOfThor* pEffect = new EffectSwordOfThor(pZone, tx, ty);
pEffect->setLevel(input.SkillLevel);
pEffect->setDeadline(output.Duration);
pZone->registerObject(pEffect);
if (i != 0 || j != 0 ) pEffect->setBroadcastingEffect(false);
else
{
GCAddEffectToTile gcAE;
gcAE.setEffectID(pEffect->getSendEffectClass());
gcAE.setXY(tx, ty);
gcAE.setObjectID(pEffect->getObjectID());
gcAE.setDuration(output.Duration);
pZone->broadcastPacket(tx, ty, &gcAE);
// cout << tx << ", " << ty << " Effect broadcast" << endl;
}
pZone->addEffect(pEffect);
rTile.addEffect(pEffect);
// cout << tx << ", " << ty << " add Effect" << endl;
}
}
__END_CATCH
}
示例12: execute
//////////////////////////////////////////////////////////////////////////////
// 뱀파이어 타일 핸들러
// 뱀파이어가 Energy Drop Skill을 Tile에 사용했을때 사용하는 Handler
//////////////////////////////////////////////////////////////////////////////
void EnergyDrop::execute(Slayer* pSlayer, ZoneCoord_t X, ZoneCoord_t Y, SkillSlot* pSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
__BEGIN_TRY
//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << "begin " << endl;
EffectEnergyDrop * pEffect = NULL;
EffectEnergyDrop * pEffect2 = NULL;
try
{
Player* pPlayer = pSlayer->getPlayer();
Zone* pZone = pSlayer->getZone();
Assert(pPlayer != NULL);
Assert(pZone != NULL);
GCSkillToTileOK1 _GCSkillToTileOK1;
GCSkillToTileOK2 _GCSkillToTileOK2;
GCSkillToTileOK3 _GCSkillToTileOK3;
GCSkillToTileOK4 _GCSkillToTileOK4;
GCSkillToTileOK5 _GCSkillToTileOK5;
GCSkillToTileOK6 _GCSkillToTileOK6;
SkillType_t SkillType = pSkillSlot->getSkillType();
SkillInfo* pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType);
SkillDomainType_t DomainType = pSkillInfo->getDomainType();
ZoneCoord_t myX = pSlayer->getX();
ZoneCoord_t myY = pSlayer->getY();
int RequiredMP = (int)pSkillInfo->getConsumeMP();
bool bManaCheck = hasEnoughMana(pSlayer, RequiredMP);
bool bTimeCheck = verifyRunTime(pSkillSlot);
bool bRangeCheck = verifyDistance(pSlayer, X, Y, pSkillInfo->getRange());
bool bHitRoll = HitRoll::isSuccessMagic(pSlayer, pSkillInfo, pSkillSlot);
bool bTileCheck = false;
VSRect rect(0, 0, pZone->getWidth()-1, pZone->getHeight()-1);
if(rect.ptInRect(X, Y))
{
Tile& tile = pZone->getTile(X, Y);
if (tile.canAddEffect()) bTileCheck = true;
}
if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll && bTileCheck)
{
decreaseMana(pSlayer, RequiredMP, _GCSkillToTileOK1);
// calculate damage and duration time
SkillInput input(pSlayer, pSkillSlot);
SkillOutput output;
computeOutput(input, output);
// Holy Smashing 이 있다면 데미지 10% 증가
if (pSlayer->hasRankBonus(RankBonus::RANK_BONUS_HOLY_SMASHING ) )
{
RankBonus* pRankBonus = pSlayer->getRankBonus(RankBonus::RANK_BONUS_HOLY_SMASHING);
Assert(pRankBonus != NULL);
output.Damage += pRankBonus->getPoint();
}
Range_t Range = 3;
// 기존에 같은 이펙트가 타일에 있다면 지우고 새로 설정한다.
Tile& tile = pZone->getTile(X, Y);
Effect* pOldEffect = tile.getEffect(Effect::EFFECT_CLASS_ENERGY_DROP);
if(pOldEffect != NULL)
{
ObjectID_t effectID = pOldEffect->getObjectID();
pZone->deleteEffect(effectID);
}
// 이펙트 오브젝트를 생성해서 타일에 붙인다.
//cout << "make EffectObject to Tile" << X << " " << Y << endl;
pEffect = new EffectEnergyDrop(pZone, X, Y);
pEffect->setUserObjectID(pSlayer->getObjectID());
// pEffect->setCasterName(pSlayer->getName());
// pEffect->setPartyID(pSlayer->getPartyID());
pEffect->setDeadline(output.Duration);
pEffect->setNextTime(0);
pEffect->setTick(output.Tick);
pEffect->setDamage(output.Damage);
pEffect->setLevel(pSkillInfo->getLevel()/2);
//
//ObjectRegistry& objectregister = pZone->getObjectRegistry();
//objectregister.registerObject(pEffect);
//.........这里部分代码省略.........
示例13: executeMotorcycle
//////////////////////////////////////////////////////////////////////////////
// 모터 사이클을 처리한다.
//////////////////////////////////////////////////////////////////////////////
void CGRequestRepairHandler::executeMotorcycle (CGRequestRepair* pPacket , Player* pPlayer)
throw(ProtocolException , Error)
{
__BEGIN_TRY __BEGIN_DEBUG_EX
#ifdef __GAME_SERVER__
// 패킷 정보를 뽑아낸다.
ObjectID_t ITEMOID = pPacket->getObjectID();
Creature* pPC = dynamic_cast<GamePlayer*>(pPlayer)->getCreature();
Zone* pZone = pPC->getZone();
Gold_t playerMoney = 0;
ZoneCoord_t CenterX = pPC->getX();
ZoneCoord_t CenterY = pPC->getY();
Item* pItem = NULL;
bool bSlayer = false;
bool bVampire = false;
bool bOusters = false;
GCNPCResponse response;
// 플레이어가 슬레이어인지 뱀파이어인지 구분.
if (pPC->isSlayer()) bSlayer = true;
else if (pPC->isVampire()) bVampire = true;
else if (pPC->isOusters()) bOusters = true;
else throw ProtocolException("CGRequestRepairHandler::execute() : Unknown player creature!");
// 플레이어가 수리하려고 하는 아이템을 가지고 있는지
// 상위에서 검사를 하기 때문에, pItem이 널일리는 없다.
if (bSlayer)
{
pItem = (dynamic_cast<Slayer*>(pPC))->findItemOID(ITEMOID);
playerMoney = (dynamic_cast<Slayer*>(pPC))->getGold();
}
else if (bVampire)
{
pItem = (dynamic_cast<Vampire*>(pPC))->findItemOID(ITEMOID);
playerMoney = (dynamic_cast<Vampire*>(pPC))->getGold();
}
else if (bOusters)
{
pItem = (dynamic_cast<Ousters*>(pPC))->findItemOID(ITEMOID);
playerMoney = (dynamic_cast<Ousters*>(pPC))->getGold();
}
// 주위 일정 범위를 검색해서, 모터 사이클이 있는지 확인한다.
for (ZoneCoord_t zx=CenterX-5; zx<=CenterX+5; zx++)
{
for (ZoneCoord_t zy=CenterY-5; zy<=CenterY+5; zy++)
{
if (!isValidZoneCoord(pZone, zx, zy)) continue;
Tile & tile = pZone->getTile(zx, zy);
if (tile.hasItem())
{
Item* pItemOnTile = tile.getItem();
Assert(pItemOnTile != NULL);
// 만일 아이템이 타일 위에 있을 경우, 모터 사이클인지 확인한다.
if (pItemOnTile->getItemClass() == Item::ITEM_CLASS_MOTORCYCLE)
{
DWORD targetID = dynamic_cast<Key*>(pItem)->getTarget();
ItemID_t motorcycleID = pItemOnTile->getItemID();
if (targetID == motorcycleID)
{
Price_t repairPrice = g_pPriceManager->getRepairPrice(pItemOnTile);
if (repairPrice > playerMoney)
{
response.setCode(NPC_RESPONSE_REPAIR_FAIL_MONEY);
pPlayer->sendPacket(&response);
return;
}
// 수리한다.
repairItem(pItemOnTile);
// 저장한다.
//pItemOnTile->save(pPC->getName(), STORAGE_ZONE, pZone->getZoneID(), zx, zy);
// item저장 최적화. by sigi. 2002.5.13
char pField[80];
sprintf(pField, "Durability=%d", pItemOnTile->getDurability());
pItemOnTile->tinysave(pField);
// 돈을 줄인다.
//if (bSlayer) (dynamic_cast<Slayer*>(pPC))->setGoldEx(playerMoney-repairPrice);
//else (dynamic_cast<Vampire*>(pPC))->setGoldEx(playerMoney-repairPrice);
// by sigi. 2002.9.4
(dynamic_cast<PlayerCreature*>(pPC))->decreaseGoldEx(repairPrice);
response.setCode(NPC_RESPONSE_REPAIR_OK);
response.setParameter(playerMoney-repairPrice);
pPlayer->sendPacket(&response);
//.........这里部分代码省略.........
示例14: execute
//////////////////////////////////////////////////////////////////////////////
// 아우스터즈 타일 핸들러
//////////////////////////////////////////////////////////////////////////////
void Prominence::execute(Ousters* pOusters, ZoneCoord_t X, ZoneCoord_t Y, OustersSkillSlot* pOustersSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
__BEGIN_TRY
//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << "begin " << endl;
Assert(pOusters != NULL);
Assert(pOustersSkillSlot != NULL);
BYTE Grade = 0;
if (pOustersSkillSlot->getExpLevel() < 15 ) Grade = 0;
else if (pOustersSkillSlot->getExpLevel() < 30 ) Grade = 1;
else Grade = 2;
try
{
Player* pPlayer = pOusters->getPlayer();
Zone* pZone = pOusters->getZone();
Assert(pPlayer != NULL);
Assert(pZone != NULL);
Item* pWeapon = pOusters->getWearItem(Ousters::WEAR_RIGHTHAND);
if (pWeapon == NULL || pWeapon->getItemClass() != Item::ITEM_CLASS_OUSTERS_WRISTLET || !pOusters->isRealWearingEx(Ousters::WEAR_RIGHTHAND))
{
executeSkillFailException(pOusters, pOustersSkillSlot->getSkillType(), Grade);
return;
}
GCSkillToTileOK1 _GCSkillToTileOK1;
GCSkillToTileOK2 _GCSkillToTileOK2;
GCSkillToTileOK3 _GCSkillToTileOK3;
GCSkillToTileOK4 _GCSkillToTileOK4;
GCSkillToTileOK5 _GCSkillToTileOK5;
GCSkillToTileOK6 _GCSkillToTileOK6;
SkillType_t SkillType = pOustersSkillSlot->getSkillType();
SkillInfo* pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType);
// 데미지와 지속 시간을 계산한다.
SkillInput input(pOusters, pOustersSkillSlot);
SkillOutput output;
computeOutput(input, output);
int RequiredMP = (int)pSkillInfo->getConsumeMP() + pOustersSkillSlot->getExpLevel()/3;
bool bManaCheck = hasEnoughMana(pOusters, RequiredMP);
bool bTimeCheck = verifyRunTime(pOustersSkillSlot);
bool bRangeCheck = verifyDistance(pOusters, X, Y, output.Range);
bool bHitRoll = HitRoll::isSuccessMagic(pOusters, pSkillInfo, pOustersSkillSlot);
bool bSatisfyRequire = pOusters->satisfySkillRequire(pSkillInfo);
bool bTileCheck = false;
VSRect rect(0, 0, pZone->getWidth()-1, pZone->getHeight()-1);
if (rect.ptInRect(X, Y))
{
Tile& tile = pZone->getTile(X, Y);
if (tile.canAddEffect()) bTileCheck = true;
}
if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll && bTileCheck && bSatisfyRequire)
{
decreaseMana(pOusters, RequiredMP, _GCSkillToTileOK1);
int oX, oY;
for (oX = X - 1 ; oX <= X + 1 ; ++oX )
for (oY = Y - 1 ; oY <= Y + 1 ; ++oY )
{
if (!rect.ptInRect(oX, oY)) continue;
Tile& tile = pZone->getTile(oX, oY);
if (!tile.canAddEffect()) continue;
// 머시 그라운드 있음 추가 못한당.
if (tile.getEffect(Effect::EFFECT_CLASS_MERCY_GROUND) != NULL ) continue;
if (tile.getEffect(Effect::EFFECT_CLASS_TRYING_POSITION) ) continue;
// 같은 이펙트가 이미 존재한다면 삭제한다.
Effect* pOldEffect = tile.getEffect(Effect::EFFECT_CLASS_PROMINENCE);
if (pOldEffect != NULL)
{
ObjectID_t effectID = pOldEffect->getObjectID();
pZone->deleteEffect(effectID);
}
checkMine(pZone, oX, oY);
// 이펙트 오브젝트를 생성한다.
EffectProminence* pEffect = new EffectProminence(pZone, oX, oY);
pEffect->setUserObjectID(pOusters->getObjectID());
pEffect->setDeadline(output.Duration);
pEffect->setNextTime(0);
pEffect->setTick(output.Tick);
pEffect->setDamage(output.Damage);
pEffect->setLevel(pOustersSkillSlot->getExpLevel());
//.........这里部分代码省略.........
示例15: execute
//////////////////////////////////////////////////////////////////////////////
// 뱀파이어 타일 핸들러
//////////////////////////////////////////////////////////////////////////////
void BloodyBreaker::execute(Vampire* pVampire, ZoneCoord_t X, ZoneCoord_t Y, VampireSkillSlot* pVampireSkillSlot, CEffectID_t CEffectID)
throw(Error)
{
__BEGIN_TRY
//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << "begin " << endl;
SkillType_t SkillType = getSkillType();
// Knowledge of Blood 가 있다면 hit bonus 10
int HitBonus = 0;
if (pVampire->hasRankBonus(RankBonus::RANK_BONUS_KNOWLEDGE_OF_BLOOD ) )
{
RankBonus* pRankBonus = pVampire->getRankBonus(RankBonus::RANK_BONUS_KNOWLEDGE_OF_BLOOD);
Assert(pRankBonus != NULL);
HitBonus = pRankBonus->getPoint();
}
try
{
SkillInput input(pVampire);
SkillOutput output;
computeOutput(input, output);
Dir_t Dir = getDirectionToPosition(pVampire->getX(), pVampire->getY(), X, Y);
// 강제로 knockback시킬 확률
// bool bForceKnockback = rand()%100 < output.ToHit;
Player* pPlayer = pVampire->getPlayer();
Zone* pZone = pVampire->getZone();
Assert(pPlayer != NULL);
Assert(pZone != NULL);
VSRect rect(1, 1, pZone->getWidth()-2, pZone->getHeight()-2);
if (!rect.ptInRect(X, Y ))
{
executeSkillFailException(pVampire, SkillType);
return;
}
GCSkillToTileOK1 _GCSkillToTileOK1;
GCSkillToTileOK2 _GCSkillToTileOK2;
// GCSkillToTileOK3 _GCSkillToTileOK3;
// GCSkillToTileOK4 _GCSkillToTileOK4;
GCSkillToTileOK5 _GCSkillToTileOK5;
// GCSkillToTileOK6 _GCSkillToTileOK6;
SkillInfo* pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType);
int RequiredMP = decreaseConsumeMP(pVampire, pSkillInfo);
bool bManaCheck = hasEnoughMana(pVampire, RequiredMP);
bool bTimeCheck = verifyRunTime(pVampireSkillSlot);
bool bRangeCheck = verifyDistance(pVampire, X, Y, pSkillInfo->getRange());
if (bManaCheck && bTimeCheck && bRangeCheck )
{
// 마나를 떨어뜨린다.
decreaseMana(pVampire, RequiredMP, _GCSkillToTileOK1);
// 좌표와 방향을 구한다.
ZoneCoord_t myX = pVampire->getX();
ZoneCoord_t myY = pVampire->getY();
Dir_t dir = calcDirection(myX, myY, X, Y);
list<Creature*> cList;
// knockback 때문에 recursive 하게 데미지를 먹는 경우가 있다.
// 그래서 제일 먼쪽에 있는 마스크부터 체크한다.
for (int i = 21; i >= 0; i-- )
{
int tileX = myX + m_pBloodyBreakerMask[Dir][i].x;
int tileY = myY + m_pBloodyBreakerMask[Dir][i].y;
// 현재 타일이 존 내부이고, 안전지대가 아니라면 맞을 가능성이 있다.
if (rect.ptInRect(tileX, tileY))
{
// 타일을 받아온다.
Tile& tile = pZone->getTile(tileX, tileY);
list<Creature*> targetList;
if (tile.hasCreature(Creature::MOVE_MODE_WALKING))
{
Creature* pCreature = tile.getCreature(Creature::MOVE_MODE_WALKING);
targetList.push_back(pCreature);
}
if (tile.hasCreature(Creature::MOVE_MODE_FLYING))
{
Creature* pCreature = tile.getCreature(Creature::MOVE_MODE_FLYING);
targetList.push_back(pCreature);
}
if (tile.hasCreature(Creature::MOVE_MODE_BURROWING))
{
Creature* pCreature = tile.getCreature(Creature::MOVE_MODE_BURROWING);
targetList.push_back(pCreature);
}
//.........这里部分代码省略.........