You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			447 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			GDScript
		
	
		
		
			
		
	
	
			447 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			GDScript
		
	
| 
								 
											2 years ago
										 
									 | 
							
								extends RefCounted
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static var force_mapped: bool
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func draw(canvas_item: CanvasItem, offset: Vector2, coords: Vector3i, skip_empty: bool, map_data: MetroidvaniaSystem.MapData, save_data: MetroidvaniaSystem.SaveData):
							 | 
						||
| 
								 | 
							
									if MetSys.settings.custom_elements and not map_data.custom_elements.is_empty():
							 | 
						||
| 
								 | 
							
										setup_custom_elements(canvas_item, offset, coords)
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var cell_data := map_data.get_cell_at(coords)
							 | 
						||
| 
								 | 
							
									if not cell_data:
							 | 
						||
| 
								 | 
							
										if not skip_empty:
							 | 
						||
| 
								 | 
							
											draw_empty(canvas_item, offset)
							 | 
						||
| 
								 | 
							
										return
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var discovered := 2
							 | 
						||
| 
								 | 
							
									if save_data:
							 | 
						||
| 
								 | 
							
										discovered = save_data.is_cell_discovered(coords)
							 | 
						||
| 
								 | 
							
									elif force_mapped:
							 | 
						||
| 
								 | 
							
										discovered = 1
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									if discovered == 0:
							 | 
						||
| 
								 | 
							
										if not skip_empty:
							 | 
						||
| 
								 | 
							
											draw_empty(canvas_item, offset)
							 | 
						||
| 
								 | 
							
										return
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var theme: MapTheme = MetSys.settings.theme
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var ci := canvas_item.get_canvas_item()
							 | 
						||
| 
								 | 
							
									var display_flags: int = (int(discovered == 2) * 255) | theme.mapped_display
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									# center
							 | 
						||
| 
								 | 
							
									if bool(display_flags & MetroidvaniaSystem.DISPLAY_CENTER):
							 | 
						||
| 
								 | 
							
										var room_color := cell_data.get_color()
							 | 
						||
| 
								 | 
							
										theme.center_texture.draw(ci, offset * MetSys.CELL_SIZE, room_color if discovered == 2 else theme.mapped_center_color)
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									# corners
							 | 
						||
| 
								 | 
							
									if theme.use_shared_borders:
							 | 
						||
| 
								 | 
							
										if not MetSys.has_meta(&"shared_borders_to_draw"):
							 | 
						||
| 
								 | 
							
											MetSys._add_meta(&"shared_borders_to_draw", {})#[Vector3i, Vector2]
							 | 
						||
| 
								 | 
							
											MetSys._add_meta(&"shared_borders_data", {"canvas_item": canvas_item, "display_flags": display_flags})
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										var shared_borders_to_draw: Dictionary = MetSys.get_meta(&"shared_borders_to_draw")
							 | 
						||
| 
								 | 
							
										shared_borders_to_draw[coords] = offset
							 | 
						||
| 
								 | 
							
									else:
							 | 
						||
| 
								 | 
							
										draw_regular_borders(canvas_item, offset, coords, map_data, cell_data, display_flags, discovered)
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									canvas_item.draw_set_transform_matrix(Transform2D())
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									if bool(display_flags & MetroidvaniaSystem.DISPLAY_SYMBOLS):
							 | 
						||
| 
								 | 
							
										var symbol: int = -1
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										if save_data and coords in save_data.custom_markers:
							 | 
						||
| 
								 | 
							
											var custom: int = save_data.custom_markers[coords]
							 | 
						||
| 
								 | 
							
											for i in range(63, -1, -1):
							 | 
						||
| 
								 | 
							
												if custom & 1 << i:
							 | 
						||
| 
								 | 
							
													symbol = i
							 | 
						||
| 
								 | 
							
													break
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										if symbol == -1:
							 | 
						||
| 
								 | 
							
											symbol = cell_data.get_symbol()
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										if symbol > - 1:
							 | 
						||
