extends Node2D enum Stats {WATER, FERTILITY, PRESENCE} const TERRAIN_SIZE = Vector2i(300, 300) const LEVELS_NUMBER : int = 20 const MAP_RATIO = 8; @onready var image := Image.create_empty( TERRAIN_SIZE.x, TERRAIN_SIZE.y, true, Image.Format.FORMAT_RGBF ) @onready var texture : ImageTexture = ImageTexture.create_from_image(image) var sum := 0.0 func _ready(): setup_texture(Vector3i(0, 0, -5)) func map_to_pixel( pos : Vector2 ) -> Vector2i : return Vector2i( int(pos.x / MAP_RATIO), int(pos.y / MAP_RATIO) ) func is_on_map(pos: Vector2) -> bool: return pos.x >= 0 and pos.x <= TERRAIN_SIZE.x * MAP_RATIO and pos.y >= 0 and pos.y <= TERRAIN_SIZE.y * MAP_RATIO func color_value_to_level( color_value : float ) -> int: return roundi(color_value*LEVELS_NUMBER) - float(LEVELS_NUMBER)/2 func color_to_levels( color: Color ) -> Vector3i : return Vector3i( color_value_to_level(color.r), color_value_to_level(color.g), color_value_to_level(color.b), ) func level_to_color_value( level : int ) -> float: var limited_level = max( min( level, float(LEVELS_NUMBER)/2 ), -float(LEVELS_NUMBER)/2 ) return float(limited_level+float(LEVELS_NUMBER)/2)/LEVELS_NUMBER func levels_to_color( levels: Vector3i ) -> Color : return Color( level_to_color_value(levels.x), level_to_color_value(levels.y), level_to_color_value(levels.z) ) func modification_to_levels( stat: Stats, modification: int ) -> Vector3i : var levels = Vector3i() match stat: Stats.WATER: levels.x = modification Stats.FERTILITY: levels.y = modification Stats.PRESENCE: levels.z = modification return levels func modify_pixel( pixel_pos: Vector2i, stat: Stats, modification: int, ): var actual_levels = color_to_levels(image.get_pixelv(pixel_pos)) var modification_levels = modification_to_levels(stat, modification) var calculated_levels = actual_levels + modification_levels set_pixel(pixel_pos, calculated_levels) func set_pixel( pixel_pos: Vector2i, level: Vector3i, ): image.set_pixelv(pixel_pos, levels_to_color(level)) func modify_zone( center: Vector2, radius: float, stat : Stats, modification: int ): var pixel_center = map_to_pixel(center) var pixel_radius = int(radius / MAP_RATIO) for x in range(pixel_center.x - pixel_radius, pixel_center.x + pixel_radius + 1) : for y in range(pixel_center.y - pixel_radius, pixel_center.y + pixel_radius + 1): if not is_on_map(Vector2i(x, y)): continue if pow(x - pixel_center.x,2) + pow(y - pixel_center.y,2) <= pow(pixel_radius,2): modify_pixel( Vector2i(x, y), stat, modification ) update_texture() func modify_rect( pos: Vector2, size: Vector2, stat : Stats, modification: int ): var pixel_pos = map_to_pixel(pos) var pixel_size = map_to_pixel(size) for x in range(pixel_pos.x, pixel_pos.x+pixel_size.x) : for y in range(pixel_pos.y, pixel_pos.y+pixel_size.y): modify_pixel( Vector2i(x, y), stat, modification ) update_texture() func get_stat( pos: Vector2, stat : Stats ) -> int: var pixel_pos = map_to_pixel(pos) var levels = color_to_levels(image.get_pixelv(pixel_pos)) match stat: Stats.WATER: return levels.x Stats.FERTILITY: return levels.y Stats.PRESENCE: return levels.z _: return 0 func setup_texture( levels : Vector3i ): for x in range(0, TERRAIN_SIZE.x) : for y in range(0, TERRAIN_SIZE.y): set_pixel(Vector2i(x,y), levels) update_texture() func update_texture(): texture.update(image) func get_texture(): return texture