public static SurroundingSurfaceValues MakeNew() { SurroundingSurfaceValues ssv = new SurroundingSurfaceValues(); ssv.xneg = ssv.zneg = ssv.xpos = ssv.zpos = 257; return(ssv); }
public void updateLightWith(List <Range1D> heightRanges, Coord blockChangedpRelCo, SurroundingSurfaceValues ssvs, bool solidBlockRemoved) { updateWindowsWithHeightRanges(heightRanges, blockChangedpRelCo, ssvs, solidBlockRemoved, true); }
private static bool SurroundingValuesGreaterThanHeight(SurroundingSurfaceValues ssvs, int height) { foreach (Direction dir in DirectionUtil.TheDirectionsXZ()) { int surfaceHeight = ssvs.valueForDirection(dir); if (surfaceHeight < height) { return(false); } } return(true); }
private static bool RangeAboveSurface(SimpleRange range, SurroundingSurfaceValues ssvs) { foreach (Direction dir in DirectionUtil.TheDirectionsXZ()) { int height = ssvs.valueForDirection(dir); if (height < range.extent()) { return(true); } } return(false); }
private void updateColumnsWithHigherHighestSurface(List <Range1D> heightRanges, Coord pRelCoord, SurroundingSurfaceValues ssvs, bool shouldPropagateLight) { b.bug("update w higher highest surf"); int x = pRelCoord.x, y = pRelCoord.y, z = pRelCoord.z; SimpleRange justCoveredColumn = new SimpleRange(y, 1); Range1D highest = heightRanges[heightRanges.Count - 1]; LightColumn newlico = null; int lowestSurroundingSurface = ssvs.lowestValue(); if (highest.range == 1) { AssertUtil.Assert(heightRanges.Count > 1, "what we just 'covered' bedrock?"); Range1D secondHighest = heightRanges[heightRanges.Count - 2]; justCoveredColumn = new SimpleRange(secondHighest.extent(), y + 1 - secondHighest.extent()); //(extent - start) //new column SimpleRange newColRange = justCoveredColumn; newColRange.range--; newlico = new LightColumn(PTwo.PTwoXZFromCoord(pRelCoord), 0, newColRange); m_lightColumnMap.addColumnAt(newlico, x, z); if (newColRange.extent() > lowestSurroundingSurface) { newlico.lightLevel = Window.LIGHT_LEVEL_MAX_BYTE; surfaceExposedColumns.Add(newlico); } } List <LightColumn> adjColsFlushToJustCovered = m_lightColumnMap.lightColumnsAdjacentToAndFlushWithSimpleRangeAndPoint(justCoveredColumn, new PTwo(x, z)); foreach (LightColumn adjcol in adjColsFlushToJustCovered) { //adj cols could still be above if (adjcol.extent() <= y) { //get surrounding surface for these? SurroundingSurfaceValues assvs = m_noisePatch.surfaceValuesSurrounding(adjcol.coord); if (adjcol.extent() <= assvs.lowestValue()) { surfaceExposedColumns.Remove(adjcol); adjcol.lightLevel = 0; // put back? } } } resetAndUpdateColumnsWithin(LightDomainAround(x, z)); }
// update a list of columns with a list of height ranges // cribbed from window map... // TODO: check surface status here as well. // could have changed... // many things to do: // check if any new ranges are cut-off or // exposed to: // other ranges // the surface. // can deal with surrounding ranges separately where surface is concerned... private void updateWindowsWithHeightRanges(List <Range1D> heightRanges, Coord pRelCoord, SurroundingSurfaceValues ssvs, bool solidBlockRemoved, bool shouldPropagateLight) { b.bug("update with ranges"); if (solidBlockRemoved) { updateWindowsWithHeightRangesSolidRemoved(heightRanges, pRelCoord, ssvs, shouldPropagateLight); ChunkManager.debugLinesAssistant.clearColumns(); //DBG return; } updateWindowsWithHeightRangesSolidAdded(heightRanges, pRelCoord, ssvs, shouldPropagateLight); ChunkManager.debugLinesAssistant.clearColumns(); //DBG }
private void updateWindowsWithHeightRangesSolidAdded(List <Range1D> heightRanges, Coord pRelCoord, SurroundingSurfaceValues ssvs, bool shouldPropagateLight) { Range1D highest = heightRanges[heightRanges.Count - 1]; int newSurfaceHeightAtXZ = highest.extent(); bool yIsNewHighestSurface = pRelCoord.y == newSurfaceHeightAtXZ - 1; b.bug("y is " + pRelCoord.y + " new surf height minus one: " + (newSurfaceHeightAtXZ - 1)); // WAS A FORMERLY SURFACE EXPOSED SURFACE COLUMN JUST COVERED? if (yIsNewHighestSurface) { updateColumnsWithHigherHighestSurface(heightRanges, pRelCoord, ssvs, shouldPropagateLight); return; } updateColumnsSolidAddedBelowSurface(heightRanges, pRelCoord, ssvs, shouldPropagateLight); }
private void updateColumnsSolidAddedBelowSurface(List <Range1D> heightRanges, Coord pRelCoord, SurroundingSurfaceValues ssvs, bool shouldPropagateLight) { b.bug("adding below surface"); int x = pRelCoord.x, y = pRelCoord.y, z = pRelCoord.z; DiscreteDomainRangeList <LightColumn> licols = m_lightColumnMap[x, z]; LightColumn prevColContainingY = licols.rangeContaining(y); AssertUtil.Assert(prevColContainingY != null, "confusing. how did we add a block not in the area of a light colm under the surface?"); List <LightColumn> columnsJustDisconnected = this.columnsThatColumnJustConnectedWith(prevColContainingY, y); LightColumn aboveSplit = licols.Incorporate(y, false); if (aboveSplit != null) { aboveSplit.coord = new PTwo(x, z); } LightColumn newBelow = licols.rangeContaining(y - 1); LightColumn newAbove = licols.rangeContaining(y + 1); if (newBelow == null && newAbove == null) // COLUMNS WERE CUT OFF? { b.bug("got both y above and below null"); // general reboot resetAndUpdateColumnsWithin(LightDomainAround(PTwo.PTwoXZFromCoord(pRelCoord))); return; } updateColumnOrLightestNeighbor(newBelow); updateColumnOrLightestNeighbor(newAbove); foreach (LightColumn colm in columnsJustDisconnected) { updateColumnOrLightestNeighbor(colm); } }
public void editLightWithSurroundingSurfaceValues(SurroundingSurfaceValues surroundingSurfaceValues, int patchRelativeZ) { // int patchRelativeZ = patchRelativeYZ.t; int spanOffset = patchRelativeZ - patchRelativeOrigin.z; bool canSeeSurface = false; foreach (Direction dir in DirectionUtil.TheDirectionsXZ()) { int surfaceHeight = surroundingSurfaceValues.valueForDirection(dir); if (windowHeightAtOffsetGreaterThanHeight(spanOffset, surfaceHeight)) { canSeeSurface = true; this.addLightLevelsWithAdjacentSurfaceHeightSpanOffset(surfaceHeight, spanOffset); } } if (!canSeeSurface) { this.lightLevelTrapezoid.removeLightLevelsBySubtractingAdjacentSurface(patchRelativeZ); } }
private void addDiscontinuityAt(SimpleRange disRange, int x, int z, SurroundingSurfaceValues surroundingSurfaceHeights, bool allowEditing, bool doLightUpdate) { //TODO: deal with this the light column way! Window tookDiscontinuity = incorporateDiscontinuityAt(disRange, x, z, allowEditing); if (tookDiscontinuity != null) { tookDiscontinuity.editLightWithSurroundingSurfaceValues(surroundingSurfaceHeights, z); return; } // TODO: edit windows when we edit a range // new window Window win = new Window(this, disRange, x, z); //TODO: add surrounding surf to constructor addWindowAt(win, x, z); if (doLightUpdate) { win.influenceNeighborsIfAboveSurfaceAddLight(); } }
private void addDiscontinuityWith(Range1D aboveRange, Range1D belowRange, int xx, int zz, SurroundingSurfaceValues ssvs, bool wantToEditPossibly, bool doLightUpDate) { int gap = aboveRange.start - belowRange.extent(); if (gap > 0) { addDiscontinuityAt(new SimpleRange(belowRange.extent(), gap), xx, zz, ssvs, wantToEditPossibly, doLightUpDate); } }
/* * clients use this to: * add to window map (by providing a 'column' (list of ranges) of solid areas) * will not 'overwrite' extant window height ranges * (for overwriting, use the update version of this func.) */ public void addDiscontinuityToWindowsWithHeightRanges(List <Range1D> heights1D, int xx, int zz, SurroundingSurfaceValues ssvs) { // m_lightColumnCalculator.updateWindowsWithHeightRanges(heights1D, xx,zz,ssvs, -1, false); return; for (int j = 1; j < heights1D.Count; ++j) { addDiscontinuityWith(heights1D[j], heights1D[j - 1], xx, zz, ssvs, false, false); } }
/* * Clients use this to: * update the window map to reflect changed * height ranges which were (potentially) already set (but possibly no longer valid) in windows * */ public void updateWindowsWithHeightRanges(List <Range1D> heightRanges, int x, int z, SurroundingSurfaceValues ssvs) { // m_lightColumnCalculator.updateWindowsWithHeightRangesAndUpdateLight(heightRanges, x, z, ssvs, -1, false); return; //reset column clearColumnAt(x, z); // re-add ranges for (int j = 1; j < heightRanges.Count; ++j) { addDiscontinuityWith(heightRanges[j], heightRanges[j - 1], x, z, ssvs, true, true); } if (windows[x] == null) { return; } //WINDOW MAINTENANCE List <Window> wins = windows[x]; Window win = null; //TRIM EDGES for (int i = 0; i < wins.Count; ++i) { win = wins[i]; win.assertSpansAreSaneDebug("bfr trim domain"); //DBG // trim edges of windows if needed // at extent if (win.trimDomain()) { // check whether we should remove the window if (win.spanRange <= 0) { wins.RemoveAt(i); --i; } } } for (int i = 0; i < wins.Count; ++i) { // split windows at z if needed win = wins[i]; if (win.spanContainsZ(z)) { List <Window> posSideWindows = win.splitAtZ(z); if (posSideWindows != null) { int count = 0; foreach (Window posSideWin in posSideWindows) //MAX COUNT: 2 { posSideWin.assertSpansAreSaneDebug("pos side win "); //DBG count++; wins.Insert(i + count, posSideWin); } i += count; } win.assertSpansAreSaneDebug("after done splitting win (wMAP)"); //DBG } } //DEBUG if (NoiseCoord.Equal(this.m_noisePatch.coord, new NoiseCoord(0, 0))) { debugAllWindowHeightColumns(); } }
private void updateRangeListAtXZ(List <Range1D> heightRanges, Coord pRelCoord, bool solidBlockRemoved, SurroundingSurfaceValues ssvs) { DiscreteDomainRangeList <LightColumn> liCols = m_lightColumnMap[pRelCoord.x, pRelCoord.z]; if (!solidBlockRemoved && heightRanges.Count <= 1) // equal zero would be down right silly. { return; } // y above highest extent? int highestDiscontinuity = liCols.highestExtent(); int lowestSurroundingLevel = ssvs.lowestValue(); //CASE WHERE A BLOCK IS ADDED TO THE TOP OF OR OVER TOP OF THE SURFACE if (pRelCoord.y > highestDiscontinuity && !solidBlockRemoved) { // Y MUST BE THE TOP BLOCK? int hRangeCount = heightRanges.Count; SimpleRange between = discontinuityBetween(heightRanges[hRangeCount - 2], heightRanges[hRangeCount - 1]); if (!between.isErsatzNull()) { AssertUtil.Assert(pRelCoord.y == between.extentMinusOne(), "confused. y is " + pRelCoord.y + " between range is " + between.toString()); int lightValue = pRelCoord.y >= lowestSurroundingLevel? (int)Window.LIGHT_LEVEL_MAX_BYTE : 0; LightColumn licol = new LightColumn(PTwo.PTwoXZFromCoord(pRelCoord), (byte)lightValue, between); liCols.Add(licol); return; // licol; } throw new Exception("don't want to be here. we think a block couldn't be placed vertically in between at this point"); } //TODO handle case where y is above surface, solid block removed // need to destroy some discon ranges (not incorporate y). Range1D highest = heightRanges[heightRanges.Count - 1]; if (pRelCoord.y > highest.extent()) { liCols.RemoveStartAbove(highest.extent()); } else { LightColumn newCol = liCols.Incorporate(pRelCoord.y, solidBlockRemoved); if (newCol != null) { newCol.coord = new PTwo(pRelCoord.x, pRelCoord.z); } // throw new Exception("lots of exceptions. we failed to incorp a solid block added."); } b.bug("we incorporated a pRelCOord: " + pRelCoord.toString() + "solid removed was: " + solidBlockRemoved); m_lightColumnMap[pRelCoord.x, pRelCoord.z] = liCols; }
private void updateWindowsWithHeightRangesSolidRemoved(List <Range1D> heightRanges, Coord pRelCoord, SurroundingSurfaceValues ssvs, bool shouldPropagateLight) { int x = pRelCoord.x, y = pRelCoord.y, z = pRelCoord.z; DiscreteDomainRangeList <LightColumn> liCols = m_lightColumnMap[x, z]; LightColumn colJustBelowYBeforeUpdate = liCols.rangeContaining(y - 1); //null if there wasn't Range1D highest = heightRanges[heightRanges.Count - 1]; int newSurfaceHeightExtentAtXZ = highest.extent(); if (colJustBelowYBeforeUpdate != null) { colJustBelowYBeforeUpdate = colJustBelowYBeforeUpdate.Copy(); // safe keeping } updateRangeListAtXZ(heightRanges, pRelCoord, true, ssvs); //case where y represents a removed top block // where either air or solid was underneath the // former top block if (newSurfaceHeightExtentAtXZ <= y) { //no column here anymore //surface was revealed. //add any adjacent blocks to exposed list // if they weren't on the list before // add them to need update list // our work is done...return (put the above in a function) b.bug("got new surf less than y"); Coord surfaceTopCoord = pRelCoord; if (newSurfaceHeightExtentAtXZ < y) { b.bug("is fully less than"); surfaceTopCoord.y = newSurfaceHeightExtentAtXZ; } foreach (LightColumn col in m_lightColumnMap.lightColumnsAdjacentToAndAtleastPartiallyAbove(surfaceTopCoord)) { b.bug("updating "); addToSurfaceExposedColumnIfNotContains(col); col.lightLevel = Window.LIGHT_LEVEL_MAX_BYTE; updateColumnAt(col, col.coord, null, LightDomainAround(col.coord)); } m_lightColumnMap[x, z] = liCols; return; } //REMAINING CASES: Y REMOVED FROM BELOW SURFACE int lowestSurroundingSurface = ssvs.lowestValue(); LightColumn colAtY = liCols.rangeContaining(y); AssertUtil.Assert(colAtY != null, "(remove block. didn't get a col at y in lc calc) y was: " + y); if (y > lowestSurroundingSurface) //just update it. anything new will update. anything not new won't. { //one way or another a newly exposed column here addToSurfaceExposedColumnIfNotContains(colAtY); updateColumnAt(colAtY, colAtY.coord, null, LightDomainAround(x, z)); return; } //REMAINING CASES: Y WAS BELOW THE SURFACE AND NOT EXPOSED BY ADJACENT SURFACE. List <LightColumn> justConnectedWithColumns = columnsThatColumnJustConnectedWith(colAtY, y); if (justConnectedWithColumns.Count == 0) { return; } LightColumn lightest = colAtY; bool atYIsLightest = true; foreach (LightColumn justConnectedCol in justConnectedWithColumns) { if (justConnectedCol.lightLevel > lightest.lightLevel) { lightest = justConnectedCol; atYIsLightest = false; } } if (atYIsLightest) { foreach (LightColumn adjCol in justConnectedWithColumns) { updateColumnAt(adjCol, adjCol.coord, colAtY, LightDomainAround(adjCol.coord)); } } else { updateColumnAt(colAtY, colAtY.coord, lightest, LightDomainAround(colAtY.coord)); } }
public void replaceColumnsWithHeightRanges(List <Range1D> heightRanges, int x, int z, SurroundingSurfaceValues ssvs) { int countAt = m_lightColumnMap.countAt(x, z); if (countAt > 0) { //clobber columns here. m_lightColumnMap.clearColumnsAt(x, z); clearSurfaceExposedListAt(x, z); } //add new discons int lowestSurroundingSurfaceHeight = ssvs.lowestValue(); ssvs.debugAssertLowestNonNegFound(); //DBG // AssertUtil.Assert(lowestSurroundingSurfaceHeight > 0, "weird. lowest sur value is: " + lowestSurroundingSurfaceHeight); // AssertUtil.Assert(NoiseCoord.Equal(this.debugOrigNoiseCoord, m_noisePatch.coord ), "not equal? nco " // + m_noisePatch.coord.toString() + " and orig??" + debugOrigNoiseCoord.toString()); //fails List <SimpleRange> discons = discontinuitiesFromHeightRanges(heightRanges); int light = 0; LightColumn col = null; bool exposedLightColumn = false; int countDisCon = discons.Count; //DBG foreach (SimpleRange discon in discons) { exposedLightColumn = discon.extent() > lowestSurroundingSurfaceHeight; light = 0; // discon.extent() > lowestSurroundingSurfaceHeight ? (int) Window.LIGHT_LEVEL_MAX_BYTE : 0; col = new LightColumn(new PTwo(x, z), (byte)light, discon); if (exposedLightColumn) { //DBG // if (countDisCon > 1) { // bugIf0Neg1( " discon extent: " + discon.extent() + " lowest Sur Height: " + lowestSurroundingSurfaceHeight + " x: " + x + " z: " + z); // } surfaceExposedColumns.Add(col); // this.addDebugColumnIfNoiseCoZIsNeg(col, 4); } m_lightColumnMap.addColumnAt(col, x, z); } }