| 
								 | 
							
											if symbol >= theme.symbols.size():
							 | 
						||
| 
								 | 
							
												push_error("Bad symbol '%s' at '%s'" % [symbol, coords])
							 | 
						||
| 
								 | 
							
											else:
							 | 
						||
| 
								 | 
							
												canvas_item.draw_texture(theme.symbols[symbol], offset * MetSys.CELL_SIZE + MetSys.CELL_SIZE * 0.5 - theme.symbols[symbol].get_size() / 2)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func draw_regular_borders(canvas_item: CanvasItem, offset: Vector2, coords: Vector3i, map_data: MetroidvaniaSystem.MapData, cell_data: MetroidvaniaSystem.MapData.CellData, display_flags: int, discovered: int):
							 | 
						||
| 
								 | 
							
									var theme: MapTheme = MetSys.settings.theme
							 | 
						||
| 
								 | 
							
									var ci := canvas_item.get_canvas_item()
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									# borders
							 | 
						||
| 
								 | 
							
									var borders: Array[int] = [-1, -1, -1, -1]
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var display_outlines := bool(display_flags & MetroidvaniaSystem.DISPLAY_OUTLINE)
							 | 
						||
| 
								 | 
							
									for i in 4:
							 | 
						||
| 
								 | 
							
										var border: int = cell_data.get_border(i)
							 | 
						||
| 
								 | 
							
										if not display_outlines and border == 0:
							 | 
						||
| 
								 | 
							
											borders[i] = -1
							 | 
						||
| 
								 | 
							
										elif not bool(display_flags & MetroidvaniaSystem.DISPLAY_BORDERS):
							 | 
						||
| 
								 | 
							
											borders[i] = mini(border, 0 if display_outlines else -1)
							 | 
						||
| 
								 | 
							
										else:
							 | 
						||
| 
								 | 
							
											borders[i] = border
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									for i in 4:
							 | 
						||
| 
								 | 
							
										var texture: Texture2D
							 | 
						||
| 
								 | 
							
										var color: Color
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										var rotation := PI * 0.5 * i
							 | 
						||
| 
								 | 
							
										if borders[i] == -1:
							 | 
						||
| 
								 | 
							
											if display_outlines:
							 | 
						||
| 
								 | 
							
												texture = get_border_texture(theme, -1, i)
							 | 
						||
| 
								 | 
							
												color = Color.WHITE
							 | 
						||
| 
								 | 
							
										else:
							 | 
						||
| 
								 | 
							
											var border: int = borders[i]
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											if not bool(display_flags & MetroidvaniaSystem.DISPLAY_BORDERS):
							 | 
						||
| 
								 | 
							
												border = 0
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											texture = get_border_texture(theme, border, i)
							 | 
						||
| 
								 | 
							
											if discovered == 2:
							 | 
						||
| 
								 | 
							
												color = cell_data.get_border_color(i)
							 | 
						||
| 
								 | 
							
											else:
							 | 
						||
| 
								 | 
							
												color = theme.mapped_border_color
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										if not texture:
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										canvas_item.draw_set_transform(offset * MetSys.CELL_SIZE + MetSys.CELL_SIZE * 0.5, rotation, Vector2.ONE)
							 | 
						||
| 
								 | 
							
										match i:
							 | 
						||
| 
								 | 
							
											MetroidvaniaSystem.R, MetroidvaniaSystem.L:
							 | 
						||
| 
								 | 
							
												texture.draw(ci, -texture.get_size() / 2 + Vector2.RIGHT * (MetSys.CELL_SIZE.x * 0.5 - texture.get_width() / 2), color)
							 | 
						||
| 
								 | 
							
											MetroidvaniaSystem.D, MetroidvaniaSystem.U:
							 | 
						||
| 
								 | 
							
												texture.draw(ci, -texture.get_size() / 2 + Vector2.RIGHT * (MetSys.CELL_SIZE.y * 0.5 - texture.get_width() / 2), color)
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									if not display_outlines:
							 | 
						||
