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 }
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); } } } }
/************************************************************************************************ * 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; }
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); } } }
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(); }
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); }
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; }
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); } }
/************************************************************************************************ * 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); }
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 }
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; }
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(); } }
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 ; } }
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; }
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; }
ThickLine(const CCurve& curve) { m_curve = curve; m_area.append(curve); m_area.Thicken(0.001); }
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; }
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 }
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; } }