Compare commits

...

3 Commits

Author SHA1 Message Date
f5abf92cff
fetch up pyglet 2024-05-23 00:01:14 +08:00
c945f33074
好欸!感觉框架开发起来了 2024-05-22 23:58:14 +08:00
82edb560ba
DR rs 0.3.4 (我甚至觉得应该是 0.4.0 2024-05-22 23:47:54 +08:00
10 changed files with 206 additions and 148 deletions

@ -1 +1 @@
Subproject commit ea875640db0e529769fcfe597faa3c3267c2b1e3 Subproject commit 55b02b16d01bd0cafa5b0db3cd2e574299db9d34

View File

@ -9,6 +9,9 @@ from .lib import * # noqa: F403
from typing import TYPE_CHECKING, Dict, Tuple, Optional, List from typing import TYPE_CHECKING, Dict, Tuple, Optional, List
if TYPE_CHECKING: if TYPE_CHECKING:
IdType = int
RawConnectionData = Tuple[int, int, IdType, IdType]
def get_version_str() -> str: def get_version_str() -> str:
""" """
获取版本号 获取版本号
@ -163,6 +166,42 @@ if TYPE_CHECKING:
def __init__(self, save_default: Optional[bool] = False) -> None: def __init__(self, save_default: Optional[bool] = False) -> None:
... ...
class SR1Connection_rs: # NOQA
"""用于存储一堆连接的信息
同时提供了一些好用的 API
至少总比你在那里吭哧吭哧在 Python 里搜快
pub datas: Vec<Connection>"""
def search_connection_by_parent(
self, parent_id: IdType
) -> List[RawConnectionData]:
"""通过父节点搜索连接"""
...
def search_connection_by_child(self, child_id: IdType) -> List[RawConnectionData]:
"""通过子节点搜索连接"""
...
def search_connection_by_id(self, any_id: IdType) -> List[RawConnectionData]:
"""通过父子中任意一个 id 搜索连接"""
...
def search_by_both_id(
self, parent_id: IdType, child_id: IdType
) -> List[RawConnectionData]:
"""通过父子双方 id 获取连接
保险起见, 我还是返回一个 Vec
万一真有 / 连接呢"""
...
def get_raw_data(self) -> List[RawConnectionData]:
"""获取原始数据
万一你确实需要吭哧吭哧去处理原始数据呢"""
...
class SR1Ship_rs: # NOQA class SR1Ship_rs: # NOQA
"""用于高效且省内存的读取 SR1Ship""" """用于高效且省内存的读取 SR1Ship"""
@ -206,11 +245,6 @@ if TYPE_CHECKING:
"""-x -y +x +y 左下右上""" """-x -y +x +y 左下右上"""
... ...
@property
def connection(self) -> List[Tuple[int, int, int, int]]:
"""获取所有连接信息"""
...
def get_part_box( def get_part_box(
self, part_id: int self, part_id: int
) -> Optional[Tuple[Tuple[int, int], Tuple[int, int]]]: ) -> Optional[Tuple[Tuple[int, int], Tuple[int, int]]]:
@ -229,6 +263,16 @@ if TYPE_CHECKING:
) -> None: ) -> None:
... ...
def connections(self) -> SR1Connection_rs:
"""获取所有连接"""
...
def disconnected_parts(
self
) -> List[Tuple[List[Tuple[SR1PartType_rs, SR1PartData_rs]], SR1Connection_rs]]:
"""获取所有未连接的零件"""
...
class Console_rs: # NOQA class Console_rs: # NOQA
def __init__(self) -> None: def __init__(self) -> None:
... ...

View File