| 
								 | 
							
										return
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									# outer corner
							 | 
						||
| 
								 | 
							
									for i in 4:
							 | 
						||
| 
								 | 
							
										var j := rotate(i)
							 | 
						||
| 
								 | 
							
										if borders[i] == -1 or borders[j] == -1:
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										var texture: Texture2D = theme.outer_corner
							 | 
						||
| 
								 | 
							
										var corner_color: Color
							 | 
						||
| 
								 | 
							
										if discovered == 2:
							 | 
						||
| 
								 | 
							
											corner_color = get_shared_color(cell_data.get_border_color(i), cell_data.get_border_color(j), theme.default_border_color)
							 | 
						||
| 
								 | 
							
										else:
							 | 
						||
| 
								 | 
							
											corner_color = theme.mapped_border_color
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										canvas_item.draw_set_transform(offset * MetSys.CELL_SIZE + MetSys.CELL_SIZE * 0.5, PI * 0.5 * i, Vector2.ONE)
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										var corner_offset := -texture.get_size()
							 | 
						||
| 
								 | 
							
										if theme.use_shared_borders:
							 | 
						||
| 
								 | 
							
											corner_offset /= 2
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										match i:
							 | 
						||
| 
								 | 
							
											MetroidvaniaSystem.R, MetroidvaniaSystem.L:
							 | 
						||
| 
								 | 
							
												texture.draw(ci, MetSys.CELL_SIZE * 0.5 + corner_offset, corner_color)
							 | 
						||
| 
								 | 
							
											MetroidvaniaSystem.D, MetroidvaniaSystem.U:
							 | 
						||
| 
								 | 
							
												texture.draw(ci, Vector2(MetSys.CELL_SIZE.y, MetSys.CELL_SIZE.x) * 0.5 + corner_offset, corner_color)
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									# inner corner
							 | 
						||
| 
								 | 
							
									for i in 4:
							 | 
						||
| 
								 | 
							
										var j := rotate(i)
							 | 
						||
| 
								 | 
							
										if borders[i] != -1 or borders[j] != -1:
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										var neighbor_room := get_neighbor(map_data, coords, map_data.FWD[i] + map_data.FWD[j])
							 | 
						||
| 
								 | 
							
										if neighbor_room:
							 | 
						||
| 
								 | 
							
											if neighbor_room.borders[opposite(i)] == -1 and neighbor_room.borders[opposite(j)] == -1:
							 | 
						||
| 
								 | 
							
												continue
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										var texture: Texture2D = theme.inner_corner
							 | 
						||
| 
								 | 
							
										var color1 := get_neighbor(map_data, coords, map_data.FWD[i]).get_border_color(rotate(i))
							 | 
						||
| 
								 | 
							
										var color2 := get_neighbor(map_data, coords, map_data.FWD[j]).get_border_color(rotate(j, -1))
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										var corner_color := get_shared_color(color1, color2, theme.default_border_color)
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										canvas_item.draw_set_transform(offset * MetSys.CELL_SIZE + MetSys.CELL_SIZE * 0.5, PI * 0.5 * i, Vector2.ONE)
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										var corner_offset := -texture.get_size()
							 | 
						||
| 
								 | 
							
										if theme.use_shared_borders:
							 | 
						||
| 
								 | 
							
											corner_offset /= 2
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										match i:
							 | 
						||
| 
								 | 
							
											MetroidvaniaSystem.R, MetroidvaniaSystem.L:
							 | 
						||
| 
								 | 
							
												theme.inner_corner.draw(ci, MetSys.CELL_SIZE * 0.5 + corner_offset, corner_color)
							 | 
						||
| 
								 | 
							
											MetroidvaniaSystem.D, MetroidvaniaSystem.U:
							 | 
						||
| 
								 | 
							
												theme.inner_corner.draw(ci, Vector2(MetSys.CELL_SIZE.y, MetSys.CELL_SIZE.x) * 0.5 + corner_offset, corner_color)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func draw_shared_borders():
							 | 
						||
