示例#1
0
void World::Step()
{
	float delta = (float)mTimer.GetDelta();
	delta = min(delta, 0.1f);

	timeBank += delta;

	deltaTime = 0.01f;
	deltaTimeScaled = deltaTime * DeltaTimeScalingFactor;
	deltaTimeScaledSquared = deltaTimeScaled * deltaTimeScaled;

#if DEBUG || 1
	timeBank = deltaTime + (deltaTime/2);
#endif

	//while(timeBank > deltaTime)
	{
		//CalculateViscoElasticity();
		UpdateGrid();
		CalculateDensity();
		CalculatePressure();
		UpdateParticles();
		DoCollision();

		timeBank -= deltaTime;
	}
}
示例#2
0
ParticleSystem::ParticleSystem(Vector3 min, Vector3 max, int n, float hVal){
    bMin = min;
    bMax = max;
    NumParticles = n;
    domain = bMax - bMin;
    boxSize = bMax - bMin;
    h = 0.5;
    supportRadius = h*2.0;
    fluid_viscosity = 3;
    particle_mass = 1.98;
    k = 1.0;
    restDensity = 1000;
    int xRange = (int)ceil(domain.x/h);
    int yRange = (int)ceil(domain.y/h);
    int zRange = (int)ceil(domain.z/h);
    grid = new Grid(xRange, yRange, zRange);
    printf("bMin: %f %f %f", bMin.x, bMin.y, bMin.z);

    float v = 0.0;
    for(Plane * w: walls){
        w->color.Set(v, 1.0, 1.0);
        v += 0.2;
    }
    printf("Walls: %lu", walls.size());
    Init();
    initKernelFunctions();
    UpdateGrid();
}
示例#3
0
afx_msg void CTuConfigTUDlg::OnAdd()
{
	if(!SaveGrid())
		return;
	
	CTu tu;
	if(m_nProcType == PROT_MODBUS)
	{
		tu.TYPE_PRIBOR=1;
		tu.FUNCTION = 5;
	}
	if(m_nProcType == PROT_SPA)
	{		
		tu.FUNCTION = 2;
		tu.DATATU_ON = 1;
		tu.DATATU_OFF = 0;
	}
	if((m_nProcType == PROT_IEC101)||(m_nProcType == PROT_IEC104))
	{
		tu.TYPE_PRIBOR=2;			
		tu.FUNCTION = 45;
	}
	if(m_nProcType == PROT_IEC103)
	{
		tu.TYPE_PRIBOR=2;
		tu.FUNCTION = 20;
		tu.DATATU_OFF = 1;
		tu.DATATU_ON = 2;
	}	
	m_TuArray.Add(tu);
	UpdateGrid();
	m_Grid.EnsureVisible(m_Grid.GetRowCount()-1,0);
}
示例#4
0
void CCmpPathfinder::HandleMessage(const CMessage& msg, bool UNUSED(global))
{
	switch (msg.GetType())
	{
	case MT_RenderSubmit:
	{
		const CMessageRenderSubmit& msgData = static_cast<const CMessageRenderSubmit&> (msg);
		RenderSubmit(msgData.collector);
		break;
	}
	case MT_TerrainChanged:
		m_TerrainDirty = true;
		MinimalTerrainUpdate();
		break;
	case MT_WaterChanged:
	case MT_ObstructionMapShapeChanged:
		m_TerrainDirty = true;
		UpdateGrid();
		m_PreserveUpdateInformations = true;
		break;
	case MT_TurnStart:
		m_SameTurnMovesCount = 0;
		break;
	}
}
示例#5
0
BOOL CRetrConfigDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	
	this->GetWindowRect(&m_Rect);	

	m_Grid.SetColumnCount(6);
	m_Grid.SetFixedColumnCount(1);
	m_Grid.SetFixedRowCount(1);
	m_Grid.SetRowCount(1);
	m_Grid.SetItemText(0,0,"№");
	m_Grid.SetItemText(0,1,"Нач.адрес в карте памяти");
	m_Grid.SetItemText(0,2,"Нач.адрес ретрансляции");
	m_Grid.SetItemText(0,3,"Количество инф.объектов");
	m_Grid.SetItemText(0,4,"Процесс ретрансляции");
	m_Grid.SetItemText(0,5,"Комментарий");
	
	UpdateGrid();

	if(((CKPLConfigApp*)(AfxGetApp()))->m_KPLProject.m_Main_Set.m_nVersion < 14)
	{
		CWnd* pWnd = this->GetDlgItem(IDC_BUTTON1);
		pWnd->ShowWindow(SW_HIDE);
	}

	return TRUE;  // return TRUE unless you set the focus to a control
	// Исключение: страница свойств OCX должна возвращать значение FALSE
}
示例#6
0
afx_msg void CRetrConfigDlg::OnDel()
{	
	CCellID SelectedCell;
	CWordArray arGrigIndexes;	

	for(int m = 1; m < m_Grid.GetRowCount(); m++)
	{
		SelectedCell.row=m;
		SelectedCell.col=0;
		BOOL bRowSelected = FALSE;
		for(int s = 1; s < m_Grid.GetColumnCount(); s++)
		{
			if(m_Grid.GetItemState(SelectedCell.row,s) & GVIS_SELECTED)
			{
				bRowSelected=TRUE;
				break;
			}
		}
		if(bRowSelected)
		{			
			arGrigIndexes.Add(SelectedCell.row);								
		}
	}
	for(int j = 0; j < arGrigIndexes.GetSize();j++)
	{				
		m_Grid.DeleteRow(arGrigIndexes[j]);				
		m_Retr.m_ManyRetrArray.RemoveAt(arGrigIndexes[j]-1);				
		for(int v = j+1; v < arGrigIndexes.GetSize();v++)
		{
			arGrigIndexes[v]--;
		}
	}	
	SaveGrid();		
	UpdateGrid();
}
示例#7
0
//-----------------------------------------------------------------------------
// Name: OnMovementTimer()
// Desc: Periodically updates the position of the object 
//-----------------------------------------------------------------------------
VOID OnMovementTimer( HWND hDlg ) 
{
    FLOAT fXScale;
    FLOAT fYScale;

    if( !g_bAllowMovementTimer )
        return;

    HWND hHorzSlider = GetDlgItem( hDlg, IDC_HORIZONTAL_SLIDER );
    HWND hVertSlider = GetDlgItem( hDlg, IDC_VERTICAL_SLIDER );

    fXScale = SendMessage( hHorzSlider, TBM_GETPOS, 0, 0 ) / 100.0f;
    fYScale = SendMessage( hVertSlider, TBM_GETPOS, 0, 0 ) / 100.0f;
    FLOAT t = timeGetTime()/1000.0f;

    // Move the sound object around the listener. The maximum radius of the
    // orbit is 27.5 units.
    D3DVECTOR vPosition;
    vPosition.x = ORBIT_MAX_RADIUS * fXScale * (FLOAT)sin(t);
    vPosition.y = 0.0f;
    vPosition.z = ORBIT_MAX_RADIUS * fYScale * (FLOAT)cos(t);

    D3DVECTOR vVelocity;
    vVelocity.x = ORBIT_MAX_RADIUS * fXScale * (FLOAT)sin(t+0.05f);
    vVelocity.y = 0.0f;
    vVelocity.z = ORBIT_MAX_RADIUS * fYScale * (FLOAT)cos(t+0.05f);

    // Show the object's position on the dialog's grid control
    UpdateGrid( hDlg, vPosition.x, vPosition.z );

    // Set the sound buffer velocity and position
    SetObjectProperties( &vPosition, &vVelocity );
}
示例#8
0
bool CCmpPathfinder::CheckUnitPlacement(const IObstructionTestFilter& filter,
	entity_pos_t x, entity_pos_t z, entity_pos_t r,	pass_class_t passClass)
{
	// Check unit obstruction
	CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
	if (cmpObstructionManager.null())
		return false;

	if (cmpObstructionManager->TestUnitShape(filter, x, z, r, NULL))
		return false;

	// Test against terrain:

	UpdateGrid();

	u16 i0, j0, i1, j1;
	NearestTile(x - r, z - r, i0, j0);
	NearestTile(x + r, z + r, i1, j1);
	for (u16 j = j0; j <= j1; ++j)
	{
		for (u16 i = i0; i <= i1; ++i)
		{
			if (!IS_TERRAIN_PASSABLE(m_Grid->get(i,j), passClass))
			{
				return false;
			}
		}
	}
	return true;
}
示例#9
0
void CFilterPageImpl::SetFilters(const std::vector<Filter>& filters)
{
	m_filters = filters;
	if (IsWindow())
	{
		UpdateGrid();
	}
}
示例#10
0
void ParticleSystem::Update(float deltaTime){
    
    UpdateGrid();
    clearAcceleration();
    computeDenisty();
    computePressure();
    checkWallCollisions();
    step(deltaTime);
}
示例#11
0
void CPlayer::DetectCollision(float fElapsedTime) {
	bool bDuck((m_eCurState & EAS_Duck)>0), bUpdateX(false), bUpdateY(false);
	UpdateGrid(bDuck);
	if (m_iRowFoot >= MAX_ROW) return;
	short sCollision(0); bool bEdge(m_iCol+1 <= m_fMaxCol/BLOCKLENGTH);
	if (m_tiles[m_iRow][m_iCol] > EBT_BlockMin)						sCollision += EGC_11;
	if (bEdge && m_tiles[m_iRow][m_iCol+1] > EBT_BlockMin)			sCollision += EGC_12;
	if (m_tiles[m_iRow+1][m_iCol] > EBT_BlockMin)					sCollision += EGC_21;
	if (bEdge && m_tiles[m_iRow+1][m_iCol+1] > EBT_BlockMin)		sCollision += EGC_22;
	if (m_iRow+2 < MAX_ROW) {
		if (m_tiles[m_iRow+2][m_iCol] > EBT_BlockMin)				sCollision += EGC_31;
		if (bEdge && m_tiles[m_iRow+2][m_iCol+1] > EBT_BlockMin)	sCollision += EGC_32;
	}

	if (bDuck) {
		if (m_vecVel.y > 0.f) {
			bUpdateY = DetectPixelColl(sCollision & EGC_MID);
		} else if (m_vecVel.y < 0.f) {
			bUpdateY = DetectPixelColl(sCollision & EGC_UP);
		}
		if (m_vecVel.x > 0.f) {
			bUpdateX = DetectPixelColl(sCollision & EGC_12);
		} else if (m_vecVel.x < 0.f) {
			bUpdateX = DetectPixelColl(sCollision & EGC_11);
		}
	} else {
		if (m_vecVel.y > 0.f) {
			bUpdateY = DetectPixelColl(sCollision & 
				(In3Grid()?EGC_DOWN:EGC_MID));
		} else if (m_vecVel.y < 0.f) {
			bUpdateY = DetectPixelColl(sCollision & EGC_UP);
		}
		if (bUpdateY) {
			m_vecPos.y -= m_vecVel.y * fElapsedTime;
			m_vecVel.y = m_vecVel.y < 0.f ? .1f : 0.f;
			UpdateGridY(bDuck);
			bUpdateY = false;
		}
		if (m_vecVel.x > 0.f) {
			bUpdateX = DetectPixelColl(sCollision & 
				((In3Grid()&&m_vecVel.y)?EGC_RIGHT:EGC_SHORT_RIGHT));
		} else if (m_vecVel.x < 0.f) {
			bUpdateX = DetectPixelColl(sCollision & 
				((In3Grid()&&m_vecVel.y)?EGC_LEFT:EGC_SHORT_LEFT));
		}
	}
	if (bUpdateY) {
		m_vecPos.y -= m_vecVel.y * fElapsedTime;
		m_vecVel.y = m_vecVel.y < 0.f ? .1f : 0.f;
		UpdateGridY(bDuck);
	}
	if (bUpdateX) {
		m_vecPos.x -= m_vecVel.x * fElapsedTime;
		m_vecVel.x = 0.f;
		UpdateGridX(bDuck);
	}
}
示例#12
0
fixed CCmpPathfinder::GetMovementSpeed(entity_pos_t x0, entity_pos_t z0, u8 costClass)
{
	UpdateGrid();

	u16 i, j;
	NearestTile(x0, z0, i, j);
	TerrainTile tileTag = m_Grid->get(i, j);
	return m_MoveSpeeds.at(costClass).at(GET_COST_CLASS(tileTag));
}
示例#13
0
ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckBuildingPlacement(const IObstructionTestFilter& filter,
	entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w,
	entity_pos_t h, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint)
{
	// Check unit obstruction
	CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
	if (!cmpObstructionManager)
		return ICmpObstruction::FOUNDATION_CHECK_FAIL_ERROR;

	if (cmpObstructionManager->TestStaticShape(filter, x, z, a, w, h, NULL))
		return ICmpObstruction::FOUNDATION_CHECK_FAIL_OBSTRUCTS_FOUNDATION;

	// Test against terrain:

	UpdateGrid();

	ICmpObstructionManager::ObstructionSquare square;
	CmpPtr<ICmpObstruction> cmpObstruction(GetSimContext(), id);
	if (!cmpObstruction || !cmpObstruction->GetObstructionSquare(square))
		return ICmpObstruction::FOUNDATION_CHECK_FAIL_NO_OBSTRUCTION;

	if (onlyCenterPoint)
	{
		u16 i, j;
		NearestTile(x, z, i, j);

		if (IS_TERRAIN_PASSABLE(m_Grid->get(i,j), passClass))
			return ICmpObstruction::FOUNDATION_CHECK_SUCCESS;

		return ICmpObstruction::FOUNDATION_CHECK_FAIL_TERRAIN_CLASS;
	}

	// Expand bounds by 1/sqrt(2) tile (multiply by TERRAIN_TILE_SIZE since we want world coordinates)
	entity_pos_t expand = entity_pos_t::FromInt(2).Sqrt().Multiply(entity_pos_t::FromInt(TERRAIN_TILE_SIZE / 2));
	CFixedVector2D halfSize(square.hw + expand, square.hh + expand);
	CFixedVector2D halfBound = Geometry::GetHalfBoundingBox(square.u, square.v, halfSize);

	u16 i0, j0, i1, j1;
	NearestTile(square.x - halfBound.X, square.z - halfBound.Y, i0, j0);
	NearestTile(square.x + halfBound.X, square.z + halfBound.Y, i1, j1);
	for (u16 j = j0; j <= j1; ++j)
	{
		for (u16 i = i0; i <= i1; ++i)
		{
			entity_pos_t x, z;
			TileCenter(i, j, x, z);
			if (Geometry::PointIsInSquare(CFixedVector2D(x - square.x, z - square.z), square.u, square.v, halfSize)
				&& !IS_TERRAIN_PASSABLE(m_Grid->get(i,j), passClass))
			{
				return ICmpObstruction::FOUNDATION_CHECK_FAIL_TERRAIN_CLASS;
			}
		}
	}

	return ICmpObstruction::FOUNDATION_CHECK_SUCCESS;
}
示例#14
0
const Grid<u16>& CCmpPathfinder::GetPassabilityGrid()
{
	if (!m_Grid)
	{
		UpdateGrid();
		m_PreserveUpdateInformations = true;
	}

	return *m_Grid;
}
示例#15
0
void Level00::VUpdate(double milliseconds)
{
	HandleInput(*mInput);
	mNetworkManager->Update();

	UpdateExplorers(milliseconds);
	UpdateGrid();
	UpdateRobots();

}
示例#16
0
void CSourcesDlg::OnAdd(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/)
{
	CSourceDlg dlg(L"UDP port 2020", SourceType::Udp, L"192.168.1.1", 2020);
	if (dlg.DoModal() != IDOK)
		return;

	auto info = SourceInfo(dlg.GetName(), dlg.GetSourceType(), dlg.GetAddress(), dlg.GetPort());
	info.enabled = true;
	m_sourceInfos.push_back(info);
	UpdateGrid();
}
示例#17
0
afx_msg void CTuConfigTUDlg::OnAddDiapason()
{
	CAddDiapTUDlg dlg;
	dlg.m_nProcType = m_nProcType;
	if(dlg.DoModal() == IDOK)
	{ 
		m_TuArray.Append(dlg.m_TuArray);
	}
	UpdateGrid();
	m_Grid.EnsureVisible(m_Grid.GetRowCount()-1,0);
}	
示例#18
0
afx_msg void CRetrConfigDlg::OnAdd()
{
	if(!SaveGrid())
		return;
	ManyRetr ManyRetr1;
	if((m_Retr.m_ManyRetrArray.GetSize() == 0)||(m_Grid.GetFocusCell().row == m_Grid.GetRowCount()-1))
	{
		m_Retr.m_ManyRetrArray.Add(ManyRetr1);
		UpdateGrid();
		m_Grid.EnsureVisible(m_Grid.GetRowCount()-1,0);
	}
	else
	{
		if(m_Grid.GetFocusCell().row > 0)
		{
			m_Retr.m_ManyRetrArray.InsertAt(m_Grid.GetFocusCell().row,ManyRetr1);
			UpdateGrid();		
		}
	}
	
}
示例#19
0
BOOL CSourcesDlg::OnInitDialog(CWindow /*wndFocus*/, LPARAM /*lInitParam*/)
{
	m_grid.SubclassWindow(GetDlgItem(IDC_SOURCES_GRID));
	m_grid.InsertColumn(0, L"", LVCFMT_LEFT, 32, 0);
	m_grid.InsertColumn(1, L"Source description", LVCFMT_LEFT, 280, 0);
	m_grid.InsertColumn(2, L"Type", LVCFMT_LEFT, 100, 0);
	m_grid.InsertColumn(3, L"", LVCFMT_LEFT, 16, 0);
	m_grid.SetExtendedGridStyle(PGS_EX_SINGLECLICKEDIT);

	UpdateGrid();
	CenterWindow(GetParent());
	DlgResize_Init();
	return TRUE;
}
示例#20
0
afx_msg void CRetrConfigDlg::OnAddDiapason()
{
	if(!SaveGrid())
		return;

	CAddDiapRetr dlg;
	dlg.m_Main_Set = m_Main_Set;
	dlg.m_Retr = m_Retr;
	if(dlg.DoModal()==IDOK)
	{
		m_Retr = dlg.m_Retr;
		UpdateGrid();
	}
}	
示例#21
0
BOOL CFilterPageImpl::OnInitDialog(CWindow /*wndFocus*/, LPARAM /*lInitParam*/)
{
	m_grid.SubclassWindow(GetDlgItem(IDC_FILTER_GRID));
	m_grid.InsertColumn(0, L"Filter", LVCFMT_LEFT, 200, 0, -1, 1);
	m_grid.InsertColumn(1, L"", LVCFMT_LEFT, 32, 0, -1, 0);
	m_grid.InsertColumn(2, L"Match", LVCFMT_LEFT, 60, 0, -1, 2);
	m_grid.InsertColumn(3, L"Type", LVCFMT_LEFT, 60, 0, -1, 3);
	m_grid.InsertColumn(4, L"Bg", LVCFMT_LEFT, 24, 0, -1, 4);
	m_grid.InsertColumn(5, L"Fg", LVCFMT_LEFT, 24, 0, -1, 5);
	m_grid.InsertColumn(6, L"", LVCFMT_LEFT, 16, 0, -1, 6);
	m_grid.SetExtendedGridStyle(PGS_EX_SINGLECLICKEDIT | PGS_EX_ADDITEMATEND);

	UpdateGrid();
	DlgResize_Init(false);
	return TRUE;
}
示例#22
0
bool CCmpPathfinder::CheckMovement(const IObstructionTestFilter& filter,
	entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, entity_pos_t r,
	pass_class_t passClass)
{
	CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
	if (cmpObstructionManager.null())
		return false;

	if (cmpObstructionManager->TestLine(filter, x0, z0, x1, z1, r))
		return false;

	// Test against terrain:

	// (TODO: this could probably be a tiny bit faster by not reusing all the vertex computation code)

	UpdateGrid();

	std::vector<Edge> edgesAA;
	std::vector<Vertex> vertexes;

	u16 i0, j0, i1, j1;
	NearestTile(std::min(x0, x1) - r, std::min(z0, z1) - r, i0, j0);
	NearestTile(std::max(x0, x1) + r, std::max(z0, z1) + r, i1, j1);
	AddTerrainEdges(edgesAA, vertexes, i0, j0, i1, j1, r, passClass, *m_Grid);

	CFixedVector2D a(x0, z0);
	CFixedVector2D b(x1, z1);

	std::vector<EdgeAA> edgesLeft;
	std::vector<EdgeAA> edgesRight;
	std::vector<EdgeAA> edgesBottom;
	std::vector<EdgeAA> edgesTop;
	SplitAAEdges(a, edgesAA, edgesLeft, edgesRight, edgesBottom, edgesTop);

	bool visible =
		CheckVisibilityLeft(a, b, edgesLeft) &&
		CheckVisibilityRight(a, b, edgesRight) &&
		CheckVisibilityBottom(a, b, edgesBottom) &&
		CheckVisibilityTop(a, b, edgesTop);

	return visible;
}
示例#23
0
afx_msg void CTuConfigTUDlg::OnDel()
{
	CCellID SelectedCell;
	CWordArray arGrigIndexes;	

	for(int m = 1; m < m_Grid.GetRowCount(); m++)
	{
		SelectedCell.row=m;
		SelectedCell.col=0;
		BOOL bRowSelected = FALSE;
		for(int s = 1; s < m_Grid.GetColumnCount(); s++)
		{
			if(m_Grid.GetItemState(SelectedCell.row,s) & GVIS_SELECTED)
			{
				bRowSelected=TRUE;
				break;
			}
		}
		if(bRowSelected)
		{			
			arGrigIndexes.Add(SelectedCell.row);								
		}
	}
	for(int j = 0; j < arGrigIndexes.GetSize();j++)
	{				
		m_Grid.DeleteRow(arGrigIndexes[j]);				
		m_TuArray.RemoveAt(arGrigIndexes[j]-1);				
		for(int v = j+1; v < arGrigIndexes.GetSize();v++)
		{
			arGrigIndexes[v]--;
		}
	}	
	/*CCellID pCell = m_Grid.GetFocusCell();
	
	if((pCell.row > 0)&&(pCell.col >= 0))
	{
		m_TuArray.RemoveAt(pCell.row-1);		
	}*/
	SaveGrid();	
	UpdateGrid();
}
示例#24
0
ICmpObstruction::EFoundationCheck CCmpPathfinder::CheckUnitPlacement(const IObstructionTestFilter& filter,
	entity_pos_t x, entity_pos_t z, entity_pos_t r,	pass_class_t passClass, bool onlyCenterPoint)
{
	// Check unit obstruction
	CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
	if (!cmpObstructionManager)
		return ICmpObstruction::FOUNDATION_CHECK_FAIL_ERROR;

	if (cmpObstructionManager->TestUnitShape(filter, x, z, r, NULL))
		return ICmpObstruction::FOUNDATION_CHECK_FAIL_OBSTRUCTS_FOUNDATION;

	// Test against terrain:

	UpdateGrid();
	
	if (onlyCenterPoint)
	{
		u16 i, j;
		NearestTile(x , z, i, j);

		if (IS_TERRAIN_PASSABLE(m_Grid->get(i,j), passClass))
			return ICmpObstruction::FOUNDATION_CHECK_SUCCESS;

		return ICmpObstruction::FOUNDATION_CHECK_FAIL_TERRAIN_CLASS;
	}

	u16 i0, j0, i1, j1;
	NearestTile(x - r, z - r, i0, j0);
	NearestTile(x + r, z + r, i1, j1);
	for (u16 j = j0; j <= j1; ++j)
	{
		for (u16 i = i0; i <= i1; ++i)
		{
			if (!IS_TERRAIN_PASSABLE(m_Grid->get(i,j), passClass))
			{
				return ICmpObstruction::FOUNDATION_CHECK_FAIL_TERRAIN_CLASS;
			}
		}
	}
	return ICmpObstruction::FOUNDATION_CHECK_SUCCESS;
}
示例#25
0
void CCmpPathfinder::ComputePath(entity_pos_t x0, entity_pos_t z0, const Goal& goal, pass_class_t passClass, cost_class_t costClass, Path& path)
{
	UpdateGrid();

	PROFILE("ComputePath");

	PathfinderState state = { 0 };

	// Convert the start/end coordinates to tile indexes
	u16 i0, j0;
	NearestTile(x0, z0, i0, j0);
	NearestTile(goal.x, goal.z, state.iGoal, state.jGoal);

	// If we're already at the goal tile, then move directly to the exact goal coordinates
	if (AtGoal(i0, j0, goal))
	{
		Waypoint w = { goal.x, goal.z };
		path.m_Waypoints.push_back(w);
		return;
	}

	// If the target is a circle, we want to aim for the edge of it (so e.g. if we're inside
	// a large circle then the heuristics will aim us directly outwards);
	// otherwise just aim at the center point. (We'll never try moving outwards to a square shape.)
	if (goal.type == Goal::CIRCLE)
		state.rGoal = (goal.hw / (int)CELL_SIZE).ToInt_RoundToZero();
	else
		state.rGoal = 0;

	state.passClass = passClass;
	state.moveCosts = m_MoveCosts.at(costClass);

	state.steps = 0;

	state.tiles = new PathfindTileGrid(m_MapSize, m_MapSize);
	state.terrain = m_Grid;

	state.iBest = i0;
	state.jBest = j0;
	state.hBest = CalculateHeuristic(i0, j0, state.iGoal, state.jGoal, state.rGoal);

	PriorityQueue::Item start = { std::make_pair(i0, j0), 0 };
	state.open.push(start);
	state.tiles->get(i0, j0).SetStatusOpen();
	state.tiles->get(i0, j0).SetPred(i0, j0, i0, j0);
	state.tiles->get(i0, j0).cost = 0;

	// To prevent units getting very stuck, if they start on an impassable tile
	// surrounded entirely by impassable tiles, we ignore the impassability
	state.ignoreImpassable = !IS_PASSABLE(state.terrain->get(i0, j0), state.passClass);

	while (1)
	{
		++state.steps;

		// Hack to avoid spending ages computing giant paths, particularly when
		// the destination is unreachable
		if (state.steps > 40000)
			break;

		// If we ran out of tiles to examine, give up
		if (state.open.empty())
			break;

#if PATHFIND_STATS
		state.sumOpenSize += state.open.size();
#endif

		// Move best tile from open to closed
		PriorityQueue::Item curr = state.open.pop();
		u16 i = curr.id.first;
		u16 j = curr.id.second;
		state.tiles->get(i, j).SetStatusClosed();

		// If we've reached the destination, stop
		if (AtGoal(i, j, goal))
		{
			state.iBest = i;
			state.jBest = j;
			state.hBest = 0;
			break;
		}

		// As soon as we find an escape route from the impassable terrain,
		// take it and forbid any further use of impassable tiles
		if (state.ignoreImpassable)
		{
			if (i > 0 && IS_PASSABLE(state.terrain->get(i-1, j), state.passClass))
				state.ignoreImpassable = false;
			else if (i < m_MapSize-1 && IS_PASSABLE(state.terrain->get(i+1, j), state.passClass))
				state.ignoreImpassable = false;
			else if (j > 0 && IS_PASSABLE(state.terrain->get(i, j-1), state.passClass))
				state.ignoreImpassable = false;
			else if (j < m_MapSize-1 && IS_PASSABLE(state.terrain->get(i, j+1), state.passClass))
				state.ignoreImpassable = false;
		}

		u32 g = state.tiles->get(i, j).cost;
		if (i > 0)
			ProcessNeighbour(i, j, i-1, j, g, state);
		if (i < m_MapSize-1)
			ProcessNeighbour(i, j, i+1, j, g, state);
		if (j > 0)
			ProcessNeighbour(i, j, i, j-1, g, state);
		if (j < m_MapSize-1)
			ProcessNeighbour(i, j, i, j+1, g, state);
	}

	// Reconstruct the path (in reverse)
	u16 ip = state.iBest, jp = state.jBest;
	while (ip != i0 || jp != j0)
	{
		PathfindTile& n = state.tiles->get(ip, jp);
		entity_pos_t x, z;
		TileCenter(ip, jp, x, z);
		Waypoint w = { x, z };
		path.m_Waypoints.push_back(w);

		// Follow the predecessor link
		ip = n.GetPredI(ip);
		jp = n.GetPredJ(jp);
	}

	// Save this grid for debug display
	delete m_DebugGrid;
	m_DebugGrid = state.tiles;
	m_DebugSteps = state.steps;

#if PATHFIND_STATS
	printf("PATHFINDER: steps=%d avgo=%d proc=%d impc=%d impo=%d addo=%d\n", state.steps, state.sumOpenSize/state.steps, state.numProcessed, state.numImproveClosed, state.numImproveOpen, state.numAddToOpen);
#endif
}
示例#26
0
const Grid<u16>& CCmpPathfinder::GetPassabilityGrid()
{
	UpdateGrid();
	return *m_Grid;
}
void Editor::Run(){
	if(!paused){

		quit_btn->Update(mx,my,mst);
		if(quit_btn->GetState() == BTT_PRESSED){
			halt = true;
		}

		level_path->Update(mx,my,mst);
		load_btn->Update(mx,my,mst);
		switch(edit_mode){
		//load mode
		case 1:
			
			if(load_btn->GetState() == BTT_PRESSED){
				std::string load;

				if(!level_path->GetText().empty()){
					load = level_path->GetText().front();
				}

				load.insert(0,LVL_FOLDER);

				lvl_file = fopen(load.c_str(),"rb");


				if(lvl_file != 0){

					for(int i = 0;i < F_HEIGHT;i++){
						for(int j = 0; j < F_WIDTH;j++){
							if(!feof(lvl_file)){
								int pos = (F_WIDTH*i + j);
								fseek(lvl_file,pos*sizeof(Block),SEEK_SET);
								fread(&grid[i][j],sizeof(Block),1,lvl_file);
							}
						}
					}



					laststat = "Loaded "+load;
					fclose(lvl_file);
				}else{
					laststat = "Failed to load "+load;
				}


				level_path->Clear();
				edit_mode = 2;
				mx = my = mst = 0;
			}

			break;
		//edit/save/close mode
		case 2:

			if(load_btn->GetState() == BTT_PRESSED){
				std::string save;

				if(!level_path->GetText().empty()){
					save = level_path->GetText().front();
				}

				save.insert(0,LVL_FOLDER);

				lvl_file = fopen(save.c_str(),"wb");


				if(lvl_file != 0){

					for(int i = 0;i < F_HEIGHT;i++){
						for(int j = 0; j < F_WIDTH;j++){
							int pos = (F_WIDTH*i + j);
							fseek(lvl_file,pos*sizeof(Block),SEEK_SET);
							fwrite(&grid[i][j],sizeof(Block),1,lvl_file);
						}
					}

					laststat = "Saved to "+save;
					fclose(lvl_file);
				}else{
					laststat = "Failed to save "+save;
				}

				level_path->Clear();
				Init();
				edit_mode = 1;
				mx = my = mst = 0;
			}

			if(close_btn->GetState() == BTT_PRESSED){
				Init();
				laststat = "";
				edit_mode = 1;
				mx = my = mst = 0;
			}

			UpdateGrid();

			close_btn->Update(mx,my,mst);
			break;
		}
	}
}
示例#28
0
void CCmpPathfinder::ComputeShortPath(const IObstructionTestFilter& filter,
	entity_pos_t x0, entity_pos_t z0, entity_pos_t r,
	entity_pos_t range, const Goal& goal, pass_class_t passClass, Path& path)
{
	UpdateGrid(); // TODO: only need to bother updating if the terrain changed

	PROFILE("ComputeShortPath");
//	ScopeTimer UID__(L"ComputeShortPath");

	m_DebugOverlayShortPathLines.clear();

	if (m_DebugOverlay)
	{
		// Render the goal shape
		m_DebugOverlayShortPathLines.push_back(SOverlayLine());
		m_DebugOverlayShortPathLines.back().m_Color = CColor(1, 0, 0, 1);
		switch (goal.type)
		{
		case CCmpPathfinder::Goal::POINT:
		{
			SimRender::ConstructCircleOnGround(GetSimContext(), goal.x.ToFloat(), goal.z.ToFloat(), 0.2f, m_DebugOverlayShortPathLines.back(), true);
			break;
		}
		case CCmpPathfinder::Goal::CIRCLE:
		{
			SimRender::ConstructCircleOnGround(GetSimContext(), goal.x.ToFloat(), goal.z.ToFloat(), goal.hw.ToFloat(), m_DebugOverlayShortPathLines.back(), true);
			break;
		}
		case CCmpPathfinder::Goal::SQUARE:
		{
			float a = atan2f(goal.v.X.ToFloat(), goal.v.Y.ToFloat());
			SimRender::ConstructSquareOnGround(GetSimContext(), goal.x.ToFloat(), goal.z.ToFloat(), goal.hw.ToFloat()*2, goal.hh.ToFloat()*2, a, m_DebugOverlayShortPathLines.back(), true);
			break;
		}
		}
	}

	// List of collision edges - paths must never cross these.
	// (Edges are one-sided so intersections are fine in one direction, but not the other direction.)
	std::vector<Edge> edges;
	std::vector<Edge> edgesAA; // axis-aligned squares

	// Create impassable edges at the max-range boundary, so we can't escape the region
	// where we're meant to be searching
	fixed rangeXMin = x0 - range;
	fixed rangeXMax = x0 + range;
	fixed rangeZMin = z0 - range;
	fixed rangeZMax = z0 + range;
	{
		// (The edges are the opposite direction to usual, so it's an inside-out square)
		Edge e0 = { CFixedVector2D(rangeXMin, rangeZMin), CFixedVector2D(rangeXMin, rangeZMax) };
		Edge e1 = { CFixedVector2D(rangeXMin, rangeZMax), CFixedVector2D(rangeXMax, rangeZMax) };
		Edge e2 = { CFixedVector2D(rangeXMax, rangeZMax), CFixedVector2D(rangeXMax, rangeZMin) };
		Edge e3 = { CFixedVector2D(rangeXMax, rangeZMin), CFixedVector2D(rangeXMin, rangeZMin) };
		edges.push_back(e0);
		edges.push_back(e1);
		edges.push_back(e2);
		edges.push_back(e3);
	}

	// List of obstruction vertexes (plus start/end points); we'll try to find paths through
	// the graph defined by these vertexes
	std::vector<Vertex> vertexes;

	// Add the start point to the graph
	CFixedVector2D posStart(x0, z0);
	fixed hStart = (posStart - NearestPointOnGoal(posStart, goal)).Length();
	Vertex start = { posStart, fixed::Zero(), hStart, 0, Vertex::OPEN, QUADRANT_NONE, QUADRANT_ALL };
	vertexes.push_back(start);
	const size_t START_VERTEX_ID = 0;

	// Add the goal vertex to the graph.
	// Since the goal isn't always a point, this a special magic virtual vertex which moves around - whenever
	// we look at it from another vertex, it is moved to be the closest point on the goal shape to that vertex.
	Vertex end = { CFixedVector2D(goal.x, goal.z), fixed::Zero(), fixed::Zero(), 0, Vertex::UNEXPLORED, QUADRANT_NONE, QUADRANT_ALL };
	vertexes.push_back(end);
	const size_t GOAL_VERTEX_ID = 1;

	// Add terrain obstructions
	{
		u16 i0, j0, i1, j1;
		NearestTile(rangeXMin, rangeZMin, i0, j0);
		NearestTile(rangeXMax, rangeZMax, i1, j1);
		AddTerrainEdges(edgesAA, vertexes, i0, j0, i1, j1, r, passClass, *m_Grid);
	}

	// Find all the obstruction squares that might affect us
	CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSimContext(), SYSTEM_ENTITY);
	std::vector<ICmpObstructionManager::ObstructionSquare> squares;
	cmpObstructionManager->GetObstructionsInRange(filter, rangeXMin - r, rangeZMin - r, rangeXMax + r, rangeZMax + r, squares);

	// Resize arrays to reduce reallocations
	vertexes.reserve(vertexes.size() + squares.size()*4);
	edgesAA.reserve(edgesAA.size() + squares.size()); // (assume most squares are AA)

	// Convert each obstruction square into collision edges and search graph vertexes
	for (size_t i = 0; i < squares.size(); ++i)
	{
		CFixedVector2D center(squares[i].x, squares[i].z);
		CFixedVector2D u = squares[i].u;
		CFixedVector2D v = squares[i].v;

		// Expand the vertexes by the moving unit's collision radius, to find the
		// closest we can get to it

		CFixedVector2D hd0(squares[i].hw + r + EDGE_EXPAND_DELTA, squares[i].hh + r + EDGE_EXPAND_DELTA);
		CFixedVector2D hd1(squares[i].hw + r + EDGE_EXPAND_DELTA, -(squares[i].hh + r + EDGE_EXPAND_DELTA));

		// Check whether this is an axis-aligned square
		bool aa = (u.X == fixed::FromInt(1) && u.Y == fixed::Zero() && v.X == fixed::Zero() && v.Y == fixed::FromInt(1));

		Vertex vert;
		vert.status = Vertex::UNEXPLORED;
		vert.quadInward = QUADRANT_NONE;
		vert.quadOutward = QUADRANT_ALL;
		vert.p.X = center.X - hd0.Dot(u); vert.p.Y = center.Y + hd0.Dot(v); if (aa) vert.quadInward = QUADRANT_BR; vertexes.push_back(vert);
		vert.p.X = center.X - hd1.Dot(u); vert.p.Y = center.Y + hd1.Dot(v); if (aa) vert.quadInward = QUADRANT_TR; vertexes.push_back(vert);
		vert.p.X = center.X + hd0.Dot(u); vert.p.Y = center.Y - hd0.Dot(v); if (aa) vert.quadInward = QUADRANT_TL; vertexes.push_back(vert);
		vert.p.X = center.X + hd1.Dot(u); vert.p.Y = center.Y - hd1.Dot(v); if (aa) vert.quadInward = QUADRANT_BL; vertexes.push_back(vert);

		// Add the edges:

		CFixedVector2D h0(squares[i].hw + r, squares[i].hh + r);
		CFixedVector2D h1(squares[i].hw + r, -(squares[i].hh + r));

		CFixedVector2D ev0(center.X - h0.Dot(u), center.Y + h0.Dot(v));
		CFixedVector2D ev1(center.X - h1.Dot(u), center.Y + h1.Dot(v));
		CFixedVector2D ev2(center.X + h0.Dot(u), center.Y - h0.Dot(v));
		CFixedVector2D ev3(center.X + h1.Dot(u), center.Y - h1.Dot(v));
		if (aa)
		{
			Edge e = { ev1, ev3 };
			edgesAA.push_back(e);
		}
		else
		{
			Edge e0 = { ev0, ev1 };
			Edge e1 = { ev1, ev2 };
			Edge e2 = { ev2, ev3 };
			Edge e3 = { ev3, ev0 };
			edges.push_back(e0);
			edges.push_back(e1);
			edges.push_back(e2);
			edges.push_back(e3);
		}

		// TODO: should clip out vertexes and edges that are outside the range,
		// to reduce the search space
	}

	ENSURE(vertexes.size() < 65536); // we store array indexes as u16

	if (m_DebugOverlay)
	{
		// Render the obstruction edges
		for (size_t i = 0; i < edges.size(); ++i)
		{
			m_DebugOverlayShortPathLines.push_back(SOverlayLine());
			m_DebugOverlayShortPathLines.back().m_Color = CColor(0, 1, 1, 1);
			std::vector<float> xz;
			xz.push_back(edges[i].p0.X.ToFloat());
			xz.push_back(edges[i].p0.Y.ToFloat());
			xz.push_back(edges[i].p1.X.ToFloat());
			xz.push_back(edges[i].p1.Y.ToFloat());
			SimRender::ConstructLineOnGround(GetSimContext(), xz, m_DebugOverlayShortPathLines.back(), true);
		}

		for (size_t i = 0; i < edgesAA.size(); ++i)
		{
			m_DebugOverlayShortPathLines.push_back(SOverlayLine());
			m_DebugOverlayShortPathLines.back().m_Color = CColor(0, 1, 1, 1);
			std::vector<float> xz;
			xz.push_back(edgesAA[i].p0.X.ToFloat());
			xz.push_back(edgesAA[i].p0.Y.ToFloat());
			xz.push_back(edgesAA[i].p0.X.ToFloat());
			xz.push_back(edgesAA[i].p1.Y.ToFloat());
			xz.push_back(edgesAA[i].p1.X.ToFloat());
			xz.push_back(edgesAA[i].p1.Y.ToFloat());
			xz.push_back(edgesAA[i].p1.X.ToFloat());
			xz.push_back(edgesAA[i].p0.Y.ToFloat());
			xz.push_back(edgesAA[i].p0.X.ToFloat());
			xz.push_back(edgesAA[i].p0.Y.ToFloat());
			SimRender::ConstructLineOnGround(GetSimContext(), xz, m_DebugOverlayShortPathLines.back(), true);
		}
	}

	// Do an A* search over the vertex/visibility graph:

	// Since we are just measuring Euclidean distance the heuristic is admissible,
	// so we never have to re-examine a node once it's been moved to the closed set.

	// To save time in common cases, we don't precompute a graph of valid edges between vertexes;
	// we do it lazily instead. When the search algorithm reaches a vertex, we examine every other
	// vertex and see if we can reach it without hitting any collision edges, and ignore the ones
	// we can't reach. Since the algorithm can only reach a vertex once (and then it'll be marked
	// as closed), we won't be doing any redundant visibility computations.

	PROFILE_START("A*");

	PriorityQueue open;
	PriorityQueue::Item qiStart = { START_VERTEX_ID, start.h };
	open.push(qiStart);

	u16 idBest = START_VERTEX_ID;
	fixed hBest = start.h;

	while (!open.empty())
	{
		// Move best tile from open to closed
		PriorityQueue::Item curr = open.pop();
		vertexes[curr.id].status = Vertex::CLOSED;

		// If we've reached the destination, stop
		if (curr.id == GOAL_VERTEX_ID)
		{
			idBest = curr.id;
			break;
		}

		// Sort the edges so ones nearer this vertex are checked first by CheckVisibility,
		// since they're more likely to block the rays
		std::sort(edgesAA.begin(), edgesAA.end(), EdgeSort(vertexes[curr.id].p));

		std::vector<EdgeAA> edgesLeft;
		std::vector<EdgeAA> edgesRight;
		std::vector<EdgeAA> edgesBottom;
		std::vector<EdgeAA> edgesTop;
		SplitAAEdges(vertexes[curr.id].p, edgesAA, edgesLeft, edgesRight, edgesBottom, edgesTop);

		// Check the lines to every other vertex
		for (size_t n = 0; n < vertexes.size(); ++n)
		{
			if (vertexes[n].status == Vertex::CLOSED)
				continue;

			// If this is the magical goal vertex, move it to near the current vertex
			CFixedVector2D npos;
			if (n == GOAL_VERTEX_ID)
			{
				npos = NearestPointOnGoal(vertexes[curr.id].p, goal);

				// To prevent integer overflows later on, we need to ensure all vertexes are
				// 'close' to the source. The goal might be far away (not a good idea but
				// sometimes it happens), so clamp it to the current search range
				npos.X = clamp(npos.X, rangeXMin, rangeXMax);
				npos.Y = clamp(npos.Y, rangeZMin, rangeZMax);
			}
			else
			{
				npos = vertexes[n].p;
			}

			// Work out which quadrant(s) we're approaching the new vertex from
			u8 quad = 0;
			if (vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y <= npos.Y) quad |= QUADRANT_BL;
			if (vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y >= npos.Y) quad |= QUADRANT_TR;
			if (vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y >= npos.Y) quad |= QUADRANT_TL;
			if (vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y <= npos.Y) quad |= QUADRANT_BR;

			// Check that the new vertex is in the right quadrant for the old vertex
			if (!(vertexes[curr.id].quadOutward & quad))
			{
				// Hack: Always head towards the goal if possible, to avoid missing it if it's
				// inside another unit
				if (n != GOAL_VERTEX_ID)
				{
					continue;
				}
			}

			bool visible =
				CheckVisibilityLeft(vertexes[curr.id].p, npos, edgesLeft) &&
				CheckVisibilityRight(vertexes[curr.id].p, npos, edgesRight) &&
				CheckVisibilityBottom(vertexes[curr.id].p, npos, edgesBottom) &&
				CheckVisibilityTop(vertexes[curr.id].p, npos, edgesTop) &&
				CheckVisibility(vertexes[curr.id].p, npos, edges);

			/*
			// Render the edges that we examine
			m_DebugOverlayShortPathLines.push_back(SOverlayLine());
			m_DebugOverlayShortPathLines.back().m_Color = visible ? CColor(0, 1, 0, 0.5) : CColor(1, 0, 0, 0.5);
			std::vector<float> xz;
			xz.push_back(vertexes[curr.id].p.X.ToFloat());
			xz.push_back(vertexes[curr.id].p.Y.ToFloat());
			xz.push_back(npos.X.ToFloat());
			xz.push_back(npos.Y.ToFloat());
			SimRender::ConstructLineOnGround(GetSimContext(), xz, m_DebugOverlayShortPathLines.back(), false);
			//*/

			if (visible)
			{
				fixed g = vertexes[curr.id].g + (vertexes[curr.id].p - npos).Length();

				// If this is a new tile, compute the heuristic distance
				if (vertexes[n].status == Vertex::UNEXPLORED)
				{
					// Add it to the open list:
					vertexes[n].status = Vertex::OPEN;
					vertexes[n].g = g;
					vertexes[n].h = DistanceToGoal(npos, goal);
					vertexes[n].pred = curr.id;

					// If this is an axis-aligned shape, the path must continue in the same quadrant
					// direction (but not go into the inside of the shape).
					// Hack: If we started *inside* a shape then perhaps headed to its corner (e.g. the unit
					// was very near another unit), don't restrict further pathing.
					if (vertexes[n].quadInward && !(curr.id == START_VERTEX_ID && g < fixed::FromInt(8)))
						vertexes[n].quadOutward = ((~vertexes[n].quadInward) & quad) & 0xF;

					if (n == GOAL_VERTEX_ID)
						vertexes[n].p = npos; // remember the new best goal position

					PriorityQueue::Item t = { (u16)n, g + vertexes[n].h };
					open.push(t);

					// Remember the heuristically best vertex we've seen so far, in case we never actually reach the target
					if (vertexes[n].h < hBest)
					{
						idBest = (u16)n;
						hBest = vertexes[n].h;
					}
				}
				else // must be OPEN
				{
					// If we've already seen this tile, and the new path to this tile does not have a
					// better cost, then stop now
					if (g >= vertexes[n].g)
						continue;

					// Otherwise, we have a better path, so replace the old one with the new cost/parent
					vertexes[n].g = g;
					vertexes[n].pred = curr.id;

					// If this is an axis-aligned shape, the path must continue in the same quadrant
					// direction (but not go into the inside of the shape).
					if (vertexes[n].quadInward)
						vertexes[n].quadOutward = ((~vertexes[n].quadInward) & quad) & 0xF;

					if (n == GOAL_VERTEX_ID)
						vertexes[n].p = npos; // remember the new best goal position

					open.promote((u16)n, g + vertexes[n].h);
				}
			}
		}
	}

	// Reconstruct the path (in reverse)
	for (u16 id = idBest; id != START_VERTEX_ID; id = vertexes[id].pred)
	{
		Waypoint w = { vertexes[id].p.X, vertexes[id].p.Y };
		path.m_Waypoints.push_back(w);
	}

	PROFILE_END("A*");
}
bool CGridAnalysis::TransferDataToGrid(
  COARfile *pFile, 
  COARsampleSort *pSort, 
  int nLabelType, 
  int nLabelTypeName, 
  wxDC *pdc)
{

  int nAMEL = -1;
  bool bError = false;

  // set up row/col count
  size_t nRowCount = pSort->GetCount();
  size_t nAlleleColCount = pFile->GetLocusCount();
  size_t nColCount = nAlleleColCount + CFrameAnalysis::FIRST_LOCUS_COLUMN + 1;
  DCholder xxx(this,pdc);
  m_nLabelSize = 0;
  m_setColChannelChange.clear();
  nwxGridBatch xBatch(this);

  bError = (!nRowCount) || (!nAlleleColCount) ||
    (!_SetGridSize((int) nRowCount,(int)nColCount));
  if(!bError)
  {
    // set up column headers
    wxString sLabel;
    wxString sLocus;
    wxString sChannel;
    SetColLabelValue(CFrameAnalysis::STATUS_COLUMN,_T(""));
    SetColLabelValue(CFrameAnalysis::ILS_COLUMN,_T("ILS"));
    SetColLabelValue(CFrameAnalysis::CHANNEL_ALERT_COLUMN,_T("Channels"));
    int nPrevChannel = 0;
    int nChannel;
    int nCol;
    size_t i;
    const COARdirectoryAlerts *pDirAlerts = pFile->GetDirectoryAlerts();

    // set up column labels

    for(i = 0, nCol = CFrameAnalysis::FIRST_LOCUS_COLUMN; i < nAlleleColCount; ++i,++nCol)
    {
      sLocus = pFile->GetLocusName(i);
      nChannel = pFile->GetChannelNr(i);
      sLabel = wxString::Format("%s-%d",sLocus.c_str(),nChannel);
      if(pDirAlerts->GetBaseLocusAlertsByLocus(sLocus) != NULL)
      {
        sLabel.Append(_T(" *"));
      }
      if(nChannel != nPrevChannel)
      {
        m_setColChannelChange.insert(nCol - 1);
        nPrevChannel = nChannel;
      }
      SetColLabelValue(nCol,sLabel);
      if(!strncmp(sLabel.MakeUpper().c_str(),"AMEL",4))
      {
        nAMEL = nCol;
      }
    }
    nCol = (int)nColCount - 1;
    SetColLabelValue(nCol,"+Ctrl");
    m_setColChannelChange.insert(nCol - 1);
    m_setColChannelChange.insert(nCol);

    UpdateGrid(pFile,pSort,nLabelType,nLabelTypeName);
    UpdateLabelSize();
    SetGridCursor(0,CFrameAnalysis::ILS_COLUMN);
    SetColLabelSize(GetRowSize(0) + 2);
  }
  return !bError;
}
示例#30
0
int combatManager::GetCommand(int hex) {
  int v7 = 0;
  UpdateGrid(0, 0);
  int result = 0;
  switch(hex) {
    case -1:
      result = 0;
      break;
    case 25:
      if(this->heroes[1]) {
        if(this->currentActionSide == 1)
          result = 4;
        else
          result = 13;
      } else {
        result = 0;
      }
      break;
    case 26:
      if(this->heroes[0]) {
        if(this->currentActionSide)
          result = 13;
        else
          result = 4;
      } else {
        result = 0;
      }
      break;
    case 77:
      if(this->isCastleBattle)
        result = 5;
      else
        result = 0;
      break;
    default:
      if(hex % 13 == 12) {
        result = 0;
      } else {
        int tempOwner = this->combatGrid[hex].unitOwner;
        int tempStack = this->combatGrid[hex].stackIdx;
        army *a = &this->creatures[this->otherCurrentSideThing][this->someSortOfStackIdx];
        this->creatures[this->otherCurrentSideThing][this->someSortOfStackIdx].targetOwner = -1;
        a->targetStackIdx = -1;
        if(this->combatGrid[hex].isBlocked
          && (!gpCombatManager->isCastleBattle || hex != 58 && hex != 59 || gpCombatManager->drawBridgePosition == 4
            && (gpCombatManager->currentActionSide != 1 || gpCombatManager->combatGrid[58].unitOwner != -1 || gpCombatManager->combatGrid[58].numCorpses))) {
          result = 0;
        } else {
          if(tempOwner == -1) {
            if(this->creatures[this->otherCurrentSideThing][this->someSortOfStackIdx].ValidPath(hex, 0) == 1)
              result = 2 - ((*(DWORD *)&this->creatures[this->otherCurrentSideThing][this->someSortOfStackIdx].creature.creature_flags & (unsigned int)FLYER) < 1);
          } else {
            if(this->otherCurrentSideThing != tempOwner || this->someSortOfStackIdx != tempStack) {
              v7 = 1;
              if(!gbProcessingCombatAction) {
                if(!giNextAction) {
                  *(DWORD *)&this->_15[104] = tempOwner;
                  *(DWORD *)&this->_15[112] = tempStack;
                  this->DrawSmallView(1, 1);
                }
              }
            }
            if(tempOwner >= 0 && tempOwner <= 1) {
              if(this->currentActionSide == tempOwner || this->otherCurrentSideThing == tempOwner && this->someSortOfStackIdx == tempStack)
                return 5;
              a->targetOwner = tempOwner;
              a->targetStackIdx = tempStack;
              if(a->creature.shots > 0 && a->GetAttackMask(a->occupiedHex, 1, -1) == 255) {
                if(this->ShotIsThroughWall(a->owningSide, a->occupiedHex, hex))
                  return 15;
                else
                  return 3;
              }
              // Makes charging possible if the path is completely blocked
              if(a->ValidPath(hex, 0) == 1 || (CreatureHasAttribute(a->creatureIdx, CHARGER) && a->TargetOnStraightLine(hex) && a->ValidFlight(hex, 0) && !a->FlightThroughObstacles(hex) && a->GetStraightLineDistanceToHex(hex) <= a->creature.speed))
                return 7;
              a->targetOwner = -1;
              a->targetStackIdx = -1;
              result = 0;
            }
          }
        }
      }
      break;
  }
  if(!v7) {
    if(!gbProcessingCombatAction) {
      *(DWORD *)&this->_15[104] = -1;
      this->DrawSmallView(1, 1);
    }
  }
  return result;
}