@ -146,7 +146,7 @@ dependencies = [
[[package]] [[package]]
name = "difficult_rocket_rs" name = "difficult_rocket_rs"
version = "0.3.3" version = "0.3.4"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"dict_derive", "dict_derive",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "difficult_rocket_rs" name = "difficult_rocket_rs"
version = "0.3.3" version = "0.3.4"
edition = "2021" edition = "2021"
license-file = '../../LICENSE' license-file = '../../LICENSE'
authors = ["shenjackyuanjie <3695888@qq.com>"] authors = ["shenjackyuanjie <3695888@qq.com>"]

View File

@ -31,6 +31,7 @@ fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_class::<python::data::PySR1PartType>()?; m.add_class::<python::data::PySR1PartType>()?;
m.add_class::<python::data::PySR1PartData>()?; m.add_class::<python::data::PySR1PartData>()?;
m.add_class::<python::data::PySaveStatus>()?; m.add_class::<python::data::PySaveStatus>()?;
m.add_class::<python::data::PySR1Connections>()?;
m.add_class::<python::console::PyConsole>()?; m.add_class::<python::console::PyConsole>()?;
// m.add_class::<python::editor::EditorArea>()?; // m.add_class::<python::editor::EditorArea>()?;
Ok(()) Ok(())

View File

@ -5,7 +5,7 @@ use pyo3::prelude::*;
use crate::dr_physics::math::{Point2D, Rotate}; use crate::dr_physics::math::{Point2D, Rotate};
use crate::sr1_parse::part_list::RawPartList; use crate::sr1_parse::part_list::RawPartList;
use crate::sr1_parse::ship::RawShip; use crate::sr1_parse::ship::{Connection, Connections, RawConnectionData, RawShip};
use crate::sr1_parse::SaveStatus; use crate::sr1_parse::SaveStatus;
use crate::sr1_parse::{get_max_box, SR1PartData, SR1PartListTrait}; use crate::sr1_parse::{get_max_box, SR1PartData, SR1PartListTrait};
use crate::sr1_parse::{SR1PartList, SR1PartType, SR1Ship}; use crate::sr1_parse::{SR1PartList, SR1PartType, SR1Ship};
@ -207,41 +207,47 @@ impl PySR1PartData {
} }
#[pyclass] #[pyclass]
#[derive(Clone, Debug)] #[derive(Debug, Clone)]
#[pyo3(name = "SR1PartTypeArrayIterator_rs")] #[pyo3(name = "SR1Connection_rs")]
pub struct PySR1PartDataIterator { pub struct PySR1Connections {
pub datas: Vec<(PySR1PartType, PySR1PartData)>, pub datas: Vec<Connection>,
pub index: usize,
} }
#[pymethods] #[pymethods]
impl PySR1PartDataIterator { impl PySR1Connections {
fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<(PySR1PartType, PySR1PartData)> { /// 通过父节点获取连接
if slf.index < slf.datas.len() { fn search_connection_by_parent(&self, parent_id: IdType) -> Vec<RawConnectionData> {
slf.index += 1; self.datas.iter().filter(|x| x.parent_part == parent_id).map(|x| x.as_raw_data()).collect()
Some(slf.datas[slf.index - 1].clone())
} else {
None
}
} }
} /// 通过子节点获取连接
fn search_by_child(&self, child_id: IdType) -> Vec<RawConnectionData> {
/// 用来存一堆 PartData 的数组 self.datas.iter().filter(|x| x.child_part == child_id).map(|x| x.as_raw_data()).collect()
#[pyclass] }
#[derive(Clone, Debug)] /// 通过父子中任意一个 id 搜索连接
#[pyo3(name = "SR1PartArray_rs")] fn search_by_id(&self, any_id: IdType) -> Vec<RawConnectionData> {
pub struct PySR1PartArray { self.datas
pub datas: Vec<(PySR1PartType, PySR1PartData)>, .iter()
pub part_list: SR1PartList, .filter(|x| x.parent_part == any_id || x.child_part == any_id)
} .map(|x| x.as_raw_data())
.collect()
#[pymethods] }
impl PySR1PartArray { /// 通过父子双方 id 获取连接
fn __iter__(&self) -> PySR1PartDataIterator { ///
PySR1PartDataIterator { /// 保险期间, 我还是返回一个 Vec
datas: self.datas.clone(), ///
index: 0, /// 万一真有 双/多 连接呢
} fn search_by_both_id(&self, parent_id: IdType, child_id: IdType) -> Vec<RawConnectionData> {
self.datas
.iter()
.filter(|x| x.parent_part == parent_id && x.child_part == child_id)
.map(|x| x.as_raw_data())
.collect()
}
/// 获取所有连接的原始数据
///
/// 万一你确实需要吭哧吭哧去处理原始数据呢
fn get_raw_data(&self) -> Vec<RawConnectionData> {
self.datas.iter().map(|x| x.as_raw_data()).collect()
} }
} }
@ -272,41 +278,28 @@ impl PySR1Ship {
} }
} }
fn parts(&self) -> PySR1PartArray { fn disconnected_parts(&self) -> Vec<(Vec<(PySR1PartType, PySR1PartData)>, PySR1Connections)> {
let mut parts: Vec<(PySR1PartType, PySR1PartData)> = Vec::new();
for part_data in self.ship.parts.iter() {
if let Some(part_type) = self.part_list.get_part_type(&part_data.part_type_id) {
let part_type = PySR1PartType::new(part_type.clone());
let py_part_data = PySR1PartData::new(part_data.clone());
parts.push((part_type, py_part_data));
}
}
PySR1PartArray {
datas: parts,
part_list: self.part_list.clone(),
}
}
fn disconnected_parts(&self) -> Vec<PySR1PartArray> {
match self.ship.disconnected.as_ref() { match self.ship.disconnected.as_ref() {
Some(parts) => { Some(parts) => {
if parts.is_empty() { if parts.is_empty() {
return Vec::new(); return Vec::new();
} }
let mut result = Vec::with_capacity(parts.len()); let mut result = Vec::with_capacity(parts.len());
for (part_group, _) in parts.iter() { for (part_group, connections) in parts.iter() {
let mut part_list = Vec::with_capacity(part_group.len()); let mut group_parts = Vec::with_capacity(part_group.len());
for part_data in part_group.iter() { for part_data in part_group.iter() {
if let Some(part_type) = self.part_list.get_part_type(&part_data.part_type_id) { if let Some(part_type) = self.part_list.get_part_type(&part_data.part_type_id) {
let part_type = PySR1PartType::new(part_type.clone()); let part_type = PySR1PartType::new(part_type.clone());
let py_part_data = PySR1PartData::new(part_data.clone()); let py_part_data = PySR1PartData::new(part_data.clone());
part_list.push((part_type, py_part_data)); group_parts.push((part_type, py_part_data));
} }
} }
result.push(PySR1PartArray { result.push((
datas: part_list, group_parts,
part_list: self.part_list.clone(), PySR1Connections {
}); datas: connections.clone().unwrap_or_default(),
},
));
} }
result result
} }
@ -339,12 +332,12 @@ impl PySR1Ship {
#[getter] #[getter]
fn get_lift_off(&self) -> bool { fn get_lift_off(&self) -> bool {
self.ship.lift_off.to_owned() self.ship.lift_off
} }
#[getter] #[getter]
fn get_touch_ground(&self) -> bool { fn get_touch_ground(&self) -> bool {
self.ship.touch_ground.to_owned() self.ship.touch_ground
} }
#[getter] #[getter]
@ -357,18 +350,10 @@ impl PySR1Ship {
mass mass
} }
#[getter] fn connections(&self) -> PySR1Connections {
fn get_connection(&self) -> Vec<(i32, i32, IdType, IdType)> { PySR1Connections {
let mut connections = Vec::new(); datas: self.ship.connections.clone(),
for connect in self.ship.connections.iter() {
connections.push((
connect.parent_attach_point,
connect.child_attach_point,
connect.parent_part,
connect.child_part,
));
} }
connections
} }
fn as_list(&self) -> Vec<(PySR1PartType, PySR1PartData)> { fn as_list(&self) -> Vec<(PySR1PartType, PySR1PartData)> {

View File

@ -155,6 +155,8 @@ pub struct DisconnectedPart {
pub connects: Connections, pub connects: Connections,
} }
pub type RawConnectionData = (i32, i32, IdType, IdType);
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Connection { pub struct Connection {
#[serde(rename = "@parentAttachPoint")] #[serde(rename = "@parentAttachPoint")]
@ -167,6 +169,18 @@ pub struct Connection {
pub child_part: IdType, pub child_part: IdType,
} }
impl Connection {
/// 真有地方需要
pub fn as_raw_data(&self) -> RawConnectionData {
(
self.parent_attach_point,
self.child_attach_point,
self.parent_part,
self.child_part,
)
}
}
impl SR1PartDataTrait for Part { impl SR1PartDataTrait for Part {
fn to_sr_part_data(&self) -> SR1PartData { fn to_sr_part_data(&self) -> SR1PartData {
let attr = SR1PartDataAttr::from_raw(self, None, true); let attr = SR1PartDataAttr::from_raw(self, None, true);

View File

@ -16,7 +16,7 @@ from Difficult_Rocket.api.types import Options, Version
from lib_not_dr import loggers from lib_not_dr import loggers
DR_rust_version = Version("0.3.3") # DR_mod 的 Rust 编写部分的兼容版本 DR_rust_version = Version("0.3.4") # DR_mod 的 Rust 编写部分的兼容版本
logger = loggers.config.get_logger_from_old("client.dr_game", "client") logger = loggers.config.get_logger_from_old("client.dr_game", "client")

View File

@ -10,10 +10,18 @@ from pyglet.graphics import Batch, Group
from Difficult_Rocket.client import ClientWindow from Difficult_Rocket.client import ClientWindow
from Difficult_Rocket.api.screen import BaseScreen from Difficult_Rocket.api.screen import BaseScreen
from Difficult_Rocket.main import Game from Difficult_Rocket.main import Game
from Difficult_Rocket.gui.widget.button import PressTextButton, MinecraftWikiButtonTheme, ButtonThemeOptions, BaseButtonTheme from Difficult_Rocket.gui.widget.button import (
PressTextButton,
MinecraftWikiButtonTheme,
ButtonThemeOptions,
BaseButtonTheme,
)
from lib_not_dr import loggers
# from . import DR_mod_runtime # from . import DR_mod_runtime
logger = loggers.config.get_logger_from_old("client.dr_game_menu", "client")
class Menu(BaseScreen): class Menu(BaseScreen):
""" """
@ -31,59 +39,59 @@ class Menu(BaseScreen):
# 欸呀, 正好是 911 纪念日哦 # 欸呀, 正好是 911 纪念日哦
# 好, 高二 第一学期 期末都考完了, 我过来做测试了 (20240119) # 好, 高二 第一学期 期末都考完了, 我过来做测试了 (20240119)
self.wiki_button1 = PressTextButton( # self.wiki_button1 = PressTextButton(
x=200, # x=200,
y=300, # y=300,
width=150, # width=150,
height=30, # height=30,
text="wiki button1", # text="wiki button1",
batch=self.main_batch, # batch=self.main_batch,
group=self.main_group, # group=self.main_group,
draw_theme=MinecraftWikiButtonTheme, # draw_theme=MinecraftWikiButtonTheme,
dict_theme={"pop_out": True}, # dict_theme={"pop_out": True},
) # )
self.wiki_button2 = PressTextButton( # self.wiki_button2 = PressTextButton(
x=400, # x=400,
y=300, # y=300,
width=150, # width=150,
height=30, # height=30,
text="wiki button2", # text="wiki button2",
batch=self.main_batch, # batch=self.main_batch,
group=self.main_group, # group=self.main_group,
draw_theme=MinecraftWikiButtonTheme, # draw_theme=MinecraftWikiButtonTheme,
dict_theme={"pop_out": False}, # dict_theme={"pop_out": False},
) # )
self.wiki_button3 = PressTextButton( # self.wiki_button3 = PressTextButton(
x=200, # x=200,
y=250, # y=250,
width=150, # width=150,
height=30, # height=30,
text="wiki button3", # text="wiki button3",
batch=self.main_batch, # batch=self.main_batch,
group=self.main_group, # group=self.main_group,
draw_theme=MinecraftWikiButtonTheme, # draw_theme=MinecraftWikiButtonTheme,
dict_theme={"pop_out": True, "drag_list": True}, # dict_theme={"pop_out": True, "drag_list": True},
) # )
self.wiki_button4 = PressTextButton( # self.wiki_button4 = PressTextButton(
x=400, # x=400,
y=250, # y=250,
width=150, # width=150,
height=30, # height=30,
text="wiki button4", # text="wiki button4",
batch=self.main_batch, # batch=self.main_batch,
group=self.main_group, # group=self.main_group,
draw_theme=MinecraftWikiButtonTheme, # draw_theme=MinecraftWikiButtonTheme,
dict_theme={"pop_out": False, "drag_list": True}, # dict_theme={"pop_out": False, "drag_list": True},
) # )
self.button3 = PressTextButton( # self.button3 = PressTextButton(
x=200, # x=200,
y=200, # y=200,
width=150, # width=150,
height=30, # height=30,
text="imgui button", # text="imgui button",
batch=self.main_batch, # batch=self.main_batch,
group=self.main_group, # group=self.main_group,
) # )
self.enter_ship_editor_button = PressEnterShipEditorButton( self.enter_ship_editor_button = PressEnterShipEditorButton(
window=main_window, window=main_window,
x=100, x=100,
@ -93,17 +101,19 @@ class Menu(BaseScreen):
text="进入编辑器", text="进入编辑器",
batch=self.main_batch, batch=self.main_batch,
group=self.main_group, group=self.main_group,
draw_theme=MinecraftWikiButtonTheme
) )
main_window.push_handlers(self.wiki_button1) # main_window.push_handlers(self.wiki_button1)
main_window.push_handlers(self.wiki_button2) # main_window.push_handlers(self.wiki_button2)
main_window.push_handlers(self.wiki_button3) # main_window.push_handlers(self.wiki_button3)
main_window.push_handlers(self.wiki_button4) # main_window.push_handlers(self.wiki_button4)
main_window.push_handlers(self.button3) # main_window.push_handlers(self.button3)
main_window.push_handlers(self.enter_ship_editor_button) main_window.push_handlers(self.enter_ship_editor_button)
def on_draw(self, dt: float, window: ClientWindow): def on_draw(self, dt: float, window: ClientWindow):
self.main_batch.draw() self.main_batch.draw()
class PressEnterShipEditorButton(PressTextButton): class PressEnterShipEditorButton(PressTextButton):
def __init__( def __init__(
self, self,
@ -117,11 +127,14 @@ class PressEnterShipEditorButton(PressTextButton):
group: Optional[Group] = None, group: Optional[Group] = None,
theme: Optional[ButtonThemeOptions] = None, theme: Optional[ButtonThemeOptions] = None,
draw_theme: Optional[type(BaseButtonTheme)] = None, draw_theme: Optional[type(BaseButtonTheme)] = None,
dict_theme: Optional[dict] = None,): dict_theme: Optional[dict] = None,
super().__init__(x,y,width,height,text,batch,group,theme,draw_theme,dict_theme) ):
self.window=window super().__init__(
x, y, width, height, text, batch, group, theme, draw_theme, dict_theme
#from lib_not_dr import loggers )
self.window = window
def on_mouse_release(self, x, y, buttons, modifiers): def on_mouse_release(self, x, y, buttons, modifiers):
if self.pressed and (x, y) in self: if self.pressed and (x, y) in self:
if self.draw_theme: if self.draw_theme:
@ -129,10 +142,9 @@ class PressEnterShipEditorButton(PressTextButton):
else: else:
self.back_rec.color = self.touched_color self.back_rec.color = self.touched_color
self.pressed = False self.pressed = False
from .sr1_ship import SR1ShipRender from .sr1_ship import SR1ShipRender
self.window.remove_sub_screen("DR_game_menu") self.window.remove_sub_screen("DR_game_menu")
self.window.add_sub_screen("SR1_ship", SR1ShipRender) self.window.add_sub_screen("SR1_ship", SR1ShipRender)
#logger.info("added SR1_ship screen", tag="dr_game") logger.info("added SR1_ship screen", tag="dr_game")

View File

@ -38,6 +38,7 @@ if DR_mod_runtime.use_DR_rust:
SR1Ship_rs, SR1Ship_rs,
SR1PartData_rs, SR1PartData_rs,
SR1PartType_rs, SR1PartType_rs,
# SR1Connection_rs
) )
@ -291,7 +292,7 @@ class SR1ShipRender(BaseScreen):
count = 0 count = 0
yield yield
connect_line_group = Group(7, parent=self.part_group) connect_line_group = Group(7, parent=self.part_group)
for connect in self.rust_ship.connection: for connect in self.rust_ship.connections().get_raw_data:
# 连接线 # 连接线
parent_part_data = cache[connect[2]][0][1] parent_part_data = cache[connect[2]][0][1]
child_part_data = cache[connect[3]][0][1] child_part_data = cache[connect[3]][0][1]
@ -371,7 +372,7 @@ class SR1ShipRender(BaseScreen):
sr_tr() sr_tr()
.sr1.ship.ship.load_time() .sr1.ship.ship.load_time()
.format((time.perf_counter_ns() - start_time) / 1000000000), .format((time.perf_counter_ns() - start_time) / 1000000000),
tag="ship" tag="ship",
) )
logger.info( logger.info(
sr_tr() sr_tr()
@ -538,7 +539,8 @@ class SR1ShipRender(BaseScreen):
for index, sprite in enumerate(sprites): for index, sprite in enumerate(sprites):
sprite_img = sprite.image sprite_img = sprite.image
print( print(
f"sprite_img: {sprite_img} {part_data[part][index][1].x * 60} {part_data[part][index][1].y * 60}" f"sprite_img: {sprite_img} {part_data[part][index][1].x * 60} "
f"{part_data[part][index][1].y * 60}"
) )
img_data = sprite_img.get_image_data() img_data = sprite_img.get_image_data()
fmt = img_data.format fmt = img_data.format