| 
								 | 
							
									assert(MetSys.settings.theme.use_shared_borders, "This function requires shared borders to be enabled.")
							 | 
						||
| 
								 | 
							
									if not MetSys.has_meta(&"shared_borders_to_draw"):
							 | 
						||
| 
								 | 
							
										return
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var theme: MapTheme = MetSys.settings.theme
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var shared_borders_to_draw: Dictionary = MetSys.get_meta(&"shared_borders_to_draw")
							 | 
						||
| 
								 | 
							
									var shared_borders_data: Dictionary = MetSys.get_meta(&"shared_borders_data")
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var shared_borders_colors: Dictionary#[Vector3i, Color]
							 | 
						||
| 
								 | 
							
									var shared_corners_data: Dictionary#[Vector3i, int]
							 | 
						||
| 
								 | 
							
									var shared_corners_colors: Dictionary#[Vector3i, Color]
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var display_flags: int = shared_borders_data["display_flags"]
							 | 
						||
| 
								 | 
							
									var canvas_item: CanvasItem = shared_borders_data["canvas_item"]
							 | 
						||
| 
								 | 
							
									var ci := canvas_item.get_canvas_item()
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var additional_corners: Dictionary#[Vector3i, Vector2]
							 | 
						||
| 
								 | 
							
									for coords in shared_borders_to_draw:
							 | 
						||
| 
								 | 
							
										for x in range (-1, 1):
							 | 
						||
| 
								 | 
							
											for y in range(-1, 1):
							 | 
						||
| 
								 | 
							
												var coords2: Vector3i = coords + Vector3i(x, y, 0)
							 | 
						||
| 
								 | 
							
												if not coords2 in shared_borders_to_draw:
							 | 
						||
| 
								 | 
							
													additional_corners[coords2] = shared_borders_to_draw[coords] + Vector2(x, y)
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									shared_borders_to_draw.merge(additional_corners)
							 | 
						||
| 
								 | 
							
									for coords in shared_borders_to_draw:
							 | 
						||
| 
								 | 
							
										var corner_data := 0
							 | 
						||
| 
								 | 
							
										corner_data |= (1 << 0) * (get_corner_bit(coords, MetroidvaniaSystem.R) | get_corner_bit(coords + Vector3i(1, 0, 0), MetroidvaniaSystem.L))
							 | 
						||
| 
								 | 
							
										corner_data |= (1 << 1) * (get_corner_bit(coords, MetroidvaniaSystem.D) | get_corner_bit(coords + Vector3i(0, 1, 0), MetroidvaniaSystem.U))
							 | 
						||
| 
								 | 
							
										corner_data |= (1 << 2) * (get_corner_bit(coords + Vector3i(0, 1, 0), MetroidvaniaSystem.R) | get_corner_bit(coords + Vector3i(1, 1, 0), MetroidvaniaSystem.L))
							 | 
						||
| 
								 | 
							
										corner_data |= (1 << 3) * (get_corner_bit(coords + Vector3i(1, 0, 0), MetroidvaniaSystem.D) | get_corner_bit(coords + Vector3i(1, 1, 0), MetroidvaniaSystem.U))
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										if theme.is_unicorner():
							 | 
						||
| 
								 | 
							
											corner_data = signi(corner_data) * 15
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										var use_default: bool
							 | 
						||
| 
								 | 
							
										var color_blend: Array[Color]
							 | 
						||
| 
								 | 
							
										for i in 4:
							 | 
						||
| 
								 | 
							
											var color: Color
							 | 
						||
| 
								 | 
							
											if i < 2:
							 | 
						||
| 
								 | 
							
												color = get_shared_border_color(coords, i)
							 | 
						||
| 
								 | 
							
											else:
							 | 
						||
| 
								 | 
							
												color = get_shared_border_color(coords + Vector3i(1, 1, 0), i)
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											if color == theme.default_border_color:
							 | 
						||
| 
								 | 
							
												use_default = true
							 | 
						||
