164 lines
3.5 KiB
GDScript
164 lines
3.5 KiB
GDScript
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
|