Example #1
0
void CAPet::Disappear()
{
	CArea* area = m_pArea;

//#ifdef MONSTER_COMBO_BUGFIX
//	GAMELOG << init("APET DISAPPEAR PREV")
//			<< m_index
//			<< end;
//#endif // MONSTER_COMBO_BUGFIX

	if (area == NULL)
	{
//#ifdef MONSTER_COMBO_BUGFIX
//		GAMELOG << init("MONSTER_COMBO_BUGFIX") << "AREA NULL" << end;
//#endif // MONSTER_COMBO_BUGFIX
		return ;
	}

	if (!IS_IN_CELL(this))
	{
//#ifdef MONSTER_COMBO_BUGFIX
//		GAMELOG << init("MONSTER_COMBO_BUGFIX")
//				<< "IS_IN_CELL" << delim
//				<< m_cellX
//				<< end;
//#endif // MONSTER_COMBO_BUGFIX
		return ;
	}

	if (!m_bSummon)
	{
//#ifdef MONSTER_COMBO_BUGFIX
//		GAMELOG << init("MONSTER_COMBO_BUGFIX") << "SUMMON FALSE" << end;
//#endif // MONSTER_COMBO_BUGFIX
		return ;
	}

	// 어택 리스트 지우고
	DelAttackList(this);

	{
		// 사라짐을 알리고
		CNetMsg::SP rmsg(new CNetMsg);
		DisappearMsg(rmsg, this);
		area->SendToCell(rmsg, this, true);
	}

	// 셀에서 제거
	area->CharFromCell(this, true);
	m_pZone = NULL;
	m_pArea = NULL;

	m_bSummon = false;
//#ifdef MONSTER_COMBO_BUGFIX
//	GAMELOG << init("APET DISAPPEAR AFTER")
//			<< m_index << delim
//			<< m_cellX << delim
//			<< m_cellZ << end;
//#endif // MONSTER_COMBO_BUGFIX
}
Example #2
0
void CArea::Split(std::list<CArea> &m_areas)const
{
	if(HolesLinked())
	{
		for(std::list<CCurve>::const_iterator It = m_curves.begin(); It != m_curves.end(); It++)
		{
			const CCurve& curve = *It;
			m_areas.push_back(CArea());
			m_areas.back().m_curves.push_back(curve);
		}
	}
	else
	{
		CArea a = *this;
		a.Reorder();

		if(CArea::m_please_abort)return;

		for(std::list<CCurve>::const_iterator It = a.m_curves.begin(); It != a.m_curves.end(); It++)
		{
			const CCurve& curve = *It;
			if(curve.IsClockwise())
			{
				if(m_areas.size() > 0)
					m_areas.back().m_curves.push_back(curve);
			}
			else
			{
				m_areas.push_back(CArea());
				m_areas.back().m_curves.push_back(curve);
			}
		}
	}
}
Example #3
0
/************************************************************************************************
 * CRMInstance::PreSpawn
 *	Prepares the instance for spawning by flattening the ground under it
 *
 * inputs:
 *  landscape: landscape the instance will be spawned on
 *
 * return:
 *	true: spawn preparation successful
 *  false: spawn preparation failed
 *
 ************************************************************************************************/