| 
								 | 
							
											elif color.a > 0:
							 | 
						||
| 
								 | 
							
												color_blend.append(color)
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										shared_corners_data[coords] = corner_data
							 | 
						||
| 
								 | 
							
										if not color_blend.is_empty():
							 | 
						||
| 
								 | 
							
											var ratio: float = 1.0 / color_blend.size()
							 | 
						||
| 
								 | 
							
											shared_corners_colors[coords] = color_blend.reduce(func(final: Color, current: Color) -> Color: return final.lerp(current, ratio))
							 | 
						||
| 
								 | 
							
										elif use_default:
							 | 
						||
| 
								 | 
							
											shared_corners_colors[coords] = theme.default_border_color
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										var border_data: Array[int] = [-1, -1]
							 | 
						||
| 
								 | 
							
										var border_colors: Array[Color] = [Color(), Color()]
							 | 
						||
| 
								 | 
							
										for i in 2:
							 | 
						||
| 
								 | 
							
											var fwd := Vector3i(MetroidvaniaSystem.MapData.FWD[i].x, MetroidvaniaSystem.MapData.FWD[i].y, 0)
							 | 
						||
| 
								 | 
							
											border_data[i] = maxi(get_border_at(coords, i), get_border_at(coords + fwd, opposite(i)))
							 | 
						||
| 
								 | 
							
											border_colors[i] = get_shared_border_color(coords, i)
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										shared_borders_data[coords] = border_data
							 | 
						||
| 
								 | 
							
										shared_borders_colors[coords] = border_colors
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									# borders
							 | 
						||
| 
								 | 
							
									for coords in shared_borders_to_draw:
							 | 
						||
| 
								 | 
							
										var borders: Array[int] = shared_borders_data[coords]
							 | 
						||
| 
								 | 
							
										for i in 2:
							 | 
						||
| 
								 | 
							
											var texture: Texture2D
							 | 
						||
| 
								 | 
							
											var color: Color
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											var rotation := PI * 0.5 * i
							 | 
						||
| 
								 | 
							
											if borders[i] == -1:
							 | 
						||
| 
								 | 
							
												texture = get_border_texture(theme, -1, i)
							 | 
						||
| 
								 | 
							
												color = Color.WHITE
							 | 
						||
| 
								 | 
							
											else:
							 | 
						||
| 
								 | 
							
												var border: int = borders[i]
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												if not bool(display_flags & MetroidvaniaSystem.DISPLAY_BORDERS):
							 | 
						||
| 
								 | 
							
													border = 0
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												texture = get_border_texture(theme, border, i)
							 | 
						||
| 
								 | 
							
												color = shared_borders_colors[coords][i]
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											if not texture:
							 | 
						||
| 
								 | 
							
												continue
							 | 
						||
| 
								 | 
							
											
							 | 
						||
| 
								 | 
							
											canvas_item.draw_set_transform(shared_borders_to_draw[coords] * MetSys.CELL_SIZE + MetSys.CELL_SIZE * 0.5, rotation, Vector2.ONE)
							 | 
						||
| 
								 | 
							
											match i:
							 | 
						||
| 
								 | 
							
												MetroidvaniaSystem.R, MetroidvaniaSystem.L:
							 | 
						||
| 
								 | 
							
													texture.draw(ci, -texture.get_size() / 2 + Vector2.RIGHT * (MetSys.CELL_SIZE.x * 0.5), color)
							 | 
						||
| 
								 | 
							
												MetroidvaniaSystem.D, MetroidvaniaSystem.U:
							 | 
						||
| 
								 | 
							
													texture.draw(ci, -texture.get_size() / 2 + Vector2.RIGHT * (MetSys.CELL_SIZE.y * 0.5), color)
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									# corners
							 | 
						||
| 
								 | 
							
									for coords in shared_borders_to_draw:
							 | 
						||
| 
								 | 
							
										var offset: Vector2 = shared_borders_to_draw[coords]
							 | 
						||
