Compare commits

..

3 Commits

Author SHA1 Message Date
InfyniteHeap
dbd4ccd31b
Change a few of details. 2023-12-24 23:59:52 +08:00
InfyniteHeap
d910a428b1
Change both the Chinese Doc and the English Doc. 2023-12-24 22:17:10 +08:00
InfyniteHeap
3224c8fc9f
Adjust file structures and bump version to 0.3.1. 2023-12-24 21:29:04 +08:00
21 changed files with 173 additions and 223 deletions

View File

@ -1,17 +1,13 @@
<div style="text-align: center;">
# Difficult Rocket
中文 | [English](./docs/README-en.md)
- [GitHub](https://github.com/shenjackyuanjie/Difficult-Rocket)
- [gitee](https://gitee.com/shenjackyuanjie/Difficult-Rocket)
- [discord](https://discord.gg/kWzw2JrG6M)
- [kook](https://kook.top/sRPjFG)
- [Gitee](https://gitee.com/shenjackyuanjie/Difficult-Rocket)
- [Discord](https://discord.gg/kWzw2JrG6M)
- [Kook](https://kook.top/sRPjFG)
## 请注意 这个仓库未来只会发布 `DR SDK` 的更新 `DR game` 的更新会在 [这里](https://github.com/shenjackyuanjie/DR-game) 发布
![demo](docs/src/demo.png)
>注意:本仓库未来只会发布`DR SDK`的更新。`DR game`的更新会在[这里](https://github.com/shenjackyuanjie/DR-game)发布。
[![996.icu](https://img.shields.io/badge/996.icu-996.icu-red.svg)](https://996.icu)
[![semver](https://img.shields.io/badge/SemVer-2.0.0-blue.svg)](https://Semver.org/)
@ -33,23 +29,19 @@
[DR rs 最新 Action 构建](https://nightly.link/shenjackyuanjie/Difficult-Rocket/workflows/dr_rs/main)
## English README please look [here](./docs/README-en.md)
## 介绍
> 这是一个用Python制作的类Simple Rocket游戏(简称:火箭模拟器)
这是一个用Python制作的类Simple Rocket游戏简称火箭模拟器。相对于原版SR它更加轻量。
## 优势
> 相对于原版SR比较“轻量化”
## [计划特性列表](docs/src/plan_features/README.md)
[计划特性列表](docs/src/plan_features/README.md)
[YouTrack](https://difficult-rocket.youtrack.cloud/projects/8dafd498-59c0-4ce7-9900-d9292e9ed1f0)
## [更新日志](docs/src/change_log/readme.md)
[更新日志](docs/src/change_log/readme.md)
## 运行方式
## 运行
### clone
### 1. Clone
```bash title="clone.sh"
mkdir DR
@ -61,7 +53,7 @@ git clone https://gitee.com/shenjackyuanjie/Difficult-Rocket.git
git clone git@github.com:shenjackyuanjie/Difficult-Rocket.git
```
### 安装依赖
### 2. 安装依赖
```bash title="install.sh"
python -m pip install -r requirement.txt
@ -71,13 +63,15 @@ python -m pip install ./lib_not_dr
python -m pip install ./pyglet
```
### 运行
### 3. 运行
```bash title="run.sh"
python DR.py
```
## 环境需求 (测试过的 / 开发平台)
## 环境需求
>开发环境使用的Python版本为`3.8.10`,但`3.10.11`同样可用。
- `开发平台 1 - Windows 10 x64 22H2`
- Python `3.8.10` / `3.10.11`
@ -108,7 +102,7 @@ python DR.py
[requirement-build.txt](requirement-build.txt)
[requirement-dev.txt](requirement-dev.txt)
##
##
- 开源项目
- [pyglet](https://github.com/pyglet/pyglet) : GUI 和画面渲染
@ -124,11 +118,11 @@ python DR.py
- [@Billchyi](https://github.com/Billchyi) : 文档矫正
- [@MSDNicrosoft](https://github.com/MSDNicrosoft) : 优化代码
</div>
## 相关链接
## 关于分享协议
>待完善。
## 许可
#### https://creativecommons.org/licenses/by-nc-sa/4.0/

View File

@ -3,13 +3,11 @@
[中文](../README.md) | English
- [GitHub](https://github.com/shenjackyuanjie/Difficult-Rocket)
- [gitee](https://gitee.com/shenjackyuanjie/Difficult-Rocket)
- [discord](https://discord.gg/kWzw2JrG6M)
- [kook](https://kook.top/sRPjFG)
- [Gitee](https://gitee.com/shenjackyuanjie/Difficult-Rocket)
- [Discord](https://discord.gg/kWzw2JrG6M)
- [Kook](https://kook.top/sRPjFG)
## Notice: This repo will only publish `DR SDK` updates, `DR game` updates will be published [here](https://github.com/shenjackyuanjie/DR-game)
![demo](docs/src/demo.png)
>Note: This repo will only publish `DR SDK` updates, `DR game` updates will be published [here](https://github.com/shenjackyuanjie/DR-game).
[![996.icu](https://img.shields.io/badge/996.icu-996.icu-red.svg)](https://996.icu)
[![semver](https://img.shields.io/badge/SemVer-2.0.0-blue.svg)](https://Semver.org/)
@ -31,23 +29,19 @@
[DR rs latest Action build](https://nightly.link/shenjackyuanjie/Difficult-Rocket/workflows/dr_rs/main)
## 中文README请移步 [这里](../README.md)
## Introduction
> Difficult-rocket is a Simple Rocket liked game build with Python (in short: rocket simulator)
Difficult-rocket is a Simple Rocket liked game build with Python (shorten as "rocket simulator"). It is lighter than Vanilla SR.
## Advantage
> Lighter than Vanilla SR
## [Plan feature list](src/plan_features/README.md)
[Plan feature list](src/plan_features/README.md)
[YouTrack](https://difficult-rocket.youtrack.cloud/projects/8dafd498-59c0-4ce7-9900-d9292e9ed1f0)
## [Update logs](src/change_log/readme.md)
[Update logs](src/change_log/readme.md)
## How To Run
## Run
### clone
### 1. Clone
```bash title="clone.sh"
mkdir DR
@ -59,7 +53,7 @@ git clone https://gitee.com/shenjackyuanjie/Difficult-Rocket.git
git clone git@github.com:shenjackyuanjie/Difficult-Rocket.git
```
### Install requirements
### 2. Install requirements
```bash title="install.sh"
python -m pip install -r requirements.txt
@ -69,13 +63,15 @@ python -m pip install ./lib_not_dr
python -m pip install ./pyglet
```
### Run
### 3. Run
```bash title="run.sh"
python DR.py
```
## Environment (been tested / developed on)
## Environment
>The developing environment used Python `3.8.10`, but `3.10.11` is also available.
- `Develop platform 1 - Windows 10 x64 22H2`
- Python `3.8.10` / `3.10.11`
@ -96,7 +92,7 @@ python DR.py
- `AMD R5 5600X`
- `AMD RX 550 4G`
## Required python modules
## Required Python Modules
- `pyglet` (pre-installed V2.0.8 path:`./libs/pyglet`)
- `xmltodict` (pre-installed V0.12.0 path:`./libs/xmltodict`)
@ -106,7 +102,7 @@ python DR.py
[requirement-build.txt](requirement-build.txt)
[requirement-dev.txt](requirement-dev.txt)
## thanks to
## Credits
- Open Source Projects
- [pyglet](https://github.com/pyglet/pyglet): GUI and graphics
@ -122,9 +118,11 @@ python DR.py
- [@Billchyi](https://github.com/Billchyi) : Check mistake in docs
- [@MSDNicrosoft](https://github.com/MSDNicrosoft) : Optimize code
## Other links
## Other Links
## About License
>Pending to be completed.
## License
#### https://creativecommons.org/licenses/by-nc-sa/4.0/

View File

@ -67,9 +67,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crossbeam"
version = "0.8.2"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c"
checksum = "6eb9105919ca8e40d437fc9cbb8f1975d916f1bd28afe795a48aae32a2cc8920"
dependencies = [
"cfg-if",
"crossbeam-channel",
@ -81,9 +81,9 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
version = "0.5.9"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5"
checksum = "82a9b73a36529d9c47029b9fb3a6f0ea3cc916a261195352ba19e770fc1748b2"
dependencies = [
"cfg-if",
"crossbeam-utils",
@ -102,21 +102,20 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.16"
version = "0.9.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa"
checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.9"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9bcf5bdbfdd6030fb4a1c497b5d5fc5921aa2f60d359a17e249c0e6df3de153"
checksum = "adc6598521bb5a83d491e8c1fe51db7296019d2ca3cb93cc6c2a20369a4d78a2"
dependencies = [
"cfg-if",
"crossbeam-utils",
@ -124,9 +123,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
version = "0.8.17"
version = "0.8.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f"
checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c"
dependencies = [
"cfg-if",
]
@ -144,7 +143,7 @@ dependencies = [
[[package]]
name = "difficult_rocket_rs"
version = "0.3.0"
version = "0.3.1"
dependencies = [
"dict_derive",
"fs-err",
@ -381,9 +380,9 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "proc-macro2"
version = "1.0.70"
version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8"
dependencies = [
"unicode-ident",
]
@ -434,7 +433,7 @@ dependencies = [
"proc-macro2",
"pyo3-macros-backend",
"quote",
"syn 2.0.41",
"syn 2.0.42",
]
[[package]]
@ -446,7 +445,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.41",
"syn 2.0.42",
]
[[package]]
@ -548,7 +547,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.41",
"syn 2.0.42",
]
[[package]]
@ -604,9 +603,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.41"
version = "2.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8"
dependencies = [
"proc-macro2",
"quote",
@ -718,20 +717,20 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "zerocopy"
version = "0.7.31"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.31"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.41",
"syn 2.0.42",
]

View File

@ -1,6 +1,6 @@
[package]
name = "difficult_rocket_rs"
version = "0.3.0"
version = "0.3.1"
edition = "2021"
license-file = '../../LICENSE'
authors = ["shenjackyuanjie <3695888@qq.com>"]
@ -14,13 +14,10 @@ crate-type = ["cdylib"]
#[profile.dev.package.rapier2d-f64]
#opt-level = 2
[profile.dev]
opt-level = 0
[profile.release]
lto = "fat"
# Abort panic info to rapidly terminate program instead of unwinding call stacks.
# To check panic info, compile the program in dev mode.
# 舍弃恐慌信息以快速终止程序,而非展开调用栈。
# 请以开发模式编译程序以检查恐慌信息。
panic = "abort"
opt-level = 2
@ -28,9 +25,7 @@ opt-level = 2
fs-err = "2.11.0"
quick-xml = { version = "0.31.0", features = ["serialize"] }
serde = { version = "1.0", features = ["derive"] }
nalgebra = "0.32.3"
rapier2d-f64 = { version = "0.17.2", features = ["simd-stable"] }
pyo3 = { version = "0.20.0", features = ["extension-module", "macros"] }
dict_derive = "0.5"

View File

@ -12,7 +12,7 @@ package_path = "Difficult_Rocket_rs"
setup(
name="Difficult_Rocket_rs",
version="0.3.0",
version="0.3.1",
author="shenjackyuanjie",
author_email="3695888@qq.com",
rust_extensions=[

View File

@ -1,13 +0,0 @@
/*
* -------------------------------
* Difficult Rocket
* Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
* All rights reserved
* -------------------------------
*/
pub mod dr;
pub mod math;
pub mod sr1;
pub type IdType = i64;

View File

@ -0,0 +1,3 @@
pub mod math;
pub mod rigid;
pub mod simulation;

View File

@ -1,6 +1,8 @@
use std::ops::Add;
pub const POINT_D: f64 = 1.0;
pub trait Rotatable {
pub trait Rotate {
// 懒了,直接实现一个协议得了
fn rotate(&self, angle: f64) -> Self;
fn rotate_radius(&self, radius: f64) -> Self;
@ -9,7 +11,7 @@ pub trait Rotatable {
fn rotate_radius_mut(&mut self, radius: f64);
}
#[derive(Clone, Copy)]
#[derive(Default, Clone, Copy)]
pub struct Point2D {
pub x: f64,
pub y: f64,
@ -20,10 +22,6 @@ impl Point2D {
Self { x, y }
}
pub fn new_default() -> Self {
Self { x: 0.0, y: 0.0 }
}
pub fn distance(&self, other: &Point2D) -> f64 {
let dx = (other.x - self.x).powf(2.0);
let dy = (other.y - self.y).powf(2.0);
@ -34,17 +32,13 @@ impl Point2D {
self.distance(&Point2D::new(0.0, 0.0))
}
pub fn add(&self, x: f64, y: f64) -> Self {
Point2D::new(self.x + x, self.y + y)
}
pub fn add_mut(&mut self, x: f64, y: f64) {
self.x += x;
self.y += y;
}
}
impl Rotatable for Point2D {
impl Rotate for Point2D {
fn rotate_radius(&self, radius: f64) -> Self {
let sin = radius.sin();
let cos = radius.cos();
@ -67,6 +61,17 @@ impl Rotatable for Point2D {
}
}
impl Add for Point2D {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
#[derive(Clone, Copy)]
pub struct CircularArc {
// 半径
@ -85,13 +90,14 @@ pub struct OneTimeLine {
// pub b: f64,
// y = kx + b
// kx + b - y = 0
pub start: Point2D,
// start point
pub end: Point2D,
pub start: Point2D,
// end point
pub end: Point2D,
}
impl Rotatable for OneTimeLine {
impl Rotate for OneTimeLine {
fn rotate(&self, angle: f64) -> Self {
self.rotate_radius(angle.to_radians())
}
@ -128,6 +134,7 @@ impl Shape {
let x = x.unwrap_or(0.0);
let y = y.unwrap_or(0.0);
let degree = degree.unwrap_or(0.0);
Self {
pos: Point2D::new(x, y),
degree,
@ -151,10 +158,12 @@ impl Shape {
Edge::OneTimeLine(line) => {
let start = line.start.rotate_radius(radius);
let end = line.end.rotate_radius(radius);
Edge::OneTimeLine(OneTimeLine::point_new(&start, &end))
}
Edge::CircularArc(arc) => {
let pos = arc.pos.rotate_radius(radius);
Edge::CircularArc(CircularArc {
r: arc.r,
pos,
@ -165,8 +174,9 @@ impl Shape {
})
.collect();
}
Self {
pos: Point2D::new_default(),
pos: Default::default(),
degree: 0.0,
bounds: edges,
}

View File

@ -5,12 +5,15 @@ use rapier2d_f64::geometry::TriMeshFlags;
use rapier2d_f64::math::{Point, Real};
use rapier2d_f64::parry::transformation::vhacd::VHACDParameters;
#[derive(Default)]
pub enum ConnectType {
#[default]
Stick,
FixedPoint,
RotatedPoint,
}
#[derive(Default)]
pub struct Connect {
pub c_type: ConnectType,
pub d_pos: f64,
@ -110,7 +113,6 @@ pub struct TankProps {
pub fuel_volume: f64,
/// 空油罐的质量if p_type==tank
pub mass: f64,
// Why the fuel type is an integer?
/// 燃油种类if p_type==tank
pub fuel_type: i32,
}
@ -129,8 +131,8 @@ pub struct EngineProps {
// pub throttle_exponential: f64,
}
// I regard this trait as the useless one at least so far.
// Canceling commenting this trait and deleting this two-line comment when it is truly useful.
// 至少目前而言我认为这个trait没有任何用途。
// 当它真正发挥作用是时再取消对它的注释并删除这两行注释。
// pub trait DRComponentPropAttr<'a, T> {
// fn name() -> &'a str;
@ -151,7 +153,7 @@ pub struct DRComponentProps<'a, T> {
pub name: &'a str,
/// 描述
pub description: &'a str,
// Should this texture be a string instead of file?
// 纹理需要用字符串而非文件句柄来表示吗?
/// 贴图
pub texture: &'a str,
/// pub r#type: SR1PartTypeEnum,

View File

@ -6,18 +6,17 @@
* -------------------------------
*/
mod data_type;
mod plugin_loader;
mod dr_physics;
mod python;
mod simulator;
mod sr1_data;
mod xml_reader;
mod sr1_parse;
use pyo3::prelude::*;
pub type IdType = i64;
#[pyfunction]
fn get_version_str() -> String {
"0.3.0".to_string()
"0.3.1".to_string()
}
#[pyfunction]
@ -31,8 +30,8 @@ fn test_call(py_obj: &PyAny) -> PyResult<bool> {
fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(get_version_str, m)?)?;
m.add_function(wrap_pyfunction!(test_call, m)?)?;
m.add_function(wrap_pyfunction!(sr1_data::part_list::read_part_list_py, m)?)?;
m.add_function(wrap_pyfunction!(sr1_data::ship::py_raw_ship_from_file, m)?)?;
m.add_function(wrap_pyfunction!(sr1_parse::part_list::read_part_list_py, m)?)?;
m.add_function(wrap_pyfunction!(sr1_parse::ship::py_raw_ship_from_file, m)?)?;
m.add_function(wrap_pyfunction!(python::data::load_and_save_test, m)?)?;
m.add_class::<python::data::PySR1Ship>()?;
m.add_class::<python::data::PySR1PartList>()?;

View File

@ -1,22 +0,0 @@
/*
* -------------------------------
* Difficult Rocket
* Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
* All rights reserved
* -------------------------------
*/
// TODO libloading
/// https://docs.rs/libloading/latest/libloading/
/// 插件加载
///
pub struct ModInfo {
pub name: String,
pub version: String,
}
pub trait ModInfoTrait {
fn info() -> ModInfo;
}

View File

@ -1,6 +1,7 @@
use pyo3::prelude::*;
use std::io::{self, Write};
use pyo3::prelude::*;
#[pyclass]
#[pyo3(name = "Console_rs")]
pub struct PyConsole {

View File

@ -3,13 +3,13 @@ use std::collections::HashMap;
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
use crate::data_type::math::{Point2D, Rotatable};
use crate::data_type::sr1::SaveStatus;
use crate::data_type::sr1::{get_max_box, SR1PartData, SR1PartListTrait};
use crate::data_type::sr1::{SR1PartList, SR1PartType, SR1Ship};
use crate::data_type::IdType;
use crate::sr1_data::part_list::RawPartList;
use crate::sr1_data::ship::RawShip;
use crate::dr_physics::math::{Point2D, Rotate};
use crate::sr1_parse::part_list::RawPartList;
use crate::sr1_parse::ship::RawShip;
use crate::sr1_parse::SaveStatus;
use crate::sr1_parse::{get_max_box, SR1PartData, SR1PartListTrait};
use crate::sr1_parse::{SR1PartList, SR1PartType, SR1Ship};
use crate::IdType;
// use serde_xml_rs::to_string;
use quick_xml::se::to_string;

View File

@ -6,12 +6,12 @@
* -------------------------------
*/
use crate::IdType;
use nalgebra::{Matrix2, Vector2};
use pyo3::prelude::*;
use rapier2d_f64::math::Real;
use crate::data_type::IdType;
/// Id 位置 碰撞体
pub type BoundedShape = (IdType, Vector2<Real>, EditorShapeEnum);

View File

@ -1,22 +1,25 @@
use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::fs;
use std::io::Cursor;
use std::ops::Deref;
mod data_structure;
use super::math::{Edge, Shape};
use crate::sr1_data::part_list::Damage as RawDamage;
use crate::sr1_data::part_list::{AttachPoint, AttachPoints, Engine, Lander, Rcs, Shape as RawShape, Solar, Tank};
use crate::sr1_data::part_list::{RawPartList, RawPartType, SR1PartTypeEnum};
use crate::sr1_data::ship::{
pub use self::data_structure::*;
use crate::dr_physics::math::{Edge, Shape};
use crate::dr_physics::math::{Point2D, Rotate};
use crate::sr1_parse::part_list::Damage as RawDamage;
use crate::sr1_parse::part_list::{AttachPoint, AttachPoints, Engine, Lander, Rcs, Shape as RawShape, Solar, Tank};
use crate::sr1_parse::part_list::{RawPartList, RawPartType, SR1PartTypeEnum};
use crate::sr1_parse::ship::{
Activate as RawActivate, Connection, Connections, DisconnectedPart as RawDisconnectedPart,
DisconnectedParts as RawDisconnectedParts, Engine as RawEngine, Part as RawPartData, Parts as RawParts,
Pod as RawPod, RawShip, Staging as RawStaging, Step as RawStep, Tank as RawTank,
};
use crate::IdType;
use crate::data_type::math::{Point2D, Rotatable};
use crate::data_type::IdType;
use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::io::Cursor;
use std::ops::Deref;
use fs_err as fs;
use quick_xml::events::{BytesEnd, BytesStart, Event};
use quick_xml::writer::Writer;
@ -45,11 +48,12 @@ pub enum SR1PartTypeAttr {
consumption: f64,
size: f64,
turn: f64,
fuel_type: i32,
// 我觉得用枚举体表示燃料种类更好。
/// 0 -> 普通燃料
/// 1 -> Rcs
/// 2 -> 电量
/// 3 -> 固推
fuel_type: i32,
throttle_exponential: bool,
},
Rcs {
@ -161,7 +165,6 @@ pub struct SR1PartList {
}
impl SR1PartList {
#[inline]
pub fn new(name: String, types: Vec<SR1PartType>) -> SR1PartList {
SR1PartList {
types,
@ -170,7 +173,6 @@ impl SR1PartList {
}
}
#[inline]
pub fn from_file(file_name: String) -> Option<SR1PartList> {
if let Some(raw_list) = RawPartList::from_file(file_name) {
let sr_list = raw_list.to_sr_part_list(None);
@ -191,7 +193,6 @@ impl SR1PartList {
self.cache.borrow().clone().unwrap()
}
#[inline]
pub fn get_part_type(&self, type_name: &String) -> Option<SR1PartType> {
let cache = self.get_cache();
cache.get(type_name).cloned()
@ -373,12 +374,10 @@ impl SR1PartTypeData for SR1PartType {
}
impl SR1PartDataTrait for SR1PartData {
#[inline]
fn to_sr_part_data(&self) -> SR1PartData {
self.clone()
}
#[inline]
fn to_raw_part_data(&self) -> RawPartData {
let (tank, engine) = if let Some(fuel) = &self.attr.fuel {
match self.part_type {
@ -600,7 +599,6 @@ impl SR1PartDataAttr {
Some(pod.throttle),
Some(pod.stages.current_stage),
Some({
// The mother-fucking nests come out again!
let mut steps = Vec::new();
match &pod.stages.steps {
Some(step_vec) => {
@ -697,7 +695,6 @@ impl SR1Ship {
part.part_type = SR1PartTypeEnum::strut;
}
}
// Why are you fucking nesting such this fucking loops?!
for disconnects in self.disconnected.iter_mut() {
for (parts, _) in disconnects.iter_mut() {
for part in parts.iter_mut() {
@ -967,8 +964,18 @@ pub fn get_max_box(parts: &[SR1PartData], part_list: &SR1PartList) -> (f64, f64,
let mut p2 = Point2D::new(x2, y2);
p1.rotate_radius_mut(part.angle);
p2.rotate_radius_mut(part.angle);
let p1 = p1.add(part.x * 2.0, part.y * 2.0);
let p2 = p2.add(part.x * 2.0, part.y * 2.0);
// let p1 = p1.add(part.x * 2.0, part.y * 2.0);
// let p2 = p2.add(part.x * 2.0, part.y * 2.0);
let p1 = p1
+ Point2D {
x: part.x * 2.0,
y: part.y * 2.0,
};
let p2 = p2
+ Point2D {
x: part.x * 2.0,
y: part.y * 2.0,
};
let (x1, y1, x2, y2) = (p1.x, p1.y, p2.x, p2.y);
// get max box
max_box.0 = max_box.0.min(x1).min(part.x);

View File

@ -1,10 +1,10 @@
use crate::data_type::sr1::{SR1PartList, SR1PartType, SR1PartTypeAttr};
use crate::data_type::sr1::{SR1PartListTrait, SR1PartTypeData};
use crate::sr1_parse::{SR1PartList, SR1PartType, SR1PartTypeAttr};
use crate::sr1_parse::{SR1PartListTrait, SR1PartTypeData};
use fs_err as fs;
use pyo3::prelude::*;
use serde::{Deserialize, Serialize};
use quick_xml::de::from_str;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RawPartList {
@ -138,8 +138,8 @@ pub struct Damage {
}
impl Damage {
pub fn take_damage(&self) -> crate::data_type::sr1::Damage {
crate::data_type::sr1::Damage {
pub fn take_damage(&self) -> crate::sr1_parse::Damage {
crate::sr1_parse::Damage {
disconnect: self.disconnect,
explode: self.explode,
explosion_power: self.explosion_power.unwrap_or(100_f64),
@ -371,8 +371,8 @@ impl RawPartList {
}
pub fn from_file(file_name: String) -> Option<RawPartList> {
let part_list_file = fs::read_to_string(file_name).unwrap();
let part_list: RawPartList = from_str(part_list_file.as_str()).unwrap();
let part_list_file = fs::read_to_string(file_name).ok()?;
let part_list: RawPartList = from_str(part_list_file.as_str()).ok()?;
Some(part_list)
}

View File

@ -1,15 +1,14 @@
use std::fs;
use crate::sr1_parse::{SR1PartData, SR1PartDataAttr, SR1Ship};
use crate::sr1_parse::{SR1PartDataTrait, SR1ShipTrait};
use crate::IdType;
use fs_err as fs;
use pyo3::prelude::*;
use quick_xml::de::from_str;
use quick_xml::se::to_string;
// use quick_xml::Error as XmlError;
use serde::{Deserialize, Serialize};
use crate::data_type::sr1::{SR1PartData, SR1PartDataAttr, SR1Ship};
use crate::data_type::sr1::{SR1PartDataTrait, SR1ShipTrait};
use crate::data_type::IdType;
/// https://docs.rs/quick-xml/latest/quick_xml/de/index.html#basics
/// using quick xml
#[derive(Debug, Serialize, Deserialize, Clone)]
@ -175,11 +174,11 @@ impl SR1PartDataTrait for Part {
let part_type = attr.get_part_type();
SR1PartData {
attr,
x: self.x.to_owned(),
y: self.y.to_owned(),
id: self.id.to_owned(),
angle: self.angle.to_owned(),
angle_v: self.angle_v.to_owned(),
x: self.x,
y: self.y,
id: self.id,
angle: self.angle,
angle_v: self.angle_v,
flip_x: self.flip_x.unwrap_or(0_i8) != 0,
flip_y: self.flip_y.unwrap_or(0_i8) != 0,
editor_angle: self.editor_angle.unwrap_or(0_i32),
@ -196,7 +195,6 @@ impl SR1PartDataTrait for Part {
}
impl SR1ShipTrait for RawShip {
#[inline]
fn to_sr_ship(&self, name: Option<String>) -> SR1Ship {
let mut parts = Vec::new();
for part in &self.parts.parts {
@ -235,14 +233,12 @@ impl SR1ShipTrait for RawShip {
}
}
#[inline]
fn to_raw_ship(&self) -> RawShip {
self.clone()
}
}
impl RawShip {
#[inline]
pub fn from_file(path: String) -> Option<RawShip> {
let ship_file = fs::read_to_string(path); // for encoding error
if let Err(e) = ship_file {
@ -267,16 +263,15 @@ impl RawShip {
}
}
#[inline]
pub fn save(&self, file_name: String) -> Option<()> {
let part_list_file = to_string(self);
pub fn save(&self, file_name: String) -> Result<(), quick_xml::DeError> {
let part_list_file = to_string(self)?;
print!("{:?}", part_list_file);
if let Ok(part_list_file) = part_list_file {
fs::write(file_name, part_list_file).unwrap();
Some(())
} else {
None
match fs::write(file_name, part_list_file) {
Ok(()) => (),
Err(_) => return Err(quick_xml::DeError::Custom("Failed to save file!".to_string())),
}
Ok(())
}
}
@ -284,7 +279,7 @@ impl RawShip {
#[pyo3(name = "read_ship_test")]
#[pyo3(signature = (path = "./assets/builtin/dock1.xml".to_string()))]
pub fn py_raw_ship_from_file(path: String) -> PyResult<bool> {
let file = fs::read_to_string(path).unwrap();
let file = fs::read_to_string(path)?;
let raw_ship = from_str::<RawShip>(&file);
match raw_ship {
Ok(ship) => {

View File

@ -1,18 +0,0 @@
use std::io;
use fs_err as fs;
// Input the directory of the xml file.
// If file does not exsit or not the XML file, return errors or return file handle.
// I think this fuction can be improved as its implementations are not as good as what I expected.
pub fn read_xml(dir: &str) -> io::Result<fs::File> {
if dir.split_inclusive('.').collect::<Vec<&str>>()[1] != "xml" {
Err(io::Error::new(io::ErrorKind::Other, "This file is not an XML file!"))
} else {
fs::File::open(dir)
}
}
pub fn parse_xml(xml_file: fs::File) {
todo!()
}