fix bug
This commit is contained in:
@@ -88,7 +88,7 @@ class Map():
|
||||
# 或者我们简单点,不分类返回,只返回总览?
|
||||
# 为了保持接口不变,我们可以现场过滤。
|
||||
|
||||
from src.classes.region import NormalRegion, CultivateRegion, CityRegion, SectRegion
|
||||
from src.classes.region import NormalRegion, CultivateRegion, CityRegion
|
||||
|
||||
def filter_regions(cls):
|
||||
return {rid: r for rid, r in self.regions.items() if isinstance(r, cls)}
|
||||
|
||||
@@ -11,65 +11,6 @@ from src.classes.plant import Plant, plants_by_id
|
||||
from src.classes.sect import sects_by_name
|
||||
|
||||
|
||||
def get_tiles_from_shape(shape: 'Shape', north_west_cor: str, south_east_cor: str) -> list[tuple[int, int]]:
|
||||
"""
|
||||
根据形状和两个角点坐标,计算出对应的所有坐标点
|
||||
"""
|
||||
if not north_west_cor or not south_east_cor:
|
||||
return []
|
||||
|
||||
nw_coords = tuple(map(int, north_west_cor.split(',')))
|
||||
se_coords = tuple(map(int, south_east_cor.split(',')))
|
||||
|
||||
min_x, min_y = nw_coords
|
||||
max_x, max_y = se_coords
|
||||
|
||||
coordinates = []
|
||||
|
||||
if shape == Shape.SQUARE or shape == Shape.RECTANGLE:
|
||||
for x in range(min_x, max_x + 1):
|
||||
for y in range(min_y, max_y + 1):
|
||||
coordinates.append((x, y))
|
||||
|
||||
elif shape == Shape.MEANDERING:
|
||||
distance_x = max_x - min_x
|
||||
distance_y = max_y - min_y
|
||||
total_distance = max(distance_x, distance_y)
|
||||
|
||||
if total_distance < 10: width = 1
|
||||
elif total_distance < 30: width = 2
|
||||
else: width = 3
|
||||
|
||||
path_points = []
|
||||
if distance_x >= distance_y:
|
||||
for x in range(min_x, max_x + 1):
|
||||
progress = (x - min_x) / max(distance_x, 1)
|
||||
base_y = min_y + int(progress * distance_y)
|
||||
import math
|
||||
wave_amplitude = min(3, distance_y // 4) if distance_y > 0 else 0
|
||||
wave_y = int(wave_amplitude * math.sin(progress * math.pi * 2))
|
||||
y = max(min_y, min(max_y, base_y + wave_y))
|
||||
path_points.append((x, y))
|
||||
else:
|
||||
for y in range(min_y, max_y + 1):
|
||||
progress = (y - min_y) / max(distance_y, 1)
|
||||
base_x = min_x + int(progress * distance_x)
|
||||
import math
|
||||
wave_amplitude = min(3, distance_x // 4) if distance_x > 0 else 0
|
||||
wave_x = int(wave_amplitude * math.sin(progress * math.pi * 2))
|
||||
x = max(min_x, min(max_x, base_x + wave_x))
|
||||
path_points.append((x, y))
|
||||
|
||||
for px, py in path_points:
|
||||
for dx in range(-width//2, width//2 + 1):
|
||||
for dy in range(-width//2, width//2 + 1):
|
||||
nx, ny = px + dx, py + dy
|
||||
if min_x <= nx <= max_x and min_y <= ny <= max_y:
|
||||
coordinates.append((nx, ny))
|
||||
|
||||
return sorted(list(set(coordinates)))
|
||||
|
||||
|
||||
@dataclass
|
||||
class Region(ABC):
|
||||
"""
|
||||
@@ -79,12 +20,7 @@ class Region(ABC):
|
||||
name: str
|
||||
desc: str
|
||||
|
||||
# 可选/默认值,因为现在主要通过外部传入 cors 初始化
|
||||
shape: 'Shape' = field(default=None)
|
||||
north_west_cor: str = ""
|
||||
south_east_cor: str = ""
|
||||
|
||||
# 核心坐标数据
|
||||
# 核心坐标数据,由 load_map.py 注入
|
||||
cors: list[tuple[int, int]] = field(default_factory=list)
|
||||
|
||||
# 计算字段
|
||||
@@ -93,13 +29,6 @@ class Region(ABC):
|
||||
|
||||
def __post_init__(self):
|
||||
"""初始化计算字段"""
|
||||
if self.shape is None:
|
||||
self.shape = Shape.SQUARE # 默认值
|
||||
|
||||
# 如果 cors 为空且提供了旧版坐标字符串,尝试计算 (兼容性)
|
||||
if not self.cors and self.north_west_cor and self.south_east_cor:
|
||||
self.cors = get_tiles_from_shape(self.shape, self.north_west_cor, self.south_east_cor)
|
||||
|
||||
# 基于坐标点计算面积
|
||||
self.area = len(self.cors)
|
||||
|
||||
@@ -116,12 +45,7 @@ class Region(ABC):
|
||||
self.center_loc = min(self.cors, key=_dist2)
|
||||
else:
|
||||
# Fallback
|
||||
if self.north_west_cor and self.south_east_cor:
|
||||
nw = list(map(int, self.north_west_cor.split(',')))
|
||||
se = list(map(int, self.south_east_cor.split(',')))
|
||||
self.center_loc = ((nw[0]+se[0])//2, (nw[1]+se[1])//2)
|
||||
else:
|
||||
self.center_loc = (0, 0)
|
||||
self.center_loc = (0, 0)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(self.id)
|
||||
@@ -157,20 +81,6 @@ class Region(ABC):
|
||||
}
|
||||
|
||||
|
||||
class Shape(Enum):
|
||||
SQUARE = "square"
|
||||
RECTANGLE = "rectangle"
|
||||
MEANDERING = "meandering"
|
||||
|
||||
@classmethod
|
||||
def from_str(cls, shape_str: str) -> 'Shape':
|
||||
if not shape_str: return cls.SQUARE
|
||||
for shape in cls:
|
||||
if shape.value == shape_str:
|
||||
return shape
|
||||
return cls.SQUARE
|
||||
|
||||
|
||||
@dataclass
|
||||
class NormalRegion(Region):
|
||||
"""普通区域"""
|
||||
|
||||
@@ -24,6 +24,11 @@ class TileType(Enum):
|
||||
RUINS = "ruins" # 遗迹
|
||||
FARM = "farm" # 农田
|
||||
SECT = "sect" # 宗门
|
||||
ISLAND = "island" # 岛屿
|
||||
BAMBOO = "bamboo" # 竹林
|
||||
GOBI = "gobi" # 戈壁
|
||||
TUNDRA = "tundra" # 苔原
|
||||
MARSH = "marsh" # 湿地
|
||||
|
||||
@dataclass
|
||||
class Tile():
|
||||
|
||||
@@ -2,10 +2,11 @@ import os
|
||||
import csv
|
||||
from src.classes.map import Map
|
||||
from src.classes.tile import TileType
|
||||
from src.classes.region import Region, Shape, NormalRegion, CultivateRegion, CityRegion
|
||||
from src.classes.region import Region, NormalRegion, CultivateRegion, CityRegion
|
||||
from src.classes.sect_region import SectRegion
|
||||
from src.utils.df import game_configs, get_str, get_int
|
||||
from src.classes.essence import EssenceType
|
||||
from src.classes.sect import sects_by_id # 直接导入已加载的宗门数据
|
||||
|
||||
# 静态配置路径
|
||||
CONFIG_DIR = os.path.join(os.path.dirname(__file__), "../../static/game_configs")
|
||||
@@ -36,13 +37,11 @@ def load_cultivation_world_map() -> Map:
|
||||
for x, tile_name in enumerate(row):
|
||||
if x < width:
|
||||
try:
|
||||
# TileType 通常是大写,兼容 CSV 可能存的小写
|
||||
t_type = TileType[tile_name.upper()]
|
||||
except KeyError:
|
||||
# 兼容性处理:如果是 sect 名称,映射为山地或平原
|
||||
# 编辑器可能把 sect 名称也存进来了
|
||||
# 这里简单处理为 MOUNTAIN,或者根据需要扩展 TileType
|
||||
t_type = TileType.MOUNTAIN if "宗" in tile_name else TileType.PLAIN
|
||||
# 如果不是标准地形,则是宗门驻地名称
|
||||
# 这些名称直接对应 SECT 类型
|
||||
t_type = TileType.SECT
|
||||
|
||||
game_map.create_tile(x, y, t_type)
|
||||
|
||||
@@ -105,9 +104,16 @@ def _load_and_assign_regions(game_map: Map, region_coords: dict[int, list[tuple[
|
||||
params["essence_type"] = EssenceType.from_str(get_str(row, "root_type"))
|
||||
params["essence_density"] = get_int(row, "root_density")
|
||||
elif type_tag == "sect":
|
||||
params["sect_id"] = get_int(row, "sect_id")
|
||||
params["sect_name"] = get_str(row, "name") # 假设驻地名即区域名
|
||||
# image_path 暂不处理或需要另寻来源
|
||||
sect_id = get_int(row, "sect_id")
|
||||
params["sect_id"] = sect_id
|
||||
|
||||
# 直接从已加载的 sects_by_id 中获取宗门对象
|
||||
# 如果找不到对应的 sect_id,默认使用驻地名称作为兜底(防止崩溃),但正常情况下应该能找到
|
||||
sect_obj = sects_by_id.get(sect_id)
|
||||
if sect_obj:
|
||||
params["sect_name"] = sect_obj.name
|
||||
else:
|
||||
params["sect_name"] = get_str(row, "name")
|
||||
|
||||
# 实例化
|
||||
try:
|
||||
@@ -137,4 +143,4 @@ def _parse_list(s: str) -> list[int]:
|
||||
try:
|
||||
return [int(x.strip()) for x in s.split(",") if x.strip()]
|
||||
except:
|
||||
return []
|
||||
return []
|
||||
|
||||
Reference in New Issue
Block a user