| 
								 | 
							
										var corner_data: int = shared_corners_data[coords]
							 | 
						||
| 
								 | 
							
										var corner_type = signi(corner_data & 1) + signi(corner_data & 2) + signi(corner_data & 4) + signi(corner_data & 8)
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										var corner_texture: Texture2D
							 | 
						||
| 
								 | 
							
										var corner_rotation := -1
							 | 
						||
| 
								 | 
							
										match corner_type:
							 | 
						||
| 
								 | 
							
											1:
							 | 
						||
| 
								 | 
							
												corner_texture = theme.u_corner
							 | 
						||
| 
								 | 
							
												match corner_data:
							 | 
						||
| 
								 | 
							
													1:
							 | 
						||
| 
								 | 
							
														corner_rotation = 0
							 | 
						||
| 
								 | 
							
													2:
							 | 
						||
| 
								 | 
							
														corner_rotation = 3
							 | 
						||
| 
								 | 
							
													4:
							 | 
						||
| 
								 | 
							
														corner_rotation = 2
							 | 
						||
| 
								 | 
							
													8:
							 | 
						||
| 
								 | 
							
														corner_rotation = 1
							 | 
						||
| 
								 | 
							
											2:
							 | 
						||
| 
								 | 
							
												corner_texture = theme.l_corner
							 | 
						||
| 
								 | 
							
												match corner_data:
							 | 
						||
| 
								 | 
							
													3:
							 | 
						||
| 
								 | 
							
														corner_rotation = 3
							 | 
						||
| 
								 | 
							
													6:
							 | 
						||
| 
								 | 
							
														corner_rotation = 2
							 | 
						||
| 
								 | 
							
													9:
							 | 
						||
| 
								 | 
							
														corner_rotation = 0
							 | 
						||
| 
								 | 
							
													12:
							 | 
						||
| 
								 | 
							
														corner_rotation = 1
							 | 
						||
| 
								 | 
							
											3:
							 | 
						||
| 
								 | 
							
												corner_texture = theme.t_corner
							 | 
						||
| 
								 | 
							
												match corner_data:
							 | 
						||
| 
								 | 
							
													7:
							 | 
						||
| 
								 | 
							
														corner_rotation = 1
							 | 
						||
| 
								 | 
							
													11:
							 | 
						||
| 
								 | 
							
														corner_rotation = 2
							 | 
						||
| 
								 | 
							
													13:
							 | 
						||
| 
								 | 
							
														corner_rotation = 3
							 | 
						||
| 
								 | 
							
													14:
							 | 
						||
| 
								 | 
							
														corner_rotation = 0
							 | 
						||
| 
								 | 
							
											4:
							 | 
						||
| 
								 | 
							
												corner_texture = theme.cross_corner
							 | 
						||
| 
								 | 
							
												corner_rotation = 0
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										if corner_rotation == -1 or not corner_texture:
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										canvas_item.draw_set_transform(offset * MetSys.CELL_SIZE + MetSys.CELL_SIZE, PI * 0.5 * corner_rotation, Vector2.ONE)
							 | 
						||
| 
								 | 
							
										corner_texture.draw(canvas_item.get_canvas_item(), -corner_texture.get_size() / 2, shared_corners_colors[coords])
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									MetSys.remove_meta(&"shared_borders_to_draw")
							 | 
						||
| 
								 | 
							
									MetSys.remove_meta(&"shared_borders_data")
							 | 
						||
| 
								 | 
							
									canvas_item.draw_set_transform_matrix(Transform2D())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func setup_custom_elements(canvas_item: CanvasItem, offset: Vector2, coords: Vector3i):
							 | 
						||
| 
								 | 
							
										var custom_element_data: Dictionary
							 | 
						||
| 
								 | 
							
										if not MetSys.has_meta(&"custom_elements_data"):
							 | 
						||
| 
								 | 
							
											custom_element_data["canvas_item"] = canvas_item
							 | 
						||