bool CRMInstance::PreSpawn ( CRandomTerrain* terrain, qboolean IsServer )
{
	vec3_t		origin;
	CArea		area;

	VectorCopy(GetOrigin(), origin);

	if (mMirror)
	{
		origin[0] = TheRandomMissionManager->GetLandScape()->GetBounds()[0][0] + TheRandomMissionManager->GetLandScape()->GetBounds()[1][0] - origin[0];
		origin[1] = TheRandomMissionManager->GetLandScape()->GetBounds()[0][1] + TheRandomMissionManager->GetLandScape()->GetBounds()[1][1] - origin[1];
	}

	const vec3_t&	  terxelSize = terrain->GetLandScape()->GetTerxelSize ( );
	const vec3pair_t& bounds     = terrain->GetLandScape()->GetBounds();

	// Align the instance to the center of a terxel
	origin[0] = bounds[0][0] + (int)((origin[0] - bounds[0][0] + terxelSize[0] / 2) / terxelSize[0]) * terxelSize[0];
	origin[1] = bounds[0][1] + (int)((origin[1] - bounds[0][1] + terxelSize[1] / 2) / terxelSize[1]) * terxelSize[1];


	// This is BAD - By copying the mirrored origin back into the instance, you've now mirrored the original instance
	// so when anything from this point on looks at the instance they'll be looking at a mirrored version but will be expecting the original
	// so later in the spawn functions the instance will be re-mirrored, because it thinks the mInstances have not been changed
//	VectorCopy(origin, GetOrigin());

	// Flatten the area below the instance 
	if ( GetFlattenRadius() )
	{	
		area.Init( origin, GetFlattenRadius(), 0.0f, AT_NONE, 0, 0 );
		terrain->GetLandScape()->FlattenArea( &area, mFlattenHeight | (mSurfaceSprites?0:0x80), false, true, true );
	}

	return true;
}
Example #4
0
void CAPet::Mount( bool bMount )
{
	m_bMount = bMount;

	// 주인관련 처리
	if( m_pOwner )
	{
		CArea* area = m_pOwner->m_pArea;

		if( bMount )		// 탈때
		{
			if(m_pArea != NULL) // NULL이 아니면 실행, NULL이면 건너뛸것.
				m_pArea->MoveChar( this, GET_YLAYER(m_pOwner), GET_X(m_pOwner), GET_Z(m_pOwner), GET_H(m_pOwner), GET_R(m_pOwner), MSG_MOVE_STOP, NULL );

			// 소환 해제
			while ( m_pOwner->m_elementalList)
				m_pOwner->UnsummonElemental(m_pOwner->m_elementalList);
		}

		if(area)
		{
			{
				// 사라졌다 나타나기
				CNetMsg::SP rmsg(new CNetMsg);
				DisappearMsg(rmsg, this);
				area->SendToCell(rmsg, this, true);
			}

			{
				CNetMsg::SP rmsg(new CNetMsg);
				AppearMsg(rmsg, this);
				area->SendToCell(rmsg, this, true);
			}
		}


		if (m_pArea)
		{
			CNetMsg::SP rmsg(new CNetMsg);
			ExAPetStatusMsg( rmsg, this );
			m_pArea->SendToCell(rmsg, GetOwner(), true);
		}

		m_pOwner->CalcStatus(true);

		{
			CNetMsg::SP rmsg(new CNetMsg);
			ExAPetFuntionMsg( rmsg, MSG_SUB_MOUNT_REP, this , 0 );
			m_pOwner->m_pArea->SendToCell(rmsg, m_pOwner, true);
		}
	}
}
Example #5
0
int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);
    QFile area_file( a.arguments().at( 1 ) );
    area_file.open( QIODevice::ReadOnly );

    QDataStream stream( &area_file );
    stream.setByteOrder( QDataStream::LittleEndian );

    CArea area;
    area.read( stream );
    qDebug() << area_file.fileName();

    CMainWindow w( &area );

    w.show();
    return a.exec();
}
Example #6
0
boost::python::list MakePocketToolpath(const CArea& a, double tool_radius, double extra_offset, double stepover, bool from_center, bool use_zig_zag, double zig_angle)
{
	std::list<CCurve> toolpath;

	CAreaPocketParams params(tool_radius, extra_offset, stepover, from_center, use_zig_zag ? ZigZagPocketMode : SpiralPocketMode, zig_angle);
	a.SplitAndMakePocketToolpath(toolpath, params);

	boost::python::list clist;
	BOOST_FOREACH(const CCurve& c, toolpath) {
		clist.append(c);
    }
Example #7
0
static CArea make_obround(const Point& p0, const Point& p1, double radius)
{
    Point dir = p1 - p0;
    double d = dir.length();
    dir.normalize();
    Point right(dir.y, -dir.x);
    CArea obround;
    CCurve c;
    if(fabs(radius) < 0.0000001)radius = (radius > 0.0) ? 0.002 : (-0.002);
    Point vt0 = p0 + right * radius;
    Point vt1 = p1 + right * radius;
    Point vt2 = p1 - right * radius;
    Point vt3 = p0 - right * radius;
    c.append(vt0);
    c.append(vt1);
    c.append(CVertex(1, vt2, p1));
    c.append(vt3);
    c.append(CVertex(1, vt0, p0));
    obround.append(c);
    return obround;
}
Example #8
0
    IslandAndOffset(const CCurve* Island)
    {
        island = Island;

        offset.m_curves.push_back(*island);
        offset.m_curves.back().Reverse();

        offset.Offset(-pocket_params->stepover);


        if(offset.m_curves.size() > 1)
        {
            for(std::list<CCurve>::iterator It = offset.m_curves.begin(); It != offset.m_curves.end(); It++)
            {
                if(It == offset.m_curves.begin())continue;
                island_inners.push_back(*It);
                island_inners.back().Reverse();
            }
            offset.m_curves.resize(1);
        }
    }
Example #9
0
/************************************************************************************************
 * CRMPathManager::PathVisit
 * This method is called recursively to create a network of nodes connected with paths.
 *
 * inputs:
 *  c_x, c_y - cell to visit
 *
 * return:
 *	none
 *
 ************************************************************************************************/
void CRMPathManager::PathVisit(const int c_x, const int c_y)
{
    // does this cell have any neighbors with all walls intact?
    int i,off;

    // look at neighbors in random order
    off = TheRandomMissionManager->GetLandScape()->irand(DIR_FIRST, DIR_MAX-1);

    ++mDepth;	// track our depth of recursion

    for (i = DIR_FIRST; i<DIR_MAX && mDepth <= mMaxDepth; i++)
    {
        int d = (i + off) % DIR_MAX;
        if ( !Cell(c_x, c_y).Border(d) )
        {   // we can move this way, since no border
            int new_c_x = c_x + neighbor_x[d];
            int new_c_y = c_y + neighbor_y[d];
            if (Cell(new_c_x,new_c_y).Wall() == DIR_ALL)
            {   // we have a new cell that has not been visited!
                int new_dir;
                // d is the direction relative to the current cell
                // new_dir is the direction relative to the next cell (N becomes S, NE becomes SW, etc...)
                if( d < HALF_DIR_MAX )
                {
                    new_dir = d + HALF_DIR_MAX;
                }
                else
                {
                    new_dir = d - HALF_DIR_MAX;
                }

                // knock down walls
                Cell(c_x,c_y).RemoveWall(d);
                Cell(new_c_x,new_c_y).RemoveWall(new_dir); //DIR_MAX - d);

                // set path id
                Node(c_x, c_y)->SetPath(d, mPathCount);
                Node(new_c_x, new_c_y)->SetPath(new_dir, mPathCount); //DIR_MAX - d, mPathCount);

                // create path between cells
                mTerrain->CreatePath( mPathCount++,
                                      -1,
                                      0,
                                      mPathPoints,
                                      GetNodePos(c_x,c_y)[0],
                                      GetNodePos(c_x,c_y)[1],
                                      GetNodePos(new_c_x,new_c_y)[0],
                                      GetNodePos(new_c_x,new_c_y)[1],
                                      mPathMinWidth,
                                      mPathMaxWidth,
                                      mPathDepth,
                                      mPathDeviation,
                                      mPathBreadth );

                // flatten a small spot
                CArea		area;
                float flat_radius = mPathMaxWidth *
                                    fabs(TheRandomMissionManager->GetLandScape()->GetBounds()[1][0] - TheRandomMissionManager->GetLandScape()->GetBounds()[0][0]);
                area.Init( GetNodePos(c_x,c_y), flat_radius, 0.0f, AT_NONE, 0, 0 );
                TheRandomMissionManager->GetLandScape()->FlattenArea(&area, 255 * mPathDepth, false, true, true );

                // recurse
                PathVisit(new_c_x, new_c_y);
            }
        }
    }

    --mDepth;

    // NOTE: *whoop* hack alert, the first time this is reached, it should be the very last placed node.
    if( !mCrossed && TheRandomMissionManager->GetMission()->GetSymmetric() &&
            TheRandomMissionManager->GetMission()->GetBackUpPath() )
    {
        mCrossed = true;

        int directionSet[3][3] = {DIR_NW,DIR_W,DIR_SW,DIR_N,-1,DIR_S,DIR_NE,DIR_E,DIR_SE};
        int	ncx	= (mXNodes-1)-c_x;
        int	ncy	= (mYNodes-1)-c_y;

        int x_delta = ncx - c_x;
        int y_delta = ncy - c_y;

        if( x_delta < -1 )
        {
            x_delta = -1;
        }
        else if( x_delta > 1 )
        {
            x_delta = 1;
        }

        if( y_delta < -1 )
        {
            y_delta = -1;
        }
        else if( y_delta > 1 )
        {
            y_delta = 1;
        }

        // make sure the mirror is actually in a different position than then un-mirrored node
        if( x_delta || y_delta )
        {

            int d = directionSet[x_delta][y_delta];
            int new_dir;
            // d is the direction relative to the current cell
            // new_dir is the direction relative to the next cell (N becomes S, NE becomes SW, etc...)
            if( d < HALF_DIR_MAX )
            {
                new_dir = d + HALF_DIR_MAX;
            }
            else
            {
                new_dir = d - HALF_DIR_MAX;
            }

            //NOTE: Knocking down these walls will cause instances to be created on this new artificial path
            // Since this path could span more than just the normal 1 cell, these walls being knocked down are not exactly correct... but get the job done

            // knock down walls
            Cell(c_x,c_y).RemoveWall(d);
            Cell(ncx,ncy).RemoveWall(new_dir); //DIR_MAX - d);

            // set path id
            Node(c_x, c_y)->SetPath(d, mPathCount);
            Node(ncx, ncy)->SetPath(new_dir, mPathCount); //DIR_MAX - d, mPathCount);

            // create an artificial path that crosses over to connect the symmetric and non-symmetric map parts
            mTerrain->CreatePath( mPathCount++,
                                  -1,
                                  0,
                                  mPathPoints,
                                  GetNodePos(c_x,c_y)[0],
                                  GetNodePos(c_x,c_y)[1],
                                  GetNodePos(ncx,ncy)[0],
                                  GetNodePos(ncx,ncy)[1],
                                  mPathMinWidth,
                                  mPathMaxWidth,
                                  mPathDepth,
                                  mPathDeviation,
                                  mPathBreadth );

        }
    }

    PlaceLocation(c_x, c_y);
}
Example #10
0
void CAPet::Appear(bool bIncludeOwner, bool bAction )
{
//#ifdef MONSTER_COMBO_BUGFIX
//	GAMELOG << init("APET APEAR PREV")
//			<< m_index << end;
//#endif // MONSTER_COMBO_BUGFIX"

	if (m_pOwner == NULL)
	{
//#ifdef MONSTER_COMBO_BUGFIX
//		GAMELOG << init("MONSTER_COMBO_BUGFIX") << "OWNER NULL"<< end;
//#endif // MONSTER_COMBO_BUGFIX
		return ;
	}

	CArea* area = m_pOwner->m_pArea;
	if (area == NULL)
	{
//#ifdef MONSTER_COMBO_BUGFIX
//		GAMELOG << init("MONSTER_COMBO_BUGFIX") << "AREA NULL" << end;
//#endif // MONSTER_COMBO_BUGFIX
		return ;
	}

	if (m_bSummon)
	{
//#ifdef MONSTER_COMBO_BUGFIX
//		GAMELOG << init("MONSTER_COMBO_BUGFIX") << "SUMMON FALSE" << end;
//#endif // MONSTER_COMBO_BUGFIX
		return ;
	}

	// 셀에 넣기
	m_pZone = area->m_zone;
	m_pArea = area;
	m_pos = m_pOwner->m_pos;
	int cx, cz;
	area->PointToCellNum(GET_X(this), GET_Z(this), &cx, &cz);
	area->CharToCell(this, GET_YLAYER(this), cx, cz);

	{
		CNetMsg::SP rmsg(new CNetMsg);
		// 나타남을 알림
		AppearMsg(rmsg, this, true, true);
		area->SendToCell(rmsg, this, bIncludeOwner);
	}

	CalcStatus(false);

	{
		CNetMsg::SP rmsg(new CNetMsg);
		ExAPetStatusMsg( rmsg, this );
		m_pArea->SendToCell(rmsg, GetOwner(), true);
	}

	for( int i=0 ; i < APET_WEARPOINT; i++ )
	{
		if( m_wearing[i] )
		{
			CNetMsg::SP rmsg(new CNetMsg);
			AddItemExAPetMsg(rmsg, m_wearing[i]);
			SEND_Q(rmsg, GetOwner()->m_desc);
		}
	}

	m_bSummon = true;
//#ifdef MONSTER_COMBO_BUGFIX
//	GAMELOG << init("APET APEAR AFTER")
//			<< m_index << delim
//			<< m_cellX << delim
//			<< m_cellZ << end;
//#endif // MONSTER_COMBO_BUGFIX
}
Example #11
0
bool CAPet::TransFormationCheck()
{
	if( m_pProto->m_TansType !=  APET_TRANS_NONE )
	{
		int comp = 0;
		char oldState = this->m_cTransSate;

		switch( m_pProto->m_TansType)
		{
		case APET_TRANS_TIME:
			{
				int nowsec = gserver->getNowSecond() % 3600;

				if (nowsec == (3600 - 30) || nowsec == (3600 / 2) - 30)	// 30초 전
				{
					CNetMsg::SP rmsg(new CNetMsg);
					SysMsg(rmsg, MSG_SYS_TRANSLATE_START );
					SEND_Q(rmsg, m_pOwner->m_desc);
				}
				else if (nowsec >= 0 && nowsec <= (3600 / 2)) // 정각s
				{
					m_cTransSate = 0;
				}
				else
				{
					m_cTransSate = 1;
				}
			}
			break;
		case APET_TRANS_FAITH:
			comp = m_nFaith;
			break;
		case APET_TRANS_STM:
			comp = m_nStm;
			break;
		}

		// 옵션이 0 또는 100 이상일때 강제로 설정해주는 부분
		if( m_cForceTrans == 1 )			// 무조건 변신
			this->m_cTransSate = 1;
		else if ( m_cForceTrans == 2 )		// 무조건 변신 안함
			this->m_cTransSate = 0;

		if( oldState != m_cTransSate )
		{
			// 변신했는데 마운트 타입이 아닌경우
			if( m_pProto->m_nMount[ (unsigned int)m_cTransSate ] < 1 && IsMount() )
			{
				Mount(false);
			}
			else
			{
				CArea* area = m_pOwner->m_pArea;

				{
					CNetMsg::SP rmsg(new CNetMsg);
					DisappearMsg(rmsg, this);
					area->SendToCell(rmsg, this, true);
				}

				{
					CNetMsg::SP rmsg(new CNetMsg);
					AppearMsg(rmsg, this);
					area->SendToCell(rmsg, this, true);
				}
			}

			CalcStatus(false);

			return true;
		}
	}
	return false;
}
Example #12
0
void CRMLandScape::CreateRandomDensityMap(byte *density, int width, int height, int seed)
{
//	int			i, border, inc;
	int			x, y, count;
//	byte		*work, *work2;
	CArea		*area;
	vec3_t		derxelSize, pos;
	ivec3_t		dmappos;
	byte		*hm_map = common->GetHeightMap();
	int			hm_width = common->GetRealWidth();
	int			hm_height = common->GetRealHeight();
	int			xpos, ypos, dx, dy;
	byte		*densityPos = density;
	bool		foundUneven;

	// Init to linear spread
	memset(density, 0, width * height);

/*	// Make more prevalent towards the edges
	border = Com_Clamp(6, 12, (width + height) >> 4);

	for(i = 0; i < border; i++)
	{
		inc = (border - i + 1) * 9;

		// Top line
		work = density + i + (i * width);
		for(x = i; x < width - i; x++, work++)
		{
			*work += (byte)common->irand(inc >> 1, inc);
		}

		// Left and right edges
		work = density + i + ((i + 1) * width);
		work2 = density + (width - i) + ((i + 1) * width);
		for(y = i + 1; y < height - i - 2; y++, work += width, work2 += width)
		{
			*work += (byte)common->irand(inc >> 1, inc);
			*work2 += (byte)common->irand(inc >> 1, inc);
		}

		// Bottom line
		work = density + i + ((height - i - 1) * width);
		for(x = i; x < width - i; x++, work++)
		{
			*work += (byte)common->irand(inc >> 1, inc);
		}
	}
*/
	count = 0;

	for(y=0;y<height;y++)
	{
		for(x=0;x<width;x++,densityPos++)
		{
			xpos = (x * hm_width / width);
			ypos = (y * hm_height / height);
			ypos = hm_height - ypos - 1;

			if (hm_map[ypos*hm_width + xpos] < 150)
			{
				continue;
			}

			foundUneven = false;
			for(dx=-4;(dx<=4 && !foundUneven);dx++)
			{
				for(dy=-4;(dy<=4 && !foundUneven);dy++)
				{
					if (dx == 0 && dy == 0)
					{
						continue;
					}
					if ((xpos+dx) >= 0 && (xpos+dx) < hm_width && (ypos+dy) >= 0 && (ypos+dy) < hm_height)
					{
						if (hm_map[(ypos+dy)*hm_width + (xpos+dx)] < 190)
						{
							*densityPos = 205;
							count++;
							foundUneven = true;
						}
					}
				}
			}
		}
	}

/*	FILE	*FH;

	FH = fopen("c:\o.raw", "wb");
	fwrite(hm_map, 1, common->GetRealWidth() * common->GetRealHeight(), FH);
	fclose(FH);

	FH = fopen("c:\d.raw", "wb");
	fwrite(density, 1, width*height, FH);
	fclose(FH);
*/
	// Reduce severely for any settlements/buildings/objectives
	VectorScale(common->GetSize(), 1.0f / width, derxelSize);

	origin_land = common;
	area = common->GetFirstArea();
	while(area)
	{
		// Skip group types since they encompass to much open area
		if ( area->GetType ( ) == AT_GROUP )
		{
			area = common->GetNextArea();
			continue;
		}

		VectorSubtract(area->GetPosition(), common->GetMins(), pos);
		VectorInverseScaleVector(pos, derxelSize, dmappos);
		// Damn upside down gensurf
		dmappos[1] = height - dmappos[1];

		count = ceilf(area->GetRadius() / derxelSize[1]);

		while(count > 0)
		{
			CM_CircularIterate(density, width, height, dmappos[0], dmappos[1], 0, count, NULL, CG_Decrease);
			count--;
		}
		area = common->GetNextArea();
	}
}
Example #13
0
void CurveTree::MakeOffsets2()
{
    // make offsets

    if(CArea::m_please_abort)return;
    CArea smaller;
    smaller.m_curves.push_back(curve);
    smaller.Offset(pocket_params->stepover);

    if(CArea::m_please_abort)return;

    // test islands
    for(std::list<const IslandAndOffset*>::iterator It = offset_islands.begin(); It != offset_islands.end();)
    {
        const IslandAndOffset* island_and_offset = *It;

        if(GetOverlapType(island_and_offset->offset, smaller) == eInside)
            It++; // island is still inside
        else
        {
            inners.push_back(new CurveTree(*island_and_offset->island));
            islands_added.push_back(inners.back());
            inners.back()->point_on_parent = curve.NearestPoint(*island_and_offset->island);
            if(CArea::m_please_abort)return;
            Point island_point = island_and_offset->island->NearestPoint(inners.back()->point_on_parent);
            if(CArea::m_please_abort)return;
            inners.back()->curve.ChangeStart(island_point);
            if(CArea::m_please_abort)return;

            // add the island offset's inner curves
            for(std::list<CCurve>::const_iterator It2 = island_and_offset->island_inners.begin(); It2 != island_and_offset->island_inners.end(); It2++)
            {
                const CCurve& island_inner = *It2;
                inners.back()->inners.push_back(new CurveTree(island_inner));
                inners.back()->inners.back()->point_on_parent = inners.back()->curve.NearestPoint(island_inner);
                if(CArea::m_please_abort)return;
                Point island_point = island_inner.NearestPoint(inners.back()->inners.back()->point_on_parent);
                if(CArea::m_please_abort)return;
                inners.back()->inners.back()->curve.ChangeStart(island_point);
                to_do_list_for_MakeOffsets.push_back(inners.back()->inners.back()); // do it later, in a while loop
                if(CArea::m_please_abort)return;
            }

            smaller.Subtract(island_and_offset->offset);

            std::set<const IslandAndOffset*> added;

            std::list<IslandAndOffsetLink> touching_list;
            for(std::list<IslandAndOffset*>::const_iterator It2 = island_and_offset->touching_offsets.begin(); It2 != island_and_offset->touching_offsets.end(); It2++)
            {
                const IslandAndOffset* touching = *It2;
                touching_list.push_back(IslandAndOffsetLink(touching, inners.back()));
                added.insert(touching);
            }

            while(touching_list.size() > 0)
            {
                IslandAndOffsetLink touching = touching_list.front();
                touching_list.pop_front();
                touching.add_to->inners.push_back(new CurveTree(*touching.island_and_offset->island));
                islands_added.push_back(touching.add_to->inners.back());
                touching.add_to->inners.back()->point_on_parent = touching.add_to->curve.NearestPoint(*touching.island_and_offset->island);
                Point island_point = touching.island_and_offset->island->NearestPoint(touching.add_to->inners.back()->point_on_parent);
                touching.add_to->inners.back()->curve.ChangeStart(island_point);
                smaller.Subtract(touching.island_and_offset->offset);

                // add the island offset's inner curves
                for(std::list<CCurve>::const_iterator It2 = touching.island_and_offset->island_inners.begin(); It2 != touching.island_and_offset->island_inners.end(); It2++)
                {
                    const CCurve& island_inner = *It2;
                    touching.add_to->inners.back()->inners.push_back(new CurveTree(island_inner));
                    touching.add_to->inners.back()->inners.back()->point_on_parent = touching.add_to->inners.back()->curve.NearestPoint(island_inner);
                    if(CArea::m_please_abort)return;
                    Point island_point = island_inner.NearestPoint(touching.add_to->inners.back()->inners.back()->point_on_parent);
                    if(CArea::m_please_abort)return;
                    touching.add_to->inners.back()->inners.back()->curve.ChangeStart(island_point);
                    to_do_list_for_MakeOffsets.push_back(touching.add_to->inners.back()->inners.back()); // do it later, in a while loop
                    if(CArea::m_please_abort)return;
                }

                for(std::list<IslandAndOffset*>::const_iterator It2 = touching.island_and_offset->touching_offsets.begin(); It2 != touching.island_and_offset->touching_offsets.end(); It2++)
                {
                    if(added.find(*It2)==added.end() && ((*It2) != island_and_offset))
                    {
                        touching_list.push_back(IslandAndOffsetLink(*It2, touching.add_to->inners.back()));
                        added.insert(*It2);
                    }
                }
            }

            if(CArea::m_please_abort)return;
            It = offset_islands.erase(It);

            for(std::set<const IslandAndOffset*>::iterator It2 = added.begin(); It2 != added.end(); It2++)
            {
                const IslandAndOffset* i = *It2;
                offset_islands.remove(i);
            }

            if(offset_islands.size() == 0)break;
            It = offset_islands.begin();
        }
    }

    CArea::m_processing_done += CArea::m_MakeOffsets_increment;
    if(CArea::m_processing_done > CArea::m_after_MakeOffsets_length)CArea::m_processing_done = CArea::m_after_MakeOffsets_length;

    std::list<CArea> separate_areas;
    smaller.Split(separate_areas);
    if(CArea::m_please_abort)return;
    for(std::list<CArea>::iterator It = separate_areas.begin(); It != separate_areas.end(); It++)
    {
        CArea& separate_area = *It;
        CCurve& first_curve = separate_area.m_curves.front();

        CurveTree* nearest_curve_tree = NULL;
        Point near_point = GetNearestPoint(this, islands_added, first_curve, &nearest_curve_tree);

        nearest_curve_tree->inners.push_back(new CurveTree(first_curve));

        for(std::list<const IslandAndOffset*>::iterator It = offset_islands.begin(); It != offset_islands.end(); It++)
        {
            const IslandAndOffset* island_and_offset = *It;
            if(GetOverlapType(island_and_offset->offset, separate_area) == eInside)
                nearest_curve_tree->inners.back()->offset_islands.push_back(island_and_offset);
            if(CArea::m_please_abort)return;
        }

        nearest_curve_tree->inners.back()->point_on_parent = near_point;

        if(CArea::m_please_abort)return;
        Point first_curve_point = first_curve.NearestPoint(nearest_curve_tree->inners.back()->point_on_parent);
        if(CArea::m_please_abort)return;
        nearest_curve_tree->inners.back()->curve.ChangeStart(first_curve_point);
        if(CArea::m_please_abort)return;
        to_do_list_for_MakeOffsets.push_back(nearest_curve_tree->inners.back()); // do it later, in a while loop
        if(CArea::m_please_abort)return;
    }
}
// 믈리 어택
void do_pd_Attack(CPC* pc, CNetMsg::SP& msg)
{
	CDratanCastle * pCastle = CDratanCastle::CreateInstance();
	pCastle->CheckRespond(pc);

	RequestClient::doPDAttack* packet = reinterpret_cast<RequestClient::doPDAttack*>(msg->m_buf);

	if (packet->multicount > 20)
	{
		LOG_ERROR("HACKING : invalid multi count[%d]. charIndex[%d]", packet->multicount, pc->m_index);
		pc->m_desc->Close("invalid multi count");
		return;
	}

	// multi target의 중복 검사
	if (packet->multicount > 1)
	{
		std::set<int> tset;
		for (int i = 0; i < packet->multicount; ++i)
		{
			if (tset.insert(packet->list[i].index).second == false)
			{
				LOG_ERROR("HACKING : duplicate multi target[%d]. charIndex[%d]", packet->list[i].index, pc->m_index);
				pc->m_desc->Close("duplicate multi target");
				return;
			}
		}
	}

	// 대상 검색 : 인접 셀에서만
	CArea* area = pc->m_pArea;
	if (area == NULL)
	{
		LOG_ERROR("HACKING : not found area. charIndex[%d]", pc->m_index);
		pc->m_desc->Close("not found area");
		return;
	}

	CCharacter* tch = area->FindCharInCell(pc, packet->tIndex, (MSG_CHAR_TYPE)packet->tCharType);
	if (tch == NULL)
		return;

	int preIndex = -1;
	for (int i = 0; i < packet->multicount; ++i)
	{
		if(preIndex == packet->list[i].index)
		{
			// 가까운 마을로
			int nearZone;
			int nearZonePos;
			CZone* pZone = gserver->FindNearestZone(pc->m_pZone->m_index, GET_X(pc), GET_Z(pc), &nearZone, &nearZonePos);
			if (pZone == NULL)
				return;

			GoZone(pc, nearZone,
				   pZone->m_zonePos[nearZonePos][0],															// ylayer
				   GetRandom(pZone->m_zonePos[nearZonePos][1], pZone->m_zonePos[nearZonePos][3]) / 2.0f,		// x
				   GetRandom(pZone->m_zonePos[nearZonePos][2], pZone->m_zonePos[nearZonePos][4]) / 2.0f);		// z

			return;
		}

		preIndex = packet->list[i].index;

		CCharacter* ch = area->FindCharInCell(pc, packet->list[i].index, (MSG_CHAR_TYPE) MSG_CHAR_NPC);

		if(!ch) continue;

		if( !IS_NPC(ch) )
		{
			CPC* bugPC = NULL;
			if( IS_ELEMENTAL(ch) )
			{
				CElemental *ele = TO_ELEMENTAL(ch);
				bugPC = ele->GetOwner();
			}
			if( IS_PET(ch) )
			{
				CPet* pet = TO_PET(ch);
				bugPC = pet->GetOwner();
			}

			if( IS_PC(ch) )
			{
				bugPC = TO_PC(ch);
			}

			if( !bugPC )
				return;

			// 가까운 마을로
			int nearZone;
			int nearZonePos;
			CZone* pZone = gserver->FindNearestZone(bugPC->m_pZone->m_index, GET_X(bugPC), GET_Z(bugPC), &nearZone, &nearZonePos);
			if (pZone == NULL)
				return;

			GoZone(bugPC, nearZone,
				   pZone->m_zonePos[nearZonePos][0],															// ylayer
				   GetRandom(pZone->m_zonePos[nearZonePos][1], pZone->m_zonePos[nearZonePos][3]) / 2.0f,		// x
				   GetRandom(pZone->m_zonePos[nearZonePos][2], pZone->m_zonePos[nearZonePos][4]) / 2.0f);		// z

			GAMELOG << init("PD_BUG", bugPC)
					<< end;
			return;
		}

		int ret = ProcAttack(ch, tch, ch->GetAttackType(NULL), NULL, 0);
		if (ret == -1)
			return ;
	}
}
Example #15
0
void CRMPathManager::RiverVisit(const int c_x, const int c_y)
{
    // does this cell have any neighbors with all walls intact?
    int i,off;

    // look at neighbors in random order
    off = TheRandomMissionManager->GetLandScape()->irand(DIR_FIRST, DIR_MAX-1);

    ++mDepth;	// track our depth of recursion

    for (i = DIR_FIRST; i<DIR_MAX && mDepth <= mMaxDepth; i+=2)
    {
        int d = (i + off) % DIR_MAX;
        if ( !Cell(c_x, c_y).Border(d) )
        {   // we can move this way, since no border
            int new_c_x = c_x + neighbor_x[d];
            int new_c_y = c_y + neighbor_y[d];
            if (RiverCell(new_c_x,new_c_y).Wall() == DIR_ALL)
            {   // we have a new cell that has not been visited!

                int new_dir;
                // d is the direction relative to the current cell
                // new_dir is the direction relative to the next cell (N becomes S, NE becomes SW, etc...)
                if( d < HALF_DIR_MAX )
                {
                    new_dir = d + HALF_DIR_MAX;
                }
                else
                {
                    new_dir = d - HALF_DIR_MAX;
                }
                // knock down walls
                RiverCell(c_x,c_y).RemoveWall(d);
                RiverCell(new_c_x,new_c_y).RemoveWall(new_dir); //DIR_MAX - d);

                // create river between cells
                mTerrain->CreatePath ( mPathCount++,
                                       -1,
                                       0,
                                       mRiverPoints,
                                       GetRiverPos(c_x,c_y)[0],
                                       GetRiverPos(c_x,c_y)[1],
                                       GetRiverPos(new_c_x,new_c_y)[0],
                                       GetRiverPos(new_c_x,new_c_y)[1],
                                       mRiverMinWidth,
                                       mRiverMaxWidth,
                                       mRiverBedDepth,
                                       mRiverDeviation,
                                       mRiverBreadth );

                // flatten a small spot
                CArea		area;
                float flat_radius = mRiverMinWidth *
                                    fabs(TheRandomMissionManager->GetLandScape()->GetBounds()[1][0] - TheRandomMissionManager->GetLandScape()->GetBounds()[0][0]);
                area.Init( GetRiverPos(c_x,c_y), flat_radius, 0.0f, AT_NONE, 0, 0 );
                TheRandomMissionManager->GetLandScape()->FlattenArea (&area, 255 * mRiverBedDepth, false, true, true );

                // recurse
                RiverVisit(new_c_x, new_c_y);
            }
        }
    }

//	--mDepth;
}
Example #16
0
static bool feed_possible(const CArea &area_for_feed_possible, const Point& p0, const Point& p1, double tool_radius)
{
    CArea obround = make_obround(p0, p1, tool_radius);
    obround.Subtract(area_for_feed_possible);
    return obround.m_curves.size() == 0;
}
Example #17
0
	ThickLine(const CCurve& curve)
	{
		m_curve = curve;
		m_area.append(curve);
		m_area.Thicken(0.001);
	}
Example #18
0
bool CCurve::Offset(double leftwards_value)
{
	// use the kurve code donated by Geoff Hawkesford, to offset the curve as an open curve
	// returns true for success, false for failure
	bool success = true;

	CCurve save_curve = *this;

	try
	{
		geoff_geometry::Kurve k = MakeKurve(*this);
		geoff_geometry::Kurve kOffset;
		int ret = 0;
		k.OffsetMethod1(kOffset, fabs(leftwards_value), (leftwards_value > 0) ? 1:-1, 1, ret);
		success = (ret == 0);
		if(success)*this = MakeCCurve(kOffset);
	}
	catch(...)
	{
		success = false;
	}

	if(success == false)
	{
		if(this->IsClosed())
		{
			double inwards_offset = leftwards_value;
			bool cw = false;
			if(this->IsClockwise())
			{
				inwards_offset = -inwards_offset;
				cw = true;
			}
			CArea a;
			a.append(*this);
			a.Offset(inwards_offset);
			if(a.m_curves.size() == 1)
			{
				Span* start_span = NULL;
				if(this->m_vertices.size() > 1)
				{
					std::list<CVertex>::iterator It = m_vertices.begin();
					CVertex &v0 = *It;
					It++;
					CVertex &v1 = *It;
					start_span = new Span(v0.m_p, v1, true);
				}
				*this = a.m_curves.front();
				if(this->IsClockwise() != cw)this->Reverse();
				if(start_span)
				{
					Point forward = start_span->GetVector(0.0);
					Point left(-forward.y, forward.x);
					Point offset_start = start_span->m_p + left * leftwards_value;
					this->ChangeStart(this->NearestPoint(offset_start));
					delete start_span;
				}
				success = true;
			}
		}
	}

	return success;
}
Example #19
0
void CCurve::CurveIntersections(const CCurve& c, std::list<Point> &pts)const
{
	CArea a;
	a.append(*this);
	a.CurveIntersections(c, pts);
}
void do_Attack(CPC* pc, CNetMsg::SP& msg)
{
	CDratanCastle * pCastle = CDratanCastle::CreateInstance();
	pCastle->CheckRespond(pc);

	RequestClient::doAttack* packet = reinterpret_cast<RequestClient::doAttack*>(msg->m_buf);

	// 동시 공격은 최대 5
	if (packet->multicount > 5)
	{
		LOG_ERROR("HACKING : invalid multi count[%d]. charIndex[%d]", packet->multicount, pc->m_index);
		pc->m_desc->Close("invalid multi count");
		return;
	}

	// multi target의 중복 검사
	if (packet->multicount > 1)
	{
		std::set<int> tset;
		for (int i = 0; i < packet->multicount; ++i)
		{
			if (tset.insert(packet->list[i].index).second == false)
			{
				LOG_ERROR("HACKING : duplicate multi target[%d]. charIndex[%d]", packet->list[i].index, pc->m_index);
				pc->m_desc->Close("duplicate multi target");
				return;
			}
		}
	}

	// 대상 검색 : 인접 셀에서만
	CArea* area = pc->m_pArea;
	if (area == NULL)
		return;

	CCharacter* ch = area->FindCharInCell(pc, packet->aIndex, (MSG_CHAR_TYPE)packet->aCharType);
	if (ch == NULL)
		return;

	CCharacter* tch = area->FindCharInCell(ch, packet->tIndex, (MSG_CHAR_TYPE)packet->tCharType);
	if (tch == NULL)
		return;

	// 공격자가 PC이면 자신의 캐릭만 조정
	if (IS_PC(ch) && ch != pc)
		return ;

	switch (ch->m_type)
	{
	case MSG_CHAR_PC:
		{
			if( IS_NPC(tch))
			{
				CPC * pPC = TO_PC(ch);
				CNPC * pNPC = TO_NPC(tch);
				if( pPC->GetSummonNpc(SUMMON_NPC_TYPE_MERCENARY) == pNPC )
					return;
			}

			//pvp보호 아이템 체크
			if (checkPvPProtect(pc, tch) == false)
				return;

			// 공격 거리 검사
			if (GetDistance(ch, tch) > ch->m_attackRange * 2)
				return ;

			// 공속 검사
			if ( ch->ChekAttackType() && ch->CheckHackAttack(pc))
				return ;

			// 펫 타고 있으면 불가능
			if (pc->GetPet() && pc->GetPet()->IsMount())
				return ;

			// 공성 아이템 착용시 해당 스킬 발동
			int mixSkillIndex[] = { pc->m_opSturnIndex, pc->m_opBloodIndex, pc->m_opPoisonIndex, pc->m_opSlowIndex, pc->m_opMoveIndex };
			int mixSkillLevel[] = { pc->m_opSturnLevel, pc->m_opBloodLevel, pc->m_opPoisonLevel, pc->m_opSlowLevel, pc->m_opMoveLevel };
			CSkill* skillMixItem = NULL;
			int i;
			int bStop = 0;
			for (i = 0; i < 5; i++)
			{
				if (mixSkillIndex[i] > 0 && mixSkillLevel[i] > 0)
				{
					skillMixItem = gserver->m_skillProtoList.Create(mixSkillIndex[i], mixSkillLevel[i]);
					if (skillMixItem)
					{
						bool bApply;
						bStop = ApplySkill(ch, tch, skillMixItem, -1, bApply);
					}
					delete skillMixItem;
					skillMixItem = NULL;
					if (bStop != 0)
						return ;
				}
			}

			if (IS_PC(ch))
			{
				CPC* pPCAttacker = TO_PC(ch);
				CItem* weaponItem = pPCAttacker->m_wearInventory.wearItemInfo[WEARING_WEAPON];

				// 암흑 공격
				if (pPCAttacker->m_opAttackBlind > 0)
				{
					CSkill* pSkillBlind = gserver->m_skillProtoList.Create(415, pPCAttacker->m_opAttackBlind);
					int nRetApplySkill = 0;
					if (pSkillBlind)
					{
						bool bApply;
						nRetApplySkill = ApplySkill(ch, tch, pSkillBlind, -1, bApply);
					}
					delete pSkillBlind;
					pSkillBlind = NULL;
					if (nRetApplySkill != 0)
						return ;
				}

				// 독 공격
				if (pPCAttacker->m_opAttackPoison > 0)
				{
					CSkill* pSkillPoison = gserver->m_skillProtoList.Create(414, pPCAttacker->m_opAttackPoison);
					int nRetApplySkill = 0;
					if (pSkillPoison)
					{
						bool bApply;
						nRetApplySkill = ApplySkill(ch, tch, pSkillPoison, -1, bApply);
					}
					delete pSkillPoison;
					pSkillPoison = NULL;
					if (nRetApplySkill != 0)
						return ;
				}
			}
		} // PC 검사

		break;

	case MSG_CHAR_PET:
	case MSG_CHAR_ELEMENTAL:
		// TODO : 소환수 공속 검사
		// 공격 거리 검사
		if (GetDistance(ch, tch) > ch->m_attackRange * 2)
			return ;

		// 공속 검사
		if (ch->CheckHackAttack(pc))
			return ;

		break;

	default:
		break;
	}

	if(IS_PC(tch))
	{
		if( TO_PC(tch)->m_bImmortal == true )
			return;
	}

	if (DEAD(ch) || !ch->CanAttack() || pc->IsDisable())	return ;
	// 결계걸린 대상은 공격 못한다.
	if ( tch->m_assist.m_state & AST_FREEZE )	return;
	//무적 버프 대상은 공격할 수 없다.
	if ( tch->m_assist.m_state & AST_SAFEGUARD )
	{
		CNetMsg::SP rmsg(new CNetMsg);
		SysMsg(rmsg, MSG_SYS_DO_NOT_ATTACK_IMMOTAL);
		SEND_Q(rmsg, pc->m_desc);
		return;
	}


	// 대상이 NPC일때만 멀티 공격
	if (!IS_NPC(tch))
		packet->multicount = 0;

	// 최소한 공격 1회 이상
	bool bAttacked = false;
	bool bAttackedPet = false;		// 애완동물은 NPC상대시 레벨 검사

	// 멀티 공격 검사용
	std::set<int> listMultiTarget;

	while (tch)
	{
		bool bBlocked = false;

		// NPC를 공격할 때에만 속성맵 검사 (프리PK 지역이 아닐때만)
		if ( IS_NPC(tch) && !(tch->GetMapAttr() & MATT_FREEPKZONE) )
		{
			char tempy = GET_YLAYER(ch);
			bBlocked = (!area->IsNotBlocked(ch, tch, true, tempy));
		}

		int ret = 0;
		if (!bBlocked)
		{
			if (IS_PC(ch) && ch->IsEnemy(tch))
			{
				bAttacked = true;
#ifdef MONSTER_AI
				if (tch != NULL	&& IS_NPC(tch))
				{
					CNPC * pTemp = TO_NPC(tch);
					if (pTemp != NULL)
					{
						if (ch->m_level - tch->m_level <= 5 && pTemp->m_proto->m_index != 303 /*악마의 묘지*/)
						{
							bAttackedPet = true;
						}

						if (pTemp->m_bMoveLock || pTemp->m_bMoveToRegen)
						{
							pTemp->m_bMoveToRegen = false;
							pTemp->m_bMoveLock = false;
							pTemp->m_pulseMoveLock = 0;
							pTemp->m_postregendelay = 0;
						}
					}
				}
#else
				if (tch != NULL	&& IS_NPC(tch) && ch->m_level - tch->m_level <= 5)
				{
					CNPC * pTemp = TO_NPC(tch);
					if (pTemp != NULL && pTemp->m_proto->m_index != 303 /*악마의 묘지*/)
					{
						bAttackedPet = true;
					}
				}
#endif
			}

			listMultiTarget.insert(tch->m_index);
			ret = ProcAttack(ch, tch, ch->GetAttackType(NULL), NULL, 0);
		}

		if (ret == -1 || tch->m_index == -1) // ProcAttack()안에서 Character 객체가 소멸된 경우도 포함
		{
			tch = NULL;
			continue ;
		}

		//공격 발동형 스킬 추가
		if( pc->m_optionAttSkillList.count() > 0 )
		{
			//공격 할 시에 적에게 스킬 적용
			void* pos = pc->m_optionAttSkillList.GetHeadPosition();
			bool bApply = false;
			while (pos)
			{
				CSkill* skill = pc->m_passiveSkillList.GetNext(pos);
				if (skill && skill->m_proto)
				{
					int rand = GetRandom(1, 10000);
					if( rand < skill->m_optionSkillProb )
					{
						ApplySkill(ch, tch, skill, -1, bApply);
						if(bApply == false)
						{
							GAMELOG << init("EVENT_PCBANG_2NDS SKILL FAILED (LOGIN) ", pc ) << end;// 스킬 적용 실패
						}
					}
				}
			}
		}

		if (area->m_zone->IsPersonalDungeon() == false)
		{
			tch = NULL;
			continue;
		}

		if (packet->multicount && !DEAD(ch))
		{
			int multitarget = packet->list[packet->multicount].index;
			--packet->multicount;

			tch = area->FindCharInCell(ch, multitarget, (MSG_CHAR_TYPE)packet->tCharType);
			if (tch == NULL)
			{
				continue;
			}

			if (GetDistance(ch, tch) > ch->m_attackRange * 2)
			{
				tch = NULL;
				continue;
			}

			std::set<int>::iterator it = listMultiTarget.find(tch->m_index);
			if (it != listMultiTarget.end())
			{
				GAMELOG << init("HACK ATTACK MULTI TARGET", pc)
						<< "ZONE" << delim
						<< pc->m_pZone->m_index << delim
						<< "TARGET" << delim
						<< packet->tCharType << delim
						<< multitarget
						<< end;

				if (pc->m_desc->IncreaseHackCount(1))
					return ;

				tch = NULL;
			}
		}
		else
		{
			tch = NULL;
			continue;
		}

		if (packet->multicount <= 0)
		{
			tch = NULL;
			continue;
		}
	} // end while

	if (bAttackedPet && !ch->IsInPeaceZone(true))
		pc->m_pulseLastAttackSkill = gserver->m_pulse;

#ifdef EVENT_SEARCHFRIEND_TIME
	// 공격시 이벤트 시간 갱신 검사
	if (gserver->m_bSearchFriendEvent && (pc->m_nEventSearchFriendListCount >= 1)
			&& (pc->m_bEventSearchFriendSelect == true) && (pc->m_nTimeEventSearchFriend <= 216000)
			&& bAttacked && !ch->IsInPeaceZone(true))
		pc->m_pulseEventSearchFriend = gserver->m_pulse;
#endif // #ifdef EVENT_SEARCHFRIEND_TIME
}
Example #21
0
int DrawChart(CDataInterface *pData, CEnvParam *pEnv, Interaction *itt,
			 string VO, string &ppOutStruct,CResult **ppRst)
{	
	AnaWord aw;
	aw.Import(VO);
	CTString szChartType = aw.GetAt(0);//调用的算法名字
	
	if (szChartType == CHART_LINE)          //直线图
	{
		CLine line;
		(*ppRst) = line.OnChart(pData, VO);  
	}
	else if (szChartType == CHART_BAR)      //条状图
	{
		CBar Bar;
		(*ppRst) = Bar.OnChart(pData, VO);
	}
	else if (szChartType == CHART_PIE)      //饼图
	{
		CPie Pie;
		(*ppRst) = Pie.OnChart(pData, VO);
	}
	else if (szChartType == CHART_AREA)     //面积图
	{
		CArea Area;
		(*ppRst) = Area.OnChart(pData, VO);
	}
	else if (szChartType == CHART_BOXPLOT)  //盒状图
	{
		CBox Box;
		(*ppRst) = Box.OnChart(pData, VO);
	}
	else if (szChartType == CHART_HISTOGRAM)//直方图
	{
		CHistogram Histogram;
		(*ppRst) = Histogram.OnChart(pData, VO);
	}
	else if (szChartType == CHART_SCATTER)  //散点图
	{
		CScatter Scatter;
		(*ppRst) = Scatter.OnChart(pData, VO);
	}
	else if (szChartType == CHART_SELFCORRELATIONS) //自相关
	{
		CSelfCorrelation SelfCorr;
		(*ppRst) = SelfCorr.OnChart(pData,VO);
	}
	else if (szChartType == CHART_CROSSCORRELATIONS) //互相关
	{
		CCrossCorrelation CrossCorr;
		(*ppRst) = CrossCorr.OnChart(pData,VO);
	}
	else if (szChartType == CHART_EMP)
	{
		CEmp Emp;
		(*ppRst) = Emp.OnChart(pData,VO);
	}
	else
	{
		CResult *pResult = new CResult("图形接口算法调用错误");
		CTString szWarning = "没有相应的图形接口,请与供应商联系!";
		CRsltElementText *pWarningTextRslt = new CRsltElementText("错误!");
		pWarningTextRslt->AddString(szWarning);
		pResult->Add(pWarningTextRslt);
		(*ppRst) = pResult; 
		(*ppRst)->Print();
		return 1;
	}

	if (ppRst == NULL)
	{
		CResult *pResult = new CResult("图形接口算法调用错误");
		CTString szWarning = "您所选择的数据不适合相应的图形接口算法,请重新运行!";
		CRsltElementText *pWarningTextRslt = new CRsltElementText( "错误!" );
		pWarningTextRslt->AddString(szWarning);
		pResult->Add(pWarningTextRslt);
		(*ppRst) = pResult; 
		(*ppRst)->Print();
		return 1;
	}
	else
	{
		(*ppRst)->Print();
		return 0;
	}
}