BOOL TMonsterSkillElement::ApplyElementTeleportSkill(int iIndex, int iTargetIndex)
{
	if ( !OBJMAX_RANGE(iIndex))
		return FALSE;

	if ( gObj[iIndex].m_iSkillStunTime > 0 )
		return FALSE;

	LPOBJ lpObj = &gObj[iIndex];
	BYTE x;
	BYTE y;
	int depth = rand()%4 + 3;
	PMSG_MAGICATTACK_RESULT pAttack;

	if ( (rand()%2) == 0 )
		x = lpObj->X + depth;
	else
		x = lpObj->X - depth;

	if ( (rand()%2) == 0 )
		y = lpObj->Y + depth;
	else
		y = lpObj->Y - depth;

	if ( gObjCheckTeleportArea(iIndex, x, y) == FALSE )
	{
		CLog.LogAddC(TColor.Red(), "[%s][%s] Try Teleport Not Move Area [%d,%d]",
			lpObj->AccountID, lpObj->Name,	x, y);
		
		return FALSE;
	}

	C3HeadSet((LPBYTE)&pAttack, 0x19, sizeof(pAttack));

	pAttack.MagicNumberH = SET_NUMBERH(6);
	pAttack.MagicNumberL = SET_NUMBERL(6);
	pAttack.SourceNumberH = SET_NUMBERH(iIndex);
	pAttack.SourceNumberL = SET_NUMBERL(iIndex);
	pAttack.TargetNumberH = SET_NUMBERH(iIndex);
	pAttack.TargetNumberL = SET_NUMBERL(iIndex);

	if ( lpObj->Type == OBJ_USER )
		gSendProto.DataSend(iIndex, (LPBYTE)&pAttack, pAttack.h.size);	

	gSendProto.VPMsgSend(lpObj, (LPBYTE)&pAttack, pAttack.h.size);	

	CLog.LogAddC(TColor.Red(), "[%s] Warp [%d,%d] -> [%d,%d]",
		lpObj->Name, lpObj->X, lpObj->Y, x, y);

	gObjTeleportMagicUse(iIndex, x, y);
	lpObj->TargetNumber = -1;

	return FALSE;
}
void CCannonTower::CannonTowerAct(int iIndex)
{
	if ( (rand()%2) != 0 )
		return;

	LPOBJ lpObj = &gObj[iIndex];
	int tObjNum;
	int count = 0;
	PMSG_BEATTACK_COUNT pCount;
	PMSG_BEATTACK pAttack;
	BYTE AttackSendBuff[256];
	int ASBOfs = 0;
	
	pCount.h.c = 0xC1;
	pCount.h.headcode = 0x10;
	pCount.h.size = 0;
	pCount.MagicNumberH = 0;
	pCount.MagicNumberL = 0;
	pCount.Count = 0;
	pCount.X = lpObj->X;
	pCount.Y = lpObj->Y;
	
	ASBOfs = sizeof(pCount);

	while ( true )
	{
		if ( lpObj->VpPlayer2[count].state )
		{
			if ( lpObj->VpPlayer2[count].type == OBJ_USER )
			{
				tObjNum = lpObj->VpPlayer2[count].number;

				if ( tObjNum >= 0 )
				{
					if ( gObj[tObjNum].m_btCsJoinSide != 1 )
					{
						if ( gObjCalDistance(lpObj, &gObj[tObjNum]) < 7 )
						{
							pAttack.NumberH = SET_NUMBERH(tObjNum);
							pAttack.NumberL = SET_NUMBERL(tObjNum);
							memcpy(&AttackSendBuff[ASBOfs], &pAttack, sizeof(pAttack));
							ASBOfs += sizeof(pAttack);
							pCount.Count++;
						}
					}
				}
			}
		}
		
		count++;

		if ( count > MAX_VIEWPORT-1 )
			break;
	}

	if ( pCount.Count > 0 )
	{
		pCount.h.size = ASBOfs;
		memcpy(AttackSendBuff, &pCount, sizeof(pCount));
		CGBeattackRecv(AttackSendBuff, lpObj->m_Index, 1);

		PMSG_DURATION_MAGIC_SEND pMsg;

		C3HeadSet((LPBYTE)&pMsg, 0x1E, sizeof(pMsg));
		pMsg.MagicNumberH = 0x00;
		pMsg.MagicNumberL = 50;
		pMsg.X = lpObj->X;
		pMsg.Y = lpObj->Y;
		pMsg.Dir = 0;
		pMsg.NumberH = SET_NUMBERH(iIndex);
		pMsg.NumberL = SET_NUMBERL(iIndex);

		gSendProto.VPMsgSend(lpObj, (LPBYTE)&pMsg, pMsg.h.size);
	}
}