EntryPointInSim* OnboardSeatInSim::GetfrontRowEntryPoint(const CPoint2008& dir)
{
	CPoint2008 rotateDir = dir;
	if (m_pSeatGroupInSim == NULL)
		return NULL;
	const CPollygon2008& polygon = m_pSeatGroupInSim->GetPolygon();

	EntryPointInSim* pEntryPointInSim = NULL;
	ARCVector3 entryPt;
	GetFrontPosition(entryPt);
	CPoint2008 seatPt(entryPt.n[VX],entryPt.n[VY],0.0);

	CPoint2008 cellPt(GRID_WIDTH,GRID_HEIGHT,0.0);
	double dDist = PAXRADIUS + GRID_WIDTH;//offset make be able to next cell
	double dOffset = m_pSeat->GetWidth()/2;

	CPoint2008 ptOffset = seatPt + rotateDir*(m_pSeat->GetWidth()/2);
	OnboardCellInSim* pCellInSim = GetGround()->getCell(ptOffset);
	CPoint2008 cellInSimPt = pCellInSim->getLocation();
	cellInSimPt += rotateDir * dDist;
	OnboardCellInSim* pEntryCellInSim = GetGround()->GetPointCell(cellInSimPt);
	if (pEntryCellInSim)
	{
		pEntryCellInSim->SetState(OnboardCellInSim::Idle);
		GetGround()->getLogicMap().setTileAsBarrier(pEntryCellInSim->getTileIndex(), false);
		pEntryPointInSim = new EntryPointInSim(pEntryCellInSim,m_pFlightInSim);
		pEntryPointInSim->SetWalkType(EntryPointInSim::TurnDirection_Walk);
		pEntryPointInSim->SetCreateSeat(this);
	}
	
	return pEntryPointInSim;
}
OnboardCellInSim* OnboardSeatInSim::GetOnboardCellInSim()
{
	ARCVector3 location;
	GetFrontPosition(location);


	return GetGround()->getCell(CPoint2008(location.n[VX],location.n[VY],location.n[VZ]));
}
void OnboardEscalatorInSim::CalculateSpace()
{
	ClearSpace();
	CreateEntryPoint();
	DeckPoint deckPt = m_pDevice->GetDeckPoint().front();
	m_pElementSpace = new OnboardElementSpace(GetGround(deckPt.first));
	m_pElementSpace->CreatePollygon(this);
	m_pElementSpace->CalculateSpace();
	
}
void OnboardSeatInSim::CalculateSpace()
{
	if (m_pSeat->getRow() || m_pSeat->getGroup())
		return;
	
	ClearSpace();
	m_pElementSpace = new OnboardElementSpace(GetGround());

	m_pElementSpace->CreatePollygon(this);

	m_pElementSpace->CalculateSpace();
}
void CDeathPirate::Update(float fElapsedTime)
{
	CIdleEnemy::Update(fElapsedTime);

	m_fTimeWaited += fElapsedTime;

	if(GetGround())
	{
		SetBaseVelY(0);
	}
	else
	{
		SetBaseVelY(GetBaseVelY() + 50*fElapsedTime);

		if(GetBaseVelY() > 75)
			SetBaseVelY(75);

		SetPosY(GetPosY() + GetBaseVelY() *fElapsedTime);
	}

	switch(ReturnAIState())
	{
	case Idle:
		GetAnimations()->SetCurrentAnimation(0);
		break;
	case iActive:
		if(m_fTimeWaited >= 15.0f && !GetCulling())
		{
			m_fTimeWaited = 0.0f;

			if(Spawn_01 == NULL)
			{
				CGame::GetInstance()->GetMessageSystemPointer()->SendMsg(new CCreateEnemyMessage(6, (int)GetPosX()-100, (int)GetPosY()-150, NULL));
			}
			else if(Spawn_02 == NULL)
			{
				CGame::GetInstance()->GetMessageSystemPointer()->SendMsg(new CCreateEnemyMessage(6, (int)GetPosX()+GetWidth()+150, (int)GetPosY()-150, NULL));
			}
		}

		GetAnimations()->SetCurrentAnimation(1);
		if(!GetAnimations()->SameFrame() && GetAnimations()->GetTrigger() != 0)
		{
			CGame::GetInstance()->GetMessageSystemPointer()->SendMsg(new CCreateBulletMessage(this));
		}
		break;
	case iDead:
		ReleaseSpawner();
		CGame::GetInstance()->GetMessageSystemPointer()->SendMsg(new CDestroyEnemyMessage((CBaseEnemy*)this));
		CSinglePlayerState::GetInstance()->SetWin(true);
		break;
	};
}
void OnboardEscalatorInSim::CreateEntryPoint()
{
	int nDeckCount = (int)m_pDevice->GetDeckPoint().size();
	if (nDeckCount < 2) //less than two point can not calculate entry point
		return;

	int nPointCount = m_realpath.getCount();
	if (nPointCount < 2)
		return;

	CPoint2008 cellPt(GRID_WIDTH,GRID_HEIGHT,0.0);
	double dDist = cellPt.length();//offset make be able to next cell

	//first entry point
	DeckPoint deckFirstPt = m_pDevice->GetDeckPoint().front();
	CPoint2008 firstDir(m_realpath.getPoint(0) - m_realpath.getPoint(1));
	firstDir.setZ(0.0);
	firstDir.Normalize();
	OnboardCellInSim* pFirstCell = GetGround(deckFirstPt.first)->getCell(m_realpath.getPoint(0));
	CPoint2008 firstLocate = pFirstCell->getLocation();
	CPoint2008 firstEntryPoint = firstLocate + firstDir*dDist;
	OnboardCellInSim* pFirstEntryCell = GetGround(deckFirstPt.first)->getCell(firstEntryPoint);
	m_entryPointList.push_back(pFirstEntryCell);

	//back entry point
	DeckPoint deckBackPt = m_pDevice->GetDeckPoint().back();
	CPoint2008 backPt = m_realpath.getPoint(nPointCount - 1);
	CPoint2008 prePt = m_realpath.getPoint(nPointCount - 2);
	CPoint2008 backDir(backPt - prePt);
	backDir.setZ(0.0);
	backDir.Normalize();
	backPt += backDir*dDist;
	OnboardCellInSim* pBackCell = GetGround(deckBackPt.first)->getCell(backPt);
	CPoint2008 backLocate = pBackCell->getLocation();
	CPoint2008 backEntryPoint = backLocate + backDir*(dDist/2);
	OnboardCellInSim* pBackEntryCell = GetGround(deckBackPt.first)->getCell(backEntryPoint);
	m_entryPointList.push_back(pBackEntryCell);
}
void OnboardEscalatorInSim::CreateBackElementSpace()
{
	int nPointCount = m_realpath.getCount();
	if (nPointCount < 2)
		return;

	DeckPoint deckBackPt = m_pDevice->GetDeckPoint().back();
	CPoint2008 backPt = m_realpath.getPoint(nPointCount - 1);
	CPoint2008 prePt = m_realpath.getPoint(nPointCount - 2);
	CPoint2008 backDir(backPt - prePt);
	backDir.setZ(0.0);
	backDir.Normalize();

	CPoint2008 cellPt(GRID_WIDTH,GRID_HEIGHT,0.0);
	double dOffsetDist = cellPt.length();//offset make be able to next cell

	COnBoardEscalator* pEscalator = (COnBoardEscalator*)m_pDevice;
	double dDist = pEscalator->GetWidth()/2;
	//rotate 90
	CPoint2008 leftDir = backDir;
	leftDir.rotate(90);
	leftDir.Normalize();
	CPoint2008 leftTop = backPt + leftDir*dDist;
	CPoint2008 rightTop = leftTop + backDir*dOffsetDist;

	//rotate -90
	CPoint2008 rightDir = backDir;
	rightDir.rotate(-90);
	rightDir.Normalize();
	CPoint2008 leftBottom = backPt + rightDir*dDist;
	CPoint2008 rightBottom = leftBottom + backDir*dOffsetDist;

	CPollygon2008 pollygon;
	CPoint2008 ptList[4];
	ptList[0] = leftTop;
	ptList[1] = rightTop;
	ptList[2] = rightBottom;
	ptList[3] = leftBottom;

	pollygon.init(4,ptList);
	if (m_pBackElementSpace)
	{
		delete m_pBackElementSpace;
		m_pBackElementSpace = NULL;
	}

	m_pBackElementSpace = new OnboardElementSpace(GetGround(deckBackPt.first));
	m_pBackElementSpace->setPollygon(pollygon);
	m_pBackElementSpace->CalculateSpace();
}
EntryPointInSim* OnboardSeatInSim::FindEntryPoint()
{
	ARCVector3 seatPt;
	GetFrontPosition(seatPt);

	CPoint2008 entryPt(seatPt.n[VX],seatPt.n[VY],0.0);
	GroundInSim* pGroundInSim = GetGround();

	if (pGroundInSim == NULL)
		return NULL;

	OnboardCellInSim* pCellInSim = pGroundInSim->getCell(entryPt);
	EntryPointInSim* pEntryPointInSim = new EntryPointInSim(pCellInSim,m_pFlightInSim);
	pEntryPointInSim->SetCreateSeat(this);
	pEntryPointInSim->SetWalkType(EntryPointInSim::Straight_Walk);
	return pEntryPointInSim;
}
EntryPointInSim* OnboardSeatInSim::GetIntersectionNodeWithSeatGroupPolygon()
{
	if (m_pSeatGroupInSim == NULL)
		return NULL;
	const CPollygon2008& polygon = m_pSeatGroupInSim->GetPolygon();

	EntryPointInSim* pEntryPointInSim = NULL;
	ARCVector3 entryPt;
	GetFrontPosition(entryPt);
	CPoint2008 seatPt(entryPt.n[VX],entryPt.n[VY],0.0);
	CPoint2008 locationPt;
	GetLocation(locationPt);
	locationPt.setZ(0.0);
	
	CPoint2008 vDir(locationPt,seatPt);
	vDir.Normalize();
	
	CPoint2008 cellPt(GRID_WIDTH,GRID_HEIGHT,0.0);
	double dDist = PAXRADIUS/2 + GRID_WIDTH;//cellPt.length()*0.5 + 20;//offset make be able to next cell
	//rotate 90
	double dRayLeft = (std::numeric_limits<double>::max)();
	CPoint2008 ptRayLeft;
	CPoint2008 vDirLeft(vDir);
	vDirLeft.rotate(90.0);
	vDirLeft.Normalize();
	CRayIntersectPath2D rayPathLeft(seatPt,vDirLeft,polygon);
	if (rayPathLeft.Get())
	{
		ptRayLeft = polygon.GetIndexPoint((float)rayPathLeft.m_Out.begin()->m_indexInpath);
		CPoint2008 rayDirLeft(seatPt,ptRayLeft);
		rayDirLeft.Normalize();
		OnboardCellInSim* pLeftCellInSim = GetGround()->getCell(ptRayLeft);
		CPoint2008 leftCellPt = pLeftCellInSim->getLocation();
		leftCellPt += rayDirLeft * dDist;
		OnboardCellInSim* pLeftEntryCellInSim = GetGround()->GetPointCell(leftCellPt);
		if (pLeftEntryCellInSim)
		{
			pLeftEntryCellInSim->SetState(OnboardCellInSim::Idle);
			GetGround()->getLogicMap().setTileAsBarrier(pLeftEntryCellInSim->getTileIndex(), false);
			dRayLeft = rayPathLeft.m_Out.front().m_dist;
			pEntryPointInSim = new EntryPointInSim(pLeftEntryCellInSim,m_pFlightInSim);
			pEntryPointInSim->SetWalkType(EntryPointInSim::TurnDirection_Walk);
			pEntryPointInSim->SetCreateSeat(this);
		}
	}
	//rotate -90
	double dRayRight = (std::numeric_limits<double>::max)();
	CPoint2008 ptRayRight;
	CPoint2008 vDirRight(vDir);
	vDirRight.rotate(-90.0);
	vDirRight.Normalize();
	CRayIntersectPath2D rayPathRight(seatPt,vDirRight,polygon);
	if (rayPathRight.Get())
	{
		ptRayRight = polygon.GetIndexPoint((float)rayPathRight.m_Out.begin()->m_indexInpath);
		OnboardCellInSim* pRightCellInSim = GetGround()->getCell(ptRayRight);
		CPoint2008 rayDirRight(seatPt,ptRayRight);
		rayDirRight.Normalize();
		CPoint2008 rightCellPt = pRightCellInSim->getLocation();
		rightCellPt += rayDirRight * dDist;
		OnboardCellInSim* pRightEntryCellInSim = GetGround()->GetPointCell(rightCellPt);

		if (pRightEntryCellInSim)
		{
			pRightEntryCellInSim->SetState(OnboardCellInSim::Idle);
			GetGround()->getLogicMap().setTileAsBarrier(pRightEntryCellInSim->getTileIndex(), false);
			dRayRight = rayPathRight.m_Out.front().m_dist;
			if (dRayRight < dRayLeft)
			{
				if (pEntryPointInSim)
				{
					delete pEntryPointInSim;
					pEntryPointInSim = NULL;
				}
				pEntryPointInSim = new EntryPointInSim(pRightEntryCellInSim,m_pFlightInSim);
				pEntryPointInSim->SetWalkType(EntryPointInSim::TurnDirection_Walk);
				pEntryPointInSim->SetCreateSeat(this);
			}
		}
		
	}

	return pEntryPointInSim;
}
bool CDeathPirate::CheckCollision(CBase* pBase)
{
	CBase::CheckCollision( pBase );
	
	if(pBase->GetType() == OBJ_BLOCK)
	{
		CBlock* BLOCK = (CBlock*)pBase;

		RECT rIntersect;

		//Descriptive replacement variables
		RECT rMyRect = { (LONG)GetPosX(), (LONG)GetPosY(), 0, 0 };
		rMyRect.right = rMyRect.left + GetWidth();
		rMyRect.bottom = rMyRect.top + GetHeight();

		RECT rHisRect = { (LONG)BLOCK->GetPosX(), (LONG)BLOCK->GetPosY(), 0, 0 };
		rHisRect.right = rHisRect.left + BLOCK->GetWidth();
		rHisRect.bottom = rHisRect.top + BLOCK->GetHeight();

		if( IntersectRect( &rIntersect, &rMyRect, &rHisRect ) )
		{
			if( (rIntersect.right-rIntersect.left) > (rIntersect.bottom-rIntersect.top) )
			{
				if(BLOCK->GetBlock() == BLOCK_SOLID || BLOCK->GetBlock() == BLOCK_MOVING || BLOCK->GetBlock() == BLOCK_PARTIAL || BLOCK->GetBlock() == BLOCK_UNSTABLE)
				{
					if(rMyRect.bottom > rHisRect.top && rMyRect.top < rHisRect.top)
					{
						SetPosY( (float)rHisRect.top - GetHeight() );
						SetGround(true);
						SetBaseVelY(0);
						SetCollision(true);
					}
					else if(rMyRect.top < rHisRect.bottom && rMyRect.bottom > rHisRect.top)
						SetPosY((float)rHisRect.bottom);

				}
				else if(BLOCK->GetBlock() == BLOCK_TRAP)
				{
					SetGround(true);
					SetCollision(true);
					SetBaseVelY(0);
				}

			}
			else if((rIntersect.right-rIntersect.left) < (rIntersect.bottom-rIntersect.top))
			{
				if(BLOCK->GetBlock() == BLOCK_SOLID || BLOCK->GetBlock() == BLOCK_MOVING || BLOCK->GetBlock() == BLOCK_PARTIAL)
				{
				}
				else if(BLOCK->GetBlock() == BLOCK_TRAP)
				{
					SetGround(true);
					SetCollision(true);
					SetBaseVelY(0);
				}
			}
			return true;
		}
	}

	if(GetGround() && GetCollision() == false)
	{
		SetGround(false);
	}

	return false;
}