| 
								 | 
							
											MetSys._add_meta(&"custom_elements_data", custom_element_data)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func draw_custom_elements(canvas_item: CanvasItem, elements: Dictionary, base_offset: Vector2, rect: Rect2i, layer: int):
							 | 
						||
| 
								 | 
							
									var element_manager: MetroidvaniaSystem.CustomElementManager = MetSys.settings.custom_elements
							 | 
						||
| 
								 | 
							
									var already_drawn: Array[Dictionary]
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									for y in rect.size.y:
							 | 
						||
| 
								 | 
							
										for x in rect.size.y:
							 | 
						||
| 
								 | 
							
											var pos := rect.position + Vector2i(x, y)
							 | 
						||
| 
								 | 
							
											for coords in elements:
							 | 
						||
| 
								 | 
							
												if coords.z != layer:
							 | 
						||
| 
								 | 
							
													continue
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												var element: Dictionary = elements[coords]
							 | 
						||
| 
								 | 
							
												if element in already_drawn:
							 | 
						||
| 
								 | 
							
													continue
							 | 
						||
| 
								 | 
							
												
							 | 
						||
| 
								 | 
							
												var elerect := Rect2i(coords.x, coords.y, element["size"].x, element["size"].y)
							 | 
						||
| 
								 | 
							
												if elerect.has_point(pos):
							 | 
						||
| 
								 | 
							
													element_manager.draw_element(canvas_item, coords, element.name, (base_offset + Vector2(coords.x, coords.y) - Vector2(pos) + Vector2(x, y)) * MetSys.CELL_SIZE, Vector2(element.size) * MetSys.CELL_SIZE, element.data)
							 | 
						||
| 
								 | 
							
													already_drawn.append(element)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func get_border_at(coords: Vector3i, idx: int) -> int:
							 | 
						||
| 
								 | 
							
									var cell_data = get_discovered_cell_at(coords)
							 | 
						||
| 
								 | 
							
									if not cell_data:
							 | 
						||
| 
								 | 
							
										return -1
							 | 
						||
| 
								 | 
							
									return cell_data.get_border(idx)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func get_corner_bit(coords: Vector3i, idx: int) -> int:
							 | 
						||
| 
								 | 
							
									return int(get_border_at(coords, idx) > -1)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func get_shared_border_color(coords: Vector3i, idx: int) -> Color:
							 | 
						||
| 
								 | 
							
									var fwd := Vector3i(MetroidvaniaSystem.MapData.FWD[idx].x, MetroidvaniaSystem.MapData.FWD[idx].y, 0)
							 | 
						||
| 
								 | 
							
									var color := Color.TRANSPARENT
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var cell_data = get_discovered_cell_at(coords)
							 | 
						||
| 
								 | 
							
									if cell_data:
							 | 
						||
| 
								 | 
							
										color = cell_data.get_border_color(idx)
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									cell_data = get_discovered_cell_at(coords + fwd)
							 | 
						||
| 
								 | 
							
									if cell_data:
							 | 
						||
| 
								 | 
							
										if color.a > 0:
							 | 
						||
| 
								 | 
							
											color = get_shared_color(color, cell_data.get_border_color(opposite(idx)), MetSys.settings.theme.default_border_color)
							 | 
						||
| 
								 | 
							
										else:
							 | 
						||
| 
								 | 
							
											color = cell_data.get_border_color(opposite(idx))
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									return color
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func get_discovered_cell_at(coords: Vector3i) -> MetroidvaniaSystem.MapData.CellData:
							 | 
						||
| 
								 | 
							
									var cell_data = MetSys.map_data.get_cell_at(coords)
							 | 
						||
| 
								 | 
							
									if cell_data and MetSys.is_cell_discovered(coords):
							 | 
						||
| 
								 | 
							
										return cell_data
							 | 
						||
| 
								 | 
							
									return null
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func get_shared_color(color1: Color, color2: Color, default: Color) -> Color:
							 | 
						||
| 
								 | 
							
									if color1 == default:
							 | 
						||
| 
								 | 
							
										return color2
							 | 
						||
