void CHC_GameSystem::ClickMouseUp(CHC_Line & L) { CHC_Vector3 P; int x, y; L.istYequal0(P); xyToBoardxy(P[0], P[2], x, y); if (InMap(SelectX, SelectY)) { if (InMap(x, y)) { Delete_mirror(SelectX, SelectY); Insert_mirror(x, y, MousePickMirror, PickMirrorState); SelectX = x, SelectY = y; // Select } else { Delete_mirror(SelectX, SelectY); SelectX = SelectY = 255; // outside } } else if (InToolBar(SelectX, SelectY) >= 0) { SelectX = SelectY = 255; if (InMap(x, y)) { Insert_mirror(x, y, MousePickMirror, PickMirrorState); SelectX = x, SelectY = y; // Select } } }
//计算地图两坐标点的距离. int dis(Point p1,Point p2) { if(p1 == p2) return 0; Point q[40]; int d[40] = {0}; int u[8][8] = {0}; int start,end; start = 0; end = 1; q[start] = p1; u[p1.x][p1.y] = 1; while(start < end) { for(int i = 0;i < 6;i++) { int tx = q[start].x + cDirection[i][0]; int ty = q[start].y + cDirection[i][1]; if(InMap(tx,ty)) { if(!u[tx][ty]) { q[end] = Point(tx,ty); d[end++] = d[start] + 1; u[tx][ty] = 1; if(Point(tx,ty) == p2) return d[end - 1]; } } } start++; } return 0x7FFFFFFF; }
bool CHC_GameSystem::Delete_mirror(int x, int y) { if (!InMap(x, y) || !now_map[x][y].isMirror()) return false; now_map[x][y].obj = BLANK_ID; ++now_nm[now_map[x][y].mirror_s]; return true; }
bool CHC_GameSystem::Insert_mirror(int x, int y, int sort, int d) { if (!InMap(x, y) || now_nm[sort] == 0 || !now_map[x][y].isBlank()) return false; now_map[x][y].obj = MIRROR_ID; now_map[x][y].mirror_s = sort; now_map[x][y].dir = d; --now_nm[sort]; return true; }
void CHC_GameSystem::KeyBoardChangeState(int dx) { if (MousePickMirror >= 0) { PickMirrorState = (PickMirrorState + dx + NUM_MIRROR_STATE) % NUM_MIRROR_STATE; } else if (InMap(SelectX, SelectY) && now_map[SelectX][SelectY].isMirror()) { now_map[SelectX][SelectY].dir = (now_map[SelectX][SelectY].dir + dx + NUM_MIRROR_STATE) % NUM_MIRROR_STATE; } }
void CalcStampdownPos() { float lv = 4; //if(!InMap(raystart)) {stdownvalid = mapstdownvalid = 0; return;} Vector3 ptt = raystart, vta; NormalizeVector3(&vta, &raydir); vta *= lv; float h; int nlp = farzvalue * 1.5f / lv; int m = (ptt.y < GetHeight(ptt.x, ptt.z)) ? 0 : 1; for(int i = 0; i < nlp; i++) { ptt += vta; if(!InMap(ptt)) continue; //{stdownvalid = mapstdownvalid = 0; return;} h = GetHeight(ptt.x, ptt.z); if(ptt.y == h) break; //if( (!m && (ptt.y > h)) // || (m && (ptt.y < h)) ) if(m ^ ((ptt.y > h)?1:0)) {vta *= -0.5f; m = 1 - m;} } if(InMap(ptt)) {mapstdownpos = ptt; mapstdownpos.y = h; mapstdownvalid = 1;} else mapstdownvalid = 0; if(mapstdownvalid && InLevel(mapstdownpos)) {stdownpos = mapstdownpos; stdownvalid = 1;} else stdownvalid = 0; }
void CHC_GameSystem::RefreshBackTrace(int x, int y, int d, CHC_Color & col) { mark[x][y][d] = true; now_map[x][y].col[d/2].add(col); x += dx[d/2], y += dy[d/2]; if (!InMap(x, y) || mark[x][y][d]) return; now_map[x][y].col[(d / 2 + 2) % 4].add(col); int d_1, d_2; if (now_map[x][y].isMirror()) { if (now_map[x][y].mirror_s == 0) { d_1 = Reflection(d, now_map[x][y].dir, 0); if (d_1 < 0) return; RefreshBackTrace(x, y, d_1, col); } else if (now_map[x][y].mirror_s == 2) { d_1 = Reflection(d, now_map[x][y].dir, 0); d_2 = Reflection(d, (now_map[x][y].dir + 4) % NUM_MIRROR_STATE, 0); if (d_1 >= 0) RefreshBackTrace(x, y, d_1, col); else if (d_2 >= 0) RefreshBackTrace(x, y, d_2, col); } else if (now_map[x][y].mirror_s == 4) { d_1 = Reflection(d, now_map[x][y].dir, 0); d_2 = Reflection(d, (now_map[x][y].dir + 4) % NUM_MIRROR_STATE, 0); if (d_1 >= 0) RefreshBackTrace(x, y, d_1, col); else if (d_2 >= 0) RefreshBackTrace(x, y, d_2, col); if (d / 2 % 2 == 1) { // - if (now_map[x][y].dir != 0 && now_map[x][y].dir != 4) RefreshBackTrace(x, y, d, col); } else { // | if (now_map[x][y].dir != 2 && now_map[x][y].dir != 6) RefreshBackTrace(x, y, d, col); } } } else if (now_map[x][y].isSender()) { return; } else { RefreshBackTrace(x, y, d, col); } }
void CHC_GameSystem::ClickMouse(CHC_Line & L) { CHC_Vector3 P; getnearest(L, P); int x, y; xyToBoardxy(P[0], P[1], x, y); SelectX = 255, SelectY = 255; if (InToolBar(x, y) >= 0) { if (MouseLeftDown && now_nm[y - MIRROR_TOOLBAR_Y] > 0) { SelectX = x, SelectY = y; MousePickMirror = y - MIRROR_TOOLBAR_Y; PickMirrorState = START_MIRROR_STATE; } else MousePickMirror = -1; } else if (InMap(x, y)) { if (MouseLeftDown && now_map[x][y].isMirror()) { SelectX = x, SelectY = y; PickMirrorState = now_map[x][y].dir; MousePickMirror = now_map[x][y].mirror_s; } else MousePickMirror = -1; } }
WorldPoint3D Map3D_c::TurnLEAlongShoreLine(WorldPoint3D waterPoint, WorldPoint3D beachedPoint, WorldPoint3D toPoint) { WorldPoint3D movedPoint = {0,0,0.}, firstEndPoint = {0,0,0.}, secondEndPoint = {0,0,0.}; WorldPoint3D testPt = {0,0,0.}, realBeachedPt = {0,0,0.}; double alpha, sideA, sideB, sideC, sideD, shorelineLength; long startver, endver, x1, y1, x2, y2, testcase = 0; LongPointHdl ptsHdl = GetPointsHdl(); if(!ptsHdl) return waterPoint; if (!InMap (beachedPoint.p)) return waterPoint; // something went wrong don't do anything if (OnLand (beachedPoint.p)) { // Find shoreline segment where LE has beached and get the endpoints // Then move LE parallel to shoreline in the direction the beaching vector tends towards // May only want to do this for current movement... WorldPoint center; float dist; long segNo = PointOnWhichSeg(beachedPoint.p.pLong,beachedPoint.p.pLat,&startver,&endver,&dist); if (segNo==-1) return waterPoint; // this should probably be an error firstEndPoint.p.pLong = (*ptsHdl)[startver].h; firstEndPoint.p.pLat = (*ptsHdl)[startver].v; secondEndPoint.p.pLong = (*ptsHdl)[endver].h; secondEndPoint.p.pLat = (*ptsHdl)[endver].v; center.pLong = (waterPoint.p.pLong + beachedPoint.p.pLong) / 2; center.pLat = (waterPoint.p.pLat + beachedPoint.p.pLat) / 2; sideA = DistanceBetweenWorldPoints(waterPoint.p,firstEndPoint.p); sideB = DistanceBetweenWorldPoints(beachedPoint.p,waterPoint.p); sideC = DistanceBetweenWorldPoints(beachedPoint.p,firstEndPoint.p); sideD = DistanceBetweenWorldPoints(waterPoint.p,toPoint.p); shorelineLength = DistanceBetweenWorldPoints(secondEndPoint.p,firstEndPoint.p); testPt.p.pLat = beachedPoint.p.pLat + DistanceToLat(LongToDistance(firstEndPoint.p.pLong - secondEndPoint.p.pLong,center)*(sideD/shorelineLength)); testPt.p.pLong = beachedPoint.p.pLong - DistanceToLong(LatToDistance(firstEndPoint.p.pLat - secondEndPoint.p.pLat)*(sideD/shorelineLength),center); if (InMap(testPt.p) && !OnLand(testPt.p)) { testcase = 1; } else { testPt.p.pLat = beachedPoint.p.pLat + DistanceToLat(LongToDistance(secondEndPoint.p.pLong - firstEndPoint.p.pLong,center)*(sideD/shorelineLength)); testPt.p.pLong = beachedPoint.p.pLong - DistanceToLong(LatToDistance(secondEndPoint.p.pLat - firstEndPoint.p.pLat)*(sideD/shorelineLength),center); if (InMap(testPt.p) && !OnLand(testPt.p)) { testcase = 2; } } if (testcase==1) { realBeachedPt.p.pLat = beachedPoint.p.pLat - DistanceToLat(LongToDistance(firstEndPoint.p.pLong - secondEndPoint.p.pLong,center)*(dist/shorelineLength)); realBeachedPt.p.pLong = beachedPoint.p.pLong + DistanceToLong(LatToDistance(firstEndPoint.p.pLat - secondEndPoint.p.pLat)*(dist/shorelineLength),center); sideB = DistanceBetweenWorldPoints(realBeachedPt.p,waterPoint.p); } else if (testcase==2) { realBeachedPt.p.pLat = beachedPoint.p.pLat - DistanceToLat(LongToDistance(secondEndPoint.p.pLong - firstEndPoint.p.pLong,center)*(dist/shorelineLength)); realBeachedPt.p.pLong = beachedPoint.p.pLong + DistanceToLong(LatToDistance(secondEndPoint.p.pLat - firstEndPoint.p.pLat)*(dist/shorelineLength),center); sideB = DistanceBetweenWorldPoints(realBeachedPt.p,waterPoint.p); } alpha = acos((sideB*sideB + sideC*sideC - sideA*sideA)/(2*sideB*sideC)); // turn direction determined by which is greater, alpha or 90, towards larger one, if same? if (alpha > PI/2.) { movedPoint.p.pLat = waterPoint.p.pLat + DistanceToLat(LatToDistance(firstEndPoint.p.pLat - secondEndPoint.p.pLat)*(sideB/shorelineLength)); movedPoint.p.pLong = waterPoint.p.pLong + DistanceToLong(LongToDistance(firstEndPoint.p.pLong - secondEndPoint.p.pLong,center)*(sideB/shorelineLength),center); } else { movedPoint.p.pLat = waterPoint.p.pLat + DistanceToLat(LatToDistance(secondEndPoint.p.pLat - firstEndPoint.p.pLat)*(sideB/shorelineLength)); movedPoint.p.pLong = waterPoint.p.pLong + DistanceToLong(LongToDistance(secondEndPoint.p.pLong - firstEndPoint.p.pLong,center)*(sideB/shorelineLength),center); } movedPoint.z = beachedPoint.z; // check that movedPoint is not onLand if (InMap(movedPoint.p) && !OnLand(movedPoint.p)) return movedPoint; else // try again { /*WorldRect wBounds = this -> GetMapBounds(); // use bounds to determine how far offshore to move point double latDiff = fabs(float(wBounds.hiLat - wBounds.loLat)/1000000); double lonDiff = fabs(float(wBounds.loLong - wBounds.hiLong)/1000000); double distOffshore; // probably want an option for user to set this value if (latDiff >=1 || lonDiff >=1){ if (sideD<1) distOffshore = 1; else distOffshore = sideD;} else if (latDiff >=.1 || lonDiff >=.1) { if (sideD<.5) distOffshore = .5; else distOffshore = sideD;} else if (latDiff >=.01 || lonDiff >=.01) { if (sideD<.05) distOffshore = .05; else distOffshore = sideD;}*/ double distOffshore; // probably want an option for user to set this value //if (sideD<1) distOffshore = fMinDistOffshore; else distOffshore = sideD; if (sideD<fMinDistOffshore) distOffshore = fMinDistOffshore; else distOffshore = sideD; //if (sideD < 1) distOffshore = 1.; // at least 1km //if (sideD < 1) distOffshore = .05; // at least 1km //if (sideD < 5) distOffshore = 5.; // at least 1km //else distOffshore = sideD; { movedPoint.p.pLat = beachedPoint.p.pLat + DistanceToLat(LongToDistance(firstEndPoint.p.pLong - secondEndPoint.p.pLong,center)*(distOffshore/shorelineLength)); movedPoint.p.pLong = beachedPoint.p.pLong - DistanceToLong(LatToDistance(firstEndPoint.p.pLat - secondEndPoint.p.pLat)*(distOffshore/shorelineLength),center); } if (InMap(movedPoint.p) && !OnLand(movedPoint.p)) return movedPoint; else { movedPoint.p.pLat = beachedPoint.p.pLat + DistanceToLat(LongToDistance(secondEndPoint.p.pLong - firstEndPoint.p.pLong,center)*(distOffshore/shorelineLength)); movedPoint.p.pLong = beachedPoint.p.pLong - DistanceToLong(LatToDistance(secondEndPoint.p.pLat - firstEndPoint.p.pLat)*(distOffshore/shorelineLength),center); } if (InMap(movedPoint.p) && !OnLand(movedPoint.p)) return movedPoint; else { distOffshore = 2*distOffshore; movedPoint.p.pLat = beachedPoint.p.pLat + DistanceToLat(LongToDistance(firstEndPoint.p.pLong - secondEndPoint.p.pLong,center)*(distOffshore/shorelineLength)); movedPoint.p.pLong = beachedPoint.p.pLong - DistanceToLong(LatToDistance(firstEndPoint.p.pLat - secondEndPoint.p.pLat)*(distOffshore/shorelineLength),center); if (InMap(movedPoint.p) && !OnLand(movedPoint.p)) return movedPoint; else { movedPoint.p.pLat = beachedPoint.p.pLat + DistanceToLat(LongToDistance(secondEndPoint.p.pLong - firstEndPoint.p.pLong,center)*(distOffshore/shorelineLength)); movedPoint.p.pLong = beachedPoint.p.pLong - DistanceToLong(LatToDistance(secondEndPoint.p.pLat - firstEndPoint.p.pLat)*(distOffshore/shorelineLength),center); } if (InMap(movedPoint.p) && !OnLand(movedPoint.p)) return movedPoint; else return waterPoint; } } } return waterPoint; // shouldn't get here }
void CHC_GameSystem::KeyBoardDelete() { if (InMap(SelectX, SelectY) && now_map[SelectX][SelectY].isMirror()) { Delete_mirror(SelectX, SelectY); } }