/// <summary> /// Draw the lines and dots around a location, as well as the closest dot to that location. /// </summary> /// <param name="location"></param> /// <returns></returns> public static Vector3 RenderAvailablePositions(Vector3 location) { float closestDistance = float.MaxValue; float floorHeight = TerrainGenerator.getInstance().getFloorHeight(); float hoverHeight = 0.5f; Vector3 closestPosition = location; int sigSplit = NumSteps / NumSigDots; bool useCachedData = Vector3.Distance(location, LastInputPoint) < 0.1f; List <Module> nearModules; // If we want to use cached data, we can skip most of this function. // Otherwise, update the cache. if (useCachedData) { return(LastSnapPoint); } else { nearModules = ModuleHelper.GetAllModules(module => { float dist = Vector3.Distance(module.getPosition(), location); bool inRange = dist < MaxDistToCheck * 2; bool isNotActiveModule = module != ActiveModule; return(inRange && isNotActiveModule); }); LastListModules = nearModules; LastInputPoint = location; // Only clear the group if we're not using cache DebugRenderer.ClearGroup(GroupName); } foreach (Module module in nearModules) { bool flipflop = true; List <PositionsLine> lines; // Attempt to use cached data. We don't need to use the cached flag here // because if cache is set, we skip this block entirely. This is only a check // to see if the module has data in the dict already. if (ModuleLineCache.ContainsKey(module)) { lines = ModuleLineCache[module]; } else { lines = GetPositionsAroundModule(module); ModuleLineCache.Add(module, lines); } foreach (var line in lines) { var startPoint = line.First(); var endPoint = line.Last(); startPoint.y = floorHeight; endPoint.y = floorHeight; bool renderedAnyDot = false; // line is a List<Vector3>, so iterate through it to draw the points. foreach (Vector3 point in line) { Vector3 pointOnFloor = point; pointOnFloor.y = floorHeight; // This math will put the dots at the end of each section. bool isSignificantPoint = line.IndexOf(point) % sigSplit == (sigSplit - 1); bool canLink = Connection.canLink( ActiveModule, module, pointOnFloor, module.getPosition()); bool canPlace = module.canPlaceModule( pointOnFloor, Vector3.up, ActiveModuleSize); if (canLink && canPlace) { renderedAnyDot = true; var tmpPoint = pointOnFloor; tmpPoint.y += hoverHeight; // Dots are red and large if significant, else blue and small. DebugRenderer.AddCube( GroupName, tmpPoint, (isSignificantPoint) ? Color.blue : Color.red, (isSignificantPoint) ? 0.75f : 0.25f); // If the distance to this point is less than the last closest, // update the closest. float dist = Vector3.Distance(pointOnFloor, location); if (dist < closestDistance) { closestDistance = dist; closestPosition = pointOnFloor; } } } // Only render the line if a dot was rendered, but always flip-flop the color. if (renderedAnyDot) { var tmpStart = startPoint; var tmpEnd = endPoint; tmpStart.y += hoverHeight; tmpEnd.y += hoverHeight; // Alternate colors, draw the line. DebugRenderer.AddLine( GroupName, tmpStart, tmpEnd, (flipflop) ? Color.blue : Color.green, 0.125f); } flipflop = !flipflop; } } Rendering = true; LastSnapPoint = closestPosition; return(closestPosition); }