| 
								 | 
							
									elif color2 == default:
							 | 
						||
| 
								 | 
							
										return color1
							 | 
						||
| 
								 | 
							
									return color1.lerp(color2, 0.5)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func get_border_texture(theme: MapTheme, idx: int, direction: int) -> Texture2D:
							 | 
						||
| 
								 | 
							
									var texture_name: StringName
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									if theme.rectangle:
							 | 
						||
| 
								 | 
							
										if direction == MetroidvaniaSystem.R or direction == MetroidvaniaSystem.L:
							 | 
						||
| 
								 | 
							
											match idx:
							 | 
						||
| 
								 | 
							
												-1:
							 | 
						||
| 
								 | 
							
													texture_name = &"vertical_separator"
							 | 
						||
| 
								 | 
							
												0:
							 | 
						||
| 
								 | 
							
													texture_name = &"vertical_wall"
							 | 
						||
| 
								 | 
							
												1:
							 | 
						||
| 
								 | 
							
													texture_name = &"vertical_passage"
							 | 
						||
| 
								 | 
							
												2:
							 | 
						||
| 
								 | 
							
													texture_name = &"vertical_borders"
							 | 
						||
| 
								 | 
							
										else:
							 | 
						||
| 
								 | 
							
											match idx:
							 | 
						||
| 
								 | 
							
												-1:
							 | 
						||
| 
								 | 
							
													texture_name = &"horizontal_separator"
							 | 
						||
| 
								 | 
							
												0:
							 | 
						||
| 
								 | 
							
													texture_name = &"horizontal_wall"
							 | 
						||
| 
								 | 
							
												1:
							 | 
						||
| 
								 | 
							
													texture_name = &"horizontal_passage"
							 | 
						||
| 
								 | 
							
												_:
							 | 
						||
| 
								 | 
							
													texture_name = &"vertical_borders"
							 | 
						||
| 
								 | 
							
									else:
							 | 
						||
| 
								 | 
							
										match idx:
							 | 
						||
| 
								 | 
							
											-1:
							 | 
						||
| 
								 | 
							
												texture_name = &"separator"
							 | 
						||
| 
								 | 
							
											0:
							 | 
						||
| 
								 | 
							
												texture_name = &"wall"
							 | 
						||
| 
								 | 
							
											1:
							 | 
						||
| 
								 | 
							
												texture_name = &"passage"
							 | 
						||
| 
								 | 
							
											_:
							 | 
						||
| 
								 | 
							
												texture_name = &"borders"
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									if idx >= 2:
							 | 
						||
| 
								 | 
							
										return theme.get(texture_name)[idx - 2]
							 | 
						||
| 
								 | 
							
									else:
							 | 
						||
| 
								 | 
							
										return theme.get(texture_name)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func draw_empty(canvas_item: CanvasItem, offset: Vector2):
							 | 
						||
| 
								 | 
							
									var theme: MapTheme = MetSys.settings.theme
							 | 
						||
| 
								 | 
							
									if theme.empty_space_texture:
							 | 
						||
| 
								 | 
							
										var ci := canvas_item.get_canvas_item()
							 | 
						||
| 
								 | 
							
										theme.empty_space_texture.draw(ci, offset * MetSys.CELL_SIZE, Color.WHITE)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func get_neighbor(map_data: MetroidvaniaSystem.MapData, coords: Vector3i, offset: Vector2i) -> MetroidvaniaSystem.MapData.CellData:
							 | 
						||
| 
								 | 
							
									var neighbor: Vector2i = Vector2i(coords.x, coords.y) + offset
							 | 
						||
| 
								 | 
							
									return map_data.get_cell_at(Vector3i(neighbor.x, neighbor.y, coords.z))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func rotate(i: int, amount := 1) -> int:
							 | 
						||
| 
								 | 
							
									return (i + amount) % 4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static func opposite(i: int) -> int:
							 | 
						||
| 
								 | 
							
									return (i + 2) % 4
							 |