Compare commits
4
Commits
b0954d25fb
..
ui_fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e06cbb4b7 | ||
|
|
9a3a1383ff | ||
|
|
1ba29b817b | ||
|
|
2874d496ee |
+75
-2
@@ -15,6 +15,27 @@ jobs:
|
||||
- name: Check out source
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Lore CLI
|
||||
run: |
|
||||
scripts/install-lore.sh "$RUNNER_TEMP/lore-bin"
|
||||
echo "$RUNNER_TEMP/lore-bin" >> "$GITHUB_PATH"
|
||||
|
||||
- name: Select Lore asset branch
|
||||
run: |
|
||||
branch=main
|
||||
if [[ "$GITHUB_EVENT_NAME" == pull_request ]]; then
|
||||
branch="$(python3 -c 'import json, os; e=json.load(open(os.environ["GITHUB_EVENT_PATH"], encoding="utf-8")); p=e["pull_request"]; print(p["head"]["ref"] if p["head"]["repo"]["full_name"] == os.environ["GITHUB_REPOSITORY"] else "main")')"
|
||||
fi
|
||||
echo "LORE_BRANCH=$branch" >> "$GITHUB_ENV"
|
||||
echo "Using Lore branch: $branch"
|
||||
|
||||
- name: Fetch assets from Lore
|
||||
env:
|
||||
LORE_CI_USERNAME: ${{ secrets.LORE_CI_USERNAME }}
|
||||
LORE_CI_PASSWORD: ${{ secrets.LORE_CI_PASSWORD }}
|
||||
LORE_AUTH_URL: https://auth.eirexe.moe
|
||||
run: scripts/update-assets.sh "$LORE_BRANCH"
|
||||
|
||||
- name: Install Rust toolchain
|
||||
run: |
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
|
||||
@@ -42,7 +63,6 @@ jobs:
|
||||
libxkbcommon-dev \
|
||||
libxkbcommon-x11-0 \
|
||||
mesa-vulkan-drivers \
|
||||
blender \
|
||||
mold \
|
||||
pkg-config
|
||||
|
||||
@@ -59,6 +79,27 @@ jobs:
|
||||
- name: Check out source
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Lore CLI
|
||||
run: |
|
||||
scripts/install-lore.sh "$RUNNER_TEMP/lore-bin"
|
||||
echo "$RUNNER_TEMP/lore-bin" >> "$GITHUB_PATH"
|
||||
|
||||
- name: Select Lore asset branch
|
||||
run: |
|
||||
branch=main
|
||||
if [[ "$GITHUB_EVENT_NAME" == pull_request ]]; then
|
||||
branch="$(python3 -c 'import json, os; e=json.load(open(os.environ["GITHUB_EVENT_PATH"], encoding="utf-8")); p=e["pull_request"]; print(p["head"]["ref"] if p["head"]["repo"]["full_name"] == os.environ["GITHUB_REPOSITORY"] else "main")')"
|
||||
fi
|
||||
echo "LORE_BRANCH=$branch" >> "$GITHUB_ENV"
|
||||
echo "Using Lore branch: $branch"
|
||||
|
||||
- name: Fetch assets from Lore
|
||||
env:
|
||||
LORE_CI_USERNAME: ${{ secrets.LORE_CI_USERNAME }}
|
||||
LORE_CI_PASSWORD: ${{ secrets.LORE_CI_PASSWORD }}
|
||||
LORE_AUTH_URL: https://auth.eirexe.moe
|
||||
run: scripts/update-assets.sh "$LORE_BRANCH"
|
||||
|
||||
- name: Install Rust toolchain
|
||||
run: |
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
|
||||
@@ -88,22 +129,54 @@ jobs:
|
||||
libusb-1.0-0-dev \
|
||||
libwayland-dev \
|
||||
libx11-dev \
|
||||
libxfixes3 \
|
||||
libxi6 \
|
||||
libxkbcommon-dev \
|
||||
libxkbcommon-x11-0 \
|
||||
blender \
|
||||
lld-19 \
|
||||
llvm-19 \
|
||||
mesa-vulkan-drivers \
|
||||
mold \
|
||||
blender \
|
||||
pkg-config
|
||||
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-19 100
|
||||
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-19 100
|
||||
echo "/usr/lib/llvm-19/bin" >> "$GITHUB_PATH"
|
||||
rm -f "$HOME/.cache/cargo-xwin/clang-cl"
|
||||
|
||||
- name: Install pinned Blender
|
||||
run: |
|
||||
scripts/install-blender.sh "$RUNNER_TEMP/blender"
|
||||
echo "BLENDER=$RUNNER_TEMP/blender/blender" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Preprocess assets
|
||||
run: cargo run --locked --bin process-assets --no-default-features --features debug_features -j 4
|
||||
|
||||
- name: Verify processed battlefield asset
|
||||
run: |
|
||||
python3 - <<'PY'
|
||||
import json
|
||||
import struct
|
||||
|
||||
path = "imported_assets/Default/stages/battlefield/bf2.blend"
|
||||
with open(path, "rb") as asset:
|
||||
header = asset.read(12)
|
||||
if len(header) != 12:
|
||||
raise SystemExit(f"processed asset is truncated: {path}")
|
||||
magic, version, length = struct.unpack("<4sII", header)
|
||||
if magic != b"glTF" or version != 2 or length != asset.seek(0, 2):
|
||||
raise SystemExit(f"processed asset is not a valid GLB: {path}")
|
||||
asset.seek(12)
|
||||
json_length, chunk_type = struct.unpack("<II", asset.read(8))
|
||||
if chunk_type != 0x4E4F534A:
|
||||
raise SystemExit(f"processed asset has no JSON chunk: {path}")
|
||||
document = json.loads(asset.read(json_length))
|
||||
meshes = document.get("meshes", [])
|
||||
if not meshes:
|
||||
raise SystemExit(f"processed asset contains no meshes: {path}")
|
||||
print(f"{path}: {len(meshes)} meshes, {length} bytes")
|
||||
PY
|
||||
|
||||
- name: Build production binary
|
||||
run: cargo build --locked --profile production --no-default-features --features debug_features -j 4
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/target
|
||||
/.jackdaw
|
||||
imported_assets
|
||||
/assets/
|
||||
|
||||
# Local editor configuration
|
||||
**/.vscode/
|
||||
|
||||
@@ -31,3 +31,20 @@ cargo run --locked \
|
||||
cargo build --locked \
|
||||
--profile production --no-default-features --features debug_features
|
||||
```
|
||||
|
||||
## Assets
|
||||
|
||||
Game assets are managed in Lore rather than Git. Install the Lore CLI, then
|
||||
bootstrap or update the local checkout with:
|
||||
|
||||
```sh
|
||||
scripts/install-lore.sh
|
||||
scripts/update-assets.sh
|
||||
```
|
||||
|
||||
The default Lore branch is `main`; pass another branch explicitly when testing
|
||||
coordinated code and asset changes:
|
||||
|
||||
```sh
|
||||
scripts/update-assets.sh my-feature-branch
|
||||
```
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 31 KiB |
@@ -1,12 +0,0 @@
|
||||
frame(4);
|
||||
hitbox(0,
|
||||
"hand_l",
|
||||
damage("5.0"),
|
||||
vec3("0.0", "0.0", "0.0"),
|
||||
fg32("5.0"),
|
||||
angle_sakurai(),
|
||||
knockback_normal(),
|
||||
knockback("10.0"),
|
||||
fg32("1.0")
|
||||
);
|
||||
frame(8);
|
||||
@@ -1,12 +0,0 @@
|
||||
frame(3);
|
||||
hitbox(0,
|
||||
"hand_l",
|
||||
damage("5.0"),
|
||||
vec3("0.0", "0.0", "0.0"),
|
||||
fg32("5.0"),
|
||||
angle(fg32("45.0")),
|
||||
knockback_normal(),
|
||||
knockback("18.0"),
|
||||
fg32("140.0")
|
||||
);
|
||||
frame(8);
|
||||
@@ -1,13 +0,0 @@
|
||||
frame(9);
|
||||
hitbox(0,
|
||||
"hand_l",
|
||||
damage("5.0"),
|
||||
vec3("1.0", "0.0", "0.0"),
|
||||
fg32("7.0"),
|
||||
angle_sakurai(),
|
||||
knockback_normal(),
|
||||
knockback("10.0"),
|
||||
fg32("1.0")
|
||||
);
|
||||
|
||||
frame(15);
|
||||
Binary file not shown.
@@ -1,219 +0,0 @@
|
||||
(
|
||||
id: TestFighter,
|
||||
model_path: "fighters/test/test.blend",
|
||||
model_scale: "10.0",
|
||||
baked_animation_path: "fighters/test/test.fighterbake",
|
||||
icon: (
|
||||
path: "fighters/test/icon.png",
|
||||
),
|
||||
attributes: (
|
||||
base_walk_accel: "0.1",
|
||||
stick_walk_accel: "0.16",
|
||||
max_walk_vel: "1.0",
|
||||
ground_friction: "0.1",
|
||||
dash_acceleration_duration: 13,
|
||||
dash_duration: 24,
|
||||
base_dash_accel: "0.1",
|
||||
stick_dash_accel: "0.05",
|
||||
max_dash_vel: "2.0",
|
||||
short_hop_vertical_velocity: "1.45",
|
||||
full_jump_vertical_velocity: "2.0",
|
||||
jump_horizontal_velocity: "0.6",
|
||||
air_jump_horizontal_velocity: "0.96",
|
||||
air_jump_multiplier: "1.0",
|
||||
dash_initial_velocity: "1.4",
|
||||
terminal_velocity: "3.0",
|
||||
fast_fall_speed: "3.5",
|
||||
gravity: "0.084",
|
||||
weight: "100.0",
|
||||
jumpsquat_duration: 5,
|
||||
landing_iasa: 4,
|
||||
landing_duration: 30,
|
||||
|
||||
max_air_horizontal_velocity: "2.5",
|
||||
air_drift_max: "1.0",
|
||||
air_acceleration_base: "0.03",
|
||||
air_acceleration_stick: "0.01",
|
||||
air_friction: "0.01",
|
||||
|
||||
air_dodge_duration: 49,
|
||||
air_dodge_velocity: "2.790",
|
||||
air_dodge_decay: "0.9",
|
||||
ecb_vertical_midpoint_offset: "0.0"
|
||||
),
|
||||
camera: (
|
||||
vertical_origin_offset: "8.0",
|
||||
forward_extent: "25.5",
|
||||
backward_extent: "8.5",
|
||||
upward_extent: "15.0",
|
||||
downward_extent: "5.0",
|
||||
visibility_radius: "5.0",
|
||||
),
|
||||
animations: {
|
||||
Wait: "Idle_Loop_Game",
|
||||
Walk: "Walk_Loop_IK_Game",
|
||||
Run: "Run_Game",
|
||||
Dash: "Dash_Game",
|
||||
JumpSquat: "Jump_Squat_Game",
|
||||
JumpForward: "Jump_Start_IK_Game",
|
||||
JumpBack: "JumpB_Game",
|
||||
LandingSpecial: "SpecialLand_Game",
|
||||
Landing: "Jump_Land_Game",
|
||||
AirDodge: "Idle_Loop_Game",
|
||||
DoubleJumpForward: "Jump_Start_IK_Game",
|
||||
DoubleJumpBack: "JumpB_Game",
|
||||
Fall: "Fall_Loop_Game",
|
||||
Turn: "Turn_Game",
|
||||
|
||||
FlinchGround: "Air_Hit_Game",
|
||||
FlinchAir: "Air_Hit_Game",
|
||||
|
||||
AttackJab1: "Punch_Jab_Game",
|
||||
AttackUpTilt: "Idle_Loop_Game",
|
||||
AttackForwardTilt: "Idle_Loop_Game",
|
||||
AttackDownTilt: "Idle_Loop_Game"
|
||||
},
|
||||
attack_scripts: {
|
||||
NeutralAir: "fighters/test/scripts/fair.attack.rhai",
|
||||
Jab: "fighters/test/scripts/jab.attack.rhai",
|
||||
UpTilt: "fighters/test/scripts/uptilt.attack.rhai",
|
||||
ForwardTilt: "fighters/test/scripts/uptilt.attack.rhai",
|
||||
DownTilt: "fighters/test/scripts/uptilt.attack.rhai",
|
||||
},
|
||||
hurtboxes: [
|
||||
// center one
|
||||
(
|
||||
bone: "spine_01",
|
||||
offset: (x: "0.0", y: "0.0", z: "0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.05",
|
||||
radius: "0.15"
|
||||
),
|
||||
(
|
||||
bone: "spine_03",
|
||||
offset: (x: "0.0", y: "0.0", z: "0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.05",
|
||||
radius: "0.15"
|
||||
),
|
||||
(
|
||||
bone: "Head",
|
||||
offset: (x: "0.0", y: "0.125", z: "0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.05",
|
||||
radius: "0.1"
|
||||
),
|
||||
(
|
||||
bone: "thigh_r",
|
||||
offset: (x: "0.0", y: "0.15", z: "-0.01"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.2",
|
||||
radius: "0.07"
|
||||
),
|
||||
(
|
||||
bone: "thigh_l",
|
||||
offset: (x: "0.0", y: "0.15", z: "-0.01"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.2",
|
||||
radius: "0.07"
|
||||
),
|
||||
(
|
||||
bone: "calf_l",
|
||||
offset: (x: "0.0", y: "0.15", z: "-0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.2",
|
||||
radius: "0.05"
|
||||
),
|
||||
(
|
||||
bone: "calf_r",
|
||||
offset: (x: "0.0", y: "0.15", z: "-0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.2",
|
||||
radius: "0.05"
|
||||
),
|
||||
(
|
||||
bone: "foot_r",
|
||||
offset: (x: "0.0", y: "0.1", z: "0.01"),
|
||||
rotation: FGVec3(x: "-25.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.1",
|
||||
radius: "0.04"
|
||||
),
|
||||
(
|
||||
bone: "foot_l",
|
||||
offset: (x: "0.0", y: "0.1", z: "0.01"),
|
||||
rotation: FGVec3(x: "-25.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.1",
|
||||
radius: "0.04"
|
||||
),
|
||||
(
|
||||
bone: "upperarm_l",
|
||||
offset: (x: "0.0", y: "0.09", z: "-0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.125",
|
||||
radius: "0.05"
|
||||
),
|
||||
(
|
||||
bone: "lowerarm_l",
|
||||
offset: (x: "0.0", y: "0.12", z: "-0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.115",
|
||||
radius: "0.04"
|
||||
),
|
||||
(
|
||||
bone: "hand_l",
|
||||
offset: (x: "0.0", y: "0.05", z: "-0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.01",
|
||||
radius: "0.04"
|
||||
),
|
||||
(
|
||||
bone: "upperarm_r",
|
||||
offset: (x: "0.0", y: "0.09", z: "-0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.125",
|
||||
radius: "0.05"
|
||||
),
|
||||
(
|
||||
bone: "lowerarm_r",
|
||||
offset: (x: "0.0", y: "0.12", z: "-0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.115",
|
||||
radius: "0.04"
|
||||
),
|
||||
(
|
||||
bone: "hand_r",
|
||||
offset: (x: "0.0", y: "0.05", z: "-0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "0.0"),
|
||||
half_length: "0.01",
|
||||
radius: "0.04"
|
||||
),
|
||||
/*(
|
||||
bone: "RFootJA",
|
||||
offset: (x: "0.0", y: "0.5", z: "0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "90.0"),
|
||||
half_length: "0.5",
|
||||
radius: "1.0"
|
||||
),
|
||||
(
|
||||
bone: "JOBJ_47",
|
||||
offset: (x: "0.0", y: "0.0", z: "0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "90.0"),
|
||||
half_length: "0.5",
|
||||
radius: "1.0"
|
||||
),
|
||||
(
|
||||
bone: "LFootJA",
|
||||
offset: (x: "0.0", y: "0.5", z: "0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "90.0"),
|
||||
half_length: "0.5",
|
||||
radius: "1.0"
|
||||
),
|
||||
(
|
||||
bone: "JOBJ_41",
|
||||
offset: (x: "0.0", y: "0.0", z: "0.0"),
|
||||
rotation: FGVec3(x: "0.0", y: "0.0", z: "90.0"),
|
||||
half_length: "0.5",
|
||||
radius: "1.0"
|
||||
),*/
|
||||
]
|
||||
)
|
||||
@@ -1,3 +0,0 @@
|
||||
(
|
||||
manifest_path: "fighters/test/test.fighter.ron",
|
||||
)
|
||||
Binary file not shown.
@@ -1,128 +0,0 @@
|
||||
(
|
||||
cursor: (
|
||||
path: "ui/textures/cursor.png",
|
||||
sampling: Nearest
|
||||
),
|
||||
css_token: (
|
||||
path: "ui/textures/fighter_select_token.png",
|
||||
sampling: Linear
|
||||
),
|
||||
player_colors: [
|
||||
Srgba((red: 0.780, green: 0.420, blue: 0.933, alpha: 1.000)),
|
||||
Srgba((red: 0.843, green: 0.227, blue: 0.204, alpha: 1.000)),
|
||||
Srgba((red: 0.333, green: 0.804, blue: 0.078, alpha: 1.000)),
|
||||
Srgba((red: 0.075, green: 0.376, blue: 0.416, alpha: 1.000)),
|
||||
Srgba((red: 0.682, green: 0.878, blue: 0.914, alpha: 1.000))
|
||||
],
|
||||
button_styles: {
|
||||
MainMenu: (
|
||||
focus_outline_width_px: 4,
|
||||
focus_outline_offset_px: 2,
|
||||
focus_outline_color: Srgba((red: 1.0, green: 1.0, blue: 0.0, alpha: 1.0)),
|
||||
normal: (
|
||||
background_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
border_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
box_shadow: (),
|
||||
),
|
||||
press: (
|
||||
background_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
border_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
box_shadow: (),
|
||||
),
|
||||
hover: (
|
||||
background_color: Srgba((red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0)),
|
||||
border_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
box_shadow: (),
|
||||
)
|
||||
),
|
||||
CharacterSelectCharacter: (
|
||||
focus_outline_width_px: 10,
|
||||
focus_outline_offset_px: 5,
|
||||
focus_outline_color: Srgba((red: 1.0, green: 1.0, blue: 0.0, alpha: 1.0)),
|
||||
normal: (
|
||||
background_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
box_shadow: (),
|
||||
border_size: 10,
|
||||
),
|
||||
press: (
|
||||
background_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
box_shadow: (),
|
||||
),
|
||||
hover: (
|
||||
background_color: Srgba((red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0)),
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
box_shadow: (),
|
||||
)
|
||||
),
|
||||
CharacterSelectStartBanner: (
|
||||
focus_outline_width_px: 10,
|
||||
focus_outline_offset_px: 5,
|
||||
focus_outline_color: Srgba((red: 1.0, green: 1.0, blue: 0.0, alpha: 1.0)),
|
||||
normal: (
|
||||
background_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
box_shadow: (),
|
||||
),
|
||||
press: (
|
||||
background_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
box_shadow: (),
|
||||
),
|
||||
hover: (
|
||||
background_color: Srgba((red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0)),
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
box_shadow: (),
|
||||
)
|
||||
),
|
||||
StageSelectIcon: (
|
||||
focus_outline_width_px: 4,
|
||||
focus_outline_offset_px: 2,
|
||||
focus_outline_color: Srgba((red: 1.0, green: 1.0, blue: 0.0, alpha: 1.0)),
|
||||
normal: (
|
||||
border_color: Srgba((red: 1.0, green: 1.0, blue: 0.0, alpha: 1.0)),
|
||||
background_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 0.0)),
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
border_size: 10,
|
||||
border_radius: 40.0,
|
||||
box_shadow: (
|
||||
spread_radius: 5.0,
|
||||
blur_radius: 5.0,
|
||||
offset_px_y: 10,
|
||||
offset_px_x: 10,
|
||||
color: Srgba((red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0))
|
||||
),
|
||||
),
|
||||
press: (
|
||||
background_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
border_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
border_radius: 40.0,
|
||||
border_size: 10,
|
||||
box_shadow: (
|
||||
spread_radius: 5.0,
|
||||
offset_px_y: 10,
|
||||
offset_px_x: 10,
|
||||
color: Srgba((red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0))
|
||||
),
|
||||
),
|
||||
hover: (
|
||||
background_color: Srgba((red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0)),
|
||||
border_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
border_radius: 40.0,
|
||||
border_size: 10,
|
||||
text_color: Srgba((red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)),
|
||||
box_shadow: (
|
||||
spread_radius: 5.0,
|
||||
offset_px_y: 10,
|
||||
offset_px_x: 10,
|
||||
color: Srgba((red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0))
|
||||
),
|
||||
)
|
||||
),
|
||||
}
|
||||
)
|
||||
@@ -1,36 +0,0 @@
|
||||
(
|
||||
input_common: (
|
||||
stick_deadzone: "0.275",
|
||||
trigger_deadzone: "0.3",
|
||||
smash_input_reset_axis_threshold: "0.25",
|
||||
smash_input_axis_threshold: "0.8",
|
||||
run_stick_threshold: "0.625",
|
||||
smash_input_frame_threshold: 3,
|
||||
input_buffer_size: 3,
|
||||
turn_into_dashback_window: 2,
|
||||
),
|
||||
fighter_common: (
|
||||
walk_speed_ease: "0.5",
|
||||
ground_max_horizontal_velocity: "3.0",
|
||||
ground_friction_over_walk_speed_multiplier: "2.0",
|
||||
knockback_stacking_window: 2,
|
||||
knockback_decay_per_frame: "0.051",
|
||||
knockback_launch_velocity_multiplier: "0.03",
|
||||
hitstun_frames_per_unit_knockback: "0.4",
|
||||
tumble_bounce_hitstop_threshold: 32,
|
||||
attack_ground_to_airborne_transition_vertical_angle_threshold: "90.0",
|
||||
meteor_angle_threshold: "10.0",
|
||||
visual_shake_frames_per_hitstop_frame: "1.2",
|
||||
visual_shake_table: [
|
||||
-3.0, -1.5, 1.5, 3.0
|
||||
],
|
||||
attacker_visual_shake_multiplier: 0.4,
|
||||
di_max_angle: "18.0"
|
||||
),
|
||||
stage_manifest_paths: [
|
||||
"stages/battlefield/test.stage.ron"
|
||||
],
|
||||
fighter_manifest_paths: [
|
||||
"fighters/test/test.fighter.ron"
|
||||
]
|
||||
)
|
||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 42 KiB |
@@ -1,139 +0,0 @@
|
||||
(
|
||||
id: TestStage,
|
||||
model_path: "stages/battlefield/bf2.blend#Scene0",
|
||||
icon: (
|
||||
path: "stages/battlefield/icon.png"
|
||||
),
|
||||
|
||||
// Battlefield
|
||||
/*camera: (
|
||||
left: -200.0,
|
||||
right: 200.0,
|
||||
bottom: -59.0,
|
||||
top: 170.0,
|
||||
origin: (0.0, 44.0),
|
||||
vertical_fov_degrees: 30.0,
|
||||
min_depth: 83.0,
|
||||
max_depth: 1000.0,
|
||||
subject_scale: 1.5,
|
||||
fighter_forward_extent_scale: 1.5,
|
||||
tracking_smoothness: 1.8,
|
||||
vertical_pan_degrees: -10.0,
|
||||
horizontal_pan_degrees_per_unit: 0.1,
|
||||
vertical_pan_degrees_per_unit: 0.1,
|
||||
max_horizontal_pan_degrees: 17.5,
|
||||
max_upward_pan_degrees: 5.0,
|
||||
max_downward_pan_degrees: 7.0,
|
||||
),*/
|
||||
// Yoshi's story
|
||||
|
||||
/*camera: (
|
||||
left: -180.0,
|
||||
right: 179.0,
|
||||
bottom: -71.0,
|
||||
top: 169.0,
|
||||
origin: (0.0, 44.0),
|
||||
vertical_fov_degrees: 20.0,
|
||||
min_depth: 100.0,
|
||||
max_depth: 1000.0,
|
||||
subject_scale: 1.0,
|
||||
fighter_forward_extent_scale: 1.0,
|
||||
tracking_smoothness: 1.0,
|
||||
vertical_pan_degrees: -10.0,
|
||||
horizontal_pan_degrees_per_unit: 0.05,
|
||||
vertical_pan_degrees_per_unit: 0.15,
|
||||
max_horizontal_pan_degrees: 17.5,
|
||||
max_upward_pan_degrees: 5.0,
|
||||
max_downward_pan_degrees: 7.0,
|
||||
),*/
|
||||
|
||||
camera: (
|
||||
left: -180.0,
|
||||
right: 179.0,
|
||||
bottom: -71.0,
|
||||
top: 169.0,
|
||||
origin: (0.0, 44.0),
|
||||
vertical_fov_degrees: 20.0,
|
||||
min_depth: 100.0,
|
||||
max_depth: 1000.0,
|
||||
subject_scale: 1.5,
|
||||
fighter_forward_extent_scale: 1.0,
|
||||
tracking_smoothness: 1.0,
|
||||
vertical_pan_degrees: -10.0,
|
||||
horizontal_pan_degrees_per_unit: 0.05,
|
||||
vertical_pan_degrees_per_unit: 0.15,
|
||||
max_horizontal_pan_degrees: 17.5,
|
||||
max_upward_pan_degrees: 5.0,
|
||||
max_downward_pan_degrees: 7.0,
|
||||
),
|
||||
polygons: [
|
||||
(
|
||||
poly_type: Platform,
|
||||
lines: [
|
||||
(
|
||||
(x: "-20.0", y: "47.0"),
|
||||
Floor
|
||||
),
|
||||
(
|
||||
(x: "20.0", y: "47.0"),
|
||||
Floor
|
||||
)
|
||||
]
|
||||
),
|
||||
(
|
||||
poly_type: Platform,
|
||||
lines: [
|
||||
(
|
||||
(x: "-65.0", y: "24.0"),
|
||||
Floor
|
||||
),
|
||||
(
|
||||
(x: "-25.0", y: "24.0"),
|
||||
Floor
|
||||
)
|
||||
]
|
||||
),
|
||||
(
|
||||
poly_type: Platform,
|
||||
lines: [
|
||||
(
|
||||
(x: "25.0", y: "24.0"),
|
||||
Floor
|
||||
),
|
||||
(
|
||||
(x: "65.0", y: "24.0"),
|
||||
Floor
|
||||
)
|
||||
]
|
||||
),
|
||||
(
|
||||
poly_type: Closed,
|
||||
lines: [
|
||||
(
|
||||
(x: "-68.0", y: "-3.0"),
|
||||
Wall
|
||||
),
|
||||
(
|
||||
(x: "-68.0", y: "0.0"),
|
||||
Floor,
|
||||
),
|
||||
(
|
||||
(x: "0.0", y: "0.0"),
|
||||
Floor
|
||||
),
|
||||
(
|
||||
(x: "68", y: "0.0"),
|
||||
Wall
|
||||
),
|
||||
(
|
||||
(x: "68.0", y: "-3.0"),
|
||||
Ceiling
|
||||
),
|
||||
(
|
||||
(x: "0.0", y: "-15.0"),
|
||||
Ceiling
|
||||
),
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 871 B |
Binary file not shown.
|
Before Width: | Height: | Size: 5.8 KiB |
@@ -1,77 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 33.866666 33.866666"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
|
||||
sodipodi:docname="cursor.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="5.6568542"
|
||||
inkscape:cx="8.6620581"
|
||||
inkscape:cy="67.086756"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1006"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1">
|
||||
<linearGradient
|
||||
id="linearGradient1"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#949494;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop1" />
|
||||
<stop
|
||||
style="stop-color:#6c6c6c;stop-opacity:1;"
|
||||
offset="0.77473962"
|
||||
id="stop3" />
|
||||
<stop
|
||||
style="stop-color:#9f9f9f;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop2" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1"
|
||||
id="radialGradient2"
|
||||
cx="16.933332"
|
||||
cy="16.933332"
|
||||
fx="16.933332"
|
||||
fy="16.933332"
|
||||
r="12.733072"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2093771,0,0,1.2093771,-3.5454518,-3.5454518)" />
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Capa 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<circle
|
||||
style="fill:url(#radialGradient2);stroke-width:0.319981"
|
||||
id="path1"
|
||||
cx="16.933332"
|
||||
cy="16.933332"
|
||||
r="15.399086" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
version="5.2.2"
|
||||
sha256="84098912789dc450e95697c4184fb8a90acbe5111c2ba4aede3fecb57806a168"
|
||||
install_dir="${1:-${BLENDER_INSTALL_DIR:-${HOME}/.local/blender-${version}}}"
|
||||
|
||||
if [[ "$(uname -s)" != Linux || "$(uname -m)" != x86_64 ]]; then
|
||||
echo "error: this installer currently supports Linux x86_64 only" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -x "$install_dir/blender" ]]; then
|
||||
"$install_dir/blender" --version | head -n 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$install_dir")"
|
||||
tmp_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp_dir"' EXIT
|
||||
|
||||
archive="blender-${version}-linux-x64.tar.xz"
|
||||
url="https://download.blender.org/release/Blender5.2/${archive}"
|
||||
|
||||
curl --fail --location --silent --show-error --output "$tmp_dir/$archive" "$url"
|
||||
printf '%s %s\n' "$sha256" "$tmp_dir/$archive" | sha256sum --check --status
|
||||
tar --extract --xz --file "$tmp_dir/$archive" --directory "$tmp_dir"
|
||||
mv "$tmp_dir/blender-${version}-linux-x64" "$install_dir"
|
||||
|
||||
"$install_dir/blender" --version | head -n 1
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
version="v0.10.0"
|
||||
sha256="0d1633b71e44081c6a3ca57ad5be3df7a9563698827638838939c3c832e87351"
|
||||
install_dir="${1:-${LORE_INSTALL_DIR:-${HOME}/.local/bin}}"
|
||||
|
||||
if [[ "$(uname -s)" != Linux || "$(uname -m)" != x86_64 ]]; then
|
||||
echo "error: this installer currently supports Linux x86_64 only" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$install_dir"
|
||||
tmp_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp_dir"' EXIT
|
||||
|
||||
archive="lore-${version}-x86_64-unknown-linux-gnu.tar.gz"
|
||||
url="https://github.com/EpicGames/lore/releases/download/${version}/${archive}"
|
||||
|
||||
curl --fail --location --silent --show-error --output "$tmp_dir/$archive" "$url"
|
||||
printf '%s %s\n' "$sha256" "$tmp_dir/$archive" | sha256sum --check --status
|
||||
tar --extract --gzip --file "$tmp_dir/$archive" --directory "$tmp_dir"
|
||||
|
||||
binary="$(find "$tmp_dir" -type f -name lore -print -quit)"
|
||||
if [[ -z "$binary" ]]; then
|
||||
echo "error: Lore archive did not contain a lore binary" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
install -m 0755 "$binary" "$install_dir/lore"
|
||||
"$install_dir/lore" --version
|
||||
Executable
+111
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
readonly lore_url="${LORE_REPOSITORY_URL:-lore://lore.eirexe.moe/shinespark}"
|
||||
readonly default_branch="${LORE_DEFAULT_BRANCH:-main}"
|
||||
readonly assets_dir="${LORE_ASSETS_DIR:-assets}"
|
||||
branch="${1:-${LORE_BRANCH:-$default_branch}}"
|
||||
|
||||
case "$branch" in
|
||||
""|*[!A-Za-z0-9._/-]*)
|
||||
echo "error: invalid Lore branch name: $branch" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ -n "${LORE_IDENTITY_TOKEN:-}" ]]; then
|
||||
lore_args=(--identity-token "$LORE_IDENTITY_TOKEN")
|
||||
elif [[ -n "${LORE_CI_USERNAME:-}" || -n "${LORE_CI_PASSWORD:-}" ]]; then
|
||||
if [[ -z "${LORE_CI_USERNAME:-}" || -z "${LORE_CI_PASSWORD:-}" ]]; then
|
||||
echo "error: LORE_CI_USERNAME and LORE_CI_PASSWORD must be provided together" >&2
|
||||
exit 2
|
||||
fi
|
||||
: "${LORE_AUTH_URL:=https://auth.eirexe.moe}"
|
||||
export LORE_AUTH_URL
|
||||
token="$(python3 - <<'PY'
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
request = urllib.request.Request(
|
||||
os.environ["LORE_AUTH_URL"].rstrip("/") + "/auth/login",
|
||||
data=json.dumps({
|
||||
"username": os.environ["LORE_CI_USERNAME"],
|
||||
"password": os.environ["LORE_CI_PASSWORD"],
|
||||
}).encode(),
|
||||
headers={"Content-Type": "application/json"},
|
||||
method="POST",
|
||||
)
|
||||
try:
|
||||
with urllib.request.urlopen(request) as response:
|
||||
payload = json.load(response)
|
||||
except urllib.error.HTTPError as error:
|
||||
print(f"Lore authentication failed with HTTP {error.code}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
token = payload.get("token")
|
||||
if not isinstance(token, str) or not token:
|
||||
print("Lore authentication response did not contain a token", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
print(token)
|
||||
PY
|
||||
)"
|
||||
if [[ -n "${GITHUB_ENV:-}" ]]; then
|
||||
echo "::add-mask::$token"
|
||||
fi
|
||||
lore_args=(--identity-token "$token")
|
||||
else
|
||||
lore_args=()
|
||||
fi
|
||||
|
||||
if [[ -e "$assets_dir" && ! -d "$assets_dir" ]]; then
|
||||
echo "error: $assets_dir exists but is not a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -d "$assets_dir/.lore" ]]; then
|
||||
if ! lore "${lore_args[@]}" --repository "$assets_dir" repository info >/dev/null; then
|
||||
echo "error: $assets_dir is not a usable Lore checkout" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! lore "${lore_args[@]}" --repository "$assets_dir" branch list --no-pager \
|
||||
| grep -Fqx " $branch"; then
|
||||
if [[ "$branch" != "$default_branch" ]]; then
|
||||
echo "warning: Lore branch does not exist: $branch; using $default_branch" >&2
|
||||
branch="$default_branch"
|
||||
else
|
||||
echo "error: Lore branch does not exist: $branch" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
lore "${lore_args[@]}" --repository "$assets_dir" sync "$branch@LATEST"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -d "$assets_dir" && -n "$(find "$assets_dir" -mindepth 1 -maxdepth 1 -print -quit)" ]]; then
|
||||
echo "error: refusing to overwrite non-Lore directory: $assets_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
metadata_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$metadata_dir"' EXIT
|
||||
lore "${lore_args[@]}" --non-interactive clone --bare "$lore_url" "$metadata_dir"
|
||||
|
||||
if ! lore "${lore_args[@]}" --repository "$metadata_dir" branch list --no-pager \
|
||||
| grep -Fqx " $branch"; then
|
||||
if [[ "$branch" != "$default_branch" ]]; then
|
||||
echo "warning: Lore branch does not exist: $branch; using $default_branch" >&2
|
||||
branch="$default_branch"
|
||||
else
|
||||
echo "error: Lore branch does not exist: $branch" >&2
|
||||
echo "available branches:" >&2
|
||||
lore "${lore_args[@]}" --repository "$metadata_dir" branch list --no-pager >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf "$assets_dir"
|
||||
lore "${lore_args[@]}" --non-interactive clone --branch "$branch" "$lore_url" "$assets_dir"
|
||||
lore "${lore_args[@]}" --repository "$assets_dir" status --revision-only --no-pager
|
||||
+22
-4
@@ -84,10 +84,11 @@ impl AssetLoader for BlendSourceLoader {
|
||||
.arg(&blend_path)
|
||||
.arg("--python")
|
||||
.arg(&script)
|
||||
.arg("--")
|
||||
.arg(&output)
|
||||
.arg(&actions_path)
|
||||
.output()
|
||||
.arg("--")
|
||||
.arg(&output)
|
||||
.arg(&actions_path)
|
||||
.arg(&blend_path)
|
||||
.output()
|
||||
.map_err(|error| io::Error::other(format!("failed to start Blender: {error}")))?;
|
||||
if !result.status.success() {
|
||||
return Err(io::Error::other(format!(
|
||||
@@ -106,6 +107,7 @@ impl AssetLoader for BlendSourceLoader {
|
||||
let mut dependencies = manifest.dependencies;
|
||||
let document: serde_json::Value = serde_json::from_slice(&fs::read(&output)?)
|
||||
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
|
||||
validate_export(&document, &output)?;
|
||||
if let Some(images) = document.get("images").and_then(serde_json::Value::as_array) {
|
||||
for image in images {
|
||||
if let Some(uri) = image.get("uri").and_then(serde_json::Value::as_str) {
|
||||
@@ -142,6 +144,22 @@ impl AssetLoader for BlendSourceLoader {
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_export(document: &serde_json::Value, output: &Path) -> io::Result<()> {
|
||||
for key in ["scenes", "nodes", "meshes"] {
|
||||
let count = document
|
||||
.get(key)
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.map_or(0, Vec::len);
|
||||
if count == 0 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
format!("Blender export {} contains no {key}", output.display()),
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn referenced_actions(
|
||||
load_context: &mut LoadContext<'_>,
|
||||
root: &Path,
|
||||
|
||||
@@ -7,6 +7,15 @@ import sys
|
||||
def main():
|
||||
output = sys.argv[sys.argv.index("--") + 1]
|
||||
actions_path = sys.argv[sys.argv.index("--") + 2]
|
||||
source_path = sys.argv[sys.argv.index("--") + 3]
|
||||
loaded_path = os.path.realpath(bpy.data.filepath)
|
||||
expected_path = os.path.realpath(source_path)
|
||||
if loaded_path != expected_path:
|
||||
raise RuntimeError(
|
||||
f"Blender loaded {loaded_path!r} instead of {expected_path!r}"
|
||||
)
|
||||
if not bpy.data.objects or not bpy.data.meshes:
|
||||
raise RuntimeError("Blender loaded an empty scene")
|
||||
with open(actions_path) as file:
|
||||
actions_to_keep = set(json.load(file))
|
||||
|
||||
|
||||
+23
-4
@@ -3,11 +3,9 @@
|
||||
use std::{collections::HashMap, time::Duration};
|
||||
|
||||
use bevy::{
|
||||
input::InputSystems,
|
||||
prelude::*,
|
||||
settings::{ReflectSettingsGroup, SaveSettingsDeferred, SettingsGroup},
|
||||
camera::{CameraOutputMode, visibility::RenderLayers}, input::InputSystems, prelude::*, render::render_resource::BlendState, settings::{ReflectSettingsGroup, SaveSettingsDeferred, SettingsGroup},
|
||||
};
|
||||
use bevy_egui::{EguiContexts, EguiPrimaryContextPass, egui};
|
||||
use bevy_egui::{EguiContexts, EguiGlobalSettings, EguiPrimaryContextPass, PrimaryEguiContext, egui};
|
||||
use bevy_ggrs::{RollbackFrameRate, RunGgrsSystems};
|
||||
use enum_cycling::EnumCycle;
|
||||
use enum_cycling_derive::EnumCycle;
|
||||
@@ -397,6 +395,7 @@ impl Plugin for DebugToolsPlugin {
|
||||
.before(RunGgrsSystems)
|
||||
.run_if(in_state(AppState::InMatch)),
|
||||
)
|
||||
.add_systems(Startup, spawn_egui_camera)
|
||||
.add_systems(PreUpdate, restore_frame_step_time.after(RunGgrsSystems))
|
||||
.add_systems(
|
||||
Update,
|
||||
@@ -408,6 +407,26 @@ impl Plugin for DebugToolsPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn_egui_camera(mut commands: Commands, mut egui_global_settings: ResMut<EguiGlobalSettings>,) {
|
||||
egui_global_settings.auto_create_primary_context = false;
|
||||
commands.spawn((
|
||||
// The `PrimaryEguiContext` component requires everything needed to render a primary context.
|
||||
PrimaryEguiContext,
|
||||
Camera2d,
|
||||
// Setting RenderLayers to none makes sure we won't render anything apart from the UI.
|
||||
RenderLayers::none(),
|
||||
Camera {
|
||||
order: 2,
|
||||
output_mode: CameraOutputMode::Write {
|
||||
blend_state: Some(BlendState::ALPHA_BLENDING),
|
||||
clear_color: ClearColorConfig::None,
|
||||
},
|
||||
clear_color: ClearColorConfig::Custom(Color::NONE),
|
||||
..default()
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
fn player_handles(players: &Query<&Player>) -> Vec<usize> {
|
||||
let mut handles = players
|
||||
.iter()
|
||||
|
||||
@@ -1,19 +1,8 @@
|
||||
use bevy::{picking::pointer::PointerId, prelude::*};
|
||||
|
||||
use crate::{
|
||||
AppState,
|
||||
fighter::manifest::{FighterManifest, FighterManifestRegistry},
|
||||
game_settings::CommonAssets,
|
||||
input::{LocalInputAssignments, LocalInputSource},
|
||||
menus::{
|
||||
MenuMarker,
|
||||
button::FGUiButton,
|
||||
character_select::{character_box::CharacterBox, token::CharacterSelectToken},
|
||||
cursor::{FGMenuCursor, MenuCursorInputSource},
|
||||
errors::MenuErrors::FighterManifestNotFound,
|
||||
match_config::{MenuMatchConfig, MenuMatchPlayerSlot},
|
||||
scaling, spawn_menu,
|
||||
style::{FGUiButtonType, FGUiStyle},
|
||||
AppState, fighter::manifest::{FighterManifest, FighterManifestRegistry}, game_settings::CommonAssets, input::{LocalInputAssignments, LocalInputSource}, menus::{
|
||||
MenuCameraMarker, MenuMarker, button::FGUiButton, character_select::{character_box::CharacterBox, token::CharacterSelectToken}, cursor::{FGMenuCursor, MenuCursorInputSource}, errors::MenuErrors::FighterManifestNotFound, match_config::{MenuMatchConfig, MenuMatchPlayerSlot}, scaling, spawn_menu, style::{FGUiButtonType, FGUiStyle},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -241,7 +230,7 @@ pub fn copy_cursor_transform_to_token(
|
||||
character_boxes: Query<(&CharacterBox, &ComputedNode, &UiGlobalTransform)>,
|
||||
match_config: Res<MenuMatchConfig>,
|
||||
cursors: Query<&UiGlobalTransform, With<FGMenuCursor>>,
|
||||
cam: Single<&Camera>,
|
||||
cam: Single<&Camera, With<MenuCameraMarker>>,
|
||||
ui_scale: Res<UiScale>,
|
||||
) -> Result {
|
||||
let camera = cam.into_inner();
|
||||
|
||||
+3
-6
@@ -9,11 +9,8 @@ use bevy::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
input::{LocalInputAssignments, LocalInputSource},
|
||||
menus::{
|
||||
input::{MenuInput, MenuInputState},
|
||||
scaling,
|
||||
style::FGUiStyle,
|
||||
input::{LocalInputAssignments, LocalInputSource}, menus::{
|
||||
MenuCameraMarker, input::{MenuInput, MenuInputState}, scaling, style::FGUiStyle,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -181,7 +178,7 @@ pub fn cursor_input(
|
||||
}
|
||||
|
||||
pub fn update_cursor_transform(
|
||||
camera: Single<&Camera>,
|
||||
camera: Single<&Camera, With<MenuCameraMarker>>,
|
||||
query: Query<(&mut Node, &PointerLocation), With<FGMenuCursor>>,
|
||||
ui_scale: Res<UiScale>,
|
||||
) {
|
||||
|
||||
+1
-4
@@ -53,6 +53,7 @@ pub fn wrap_menu(menu: impl Scene) -> impl Scene {
|
||||
#MenuCamera
|
||||
Camera
|
||||
Camera2d
|
||||
MenuCameraMarker
|
||||
),
|
||||
(
|
||||
#MenuContainer
|
||||
@@ -73,7 +74,6 @@ pub fn wrap_menu(menu: impl Scene) -> impl Scene {
|
||||
|
||||
pub fn despawn_menu(
|
||||
existing_menu: Option<Single<Entity, With<MenuMarker>>>,
|
||||
existing_menu_camera: Option<Single<Entity, With<MenuCameraMarker>>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
if let Some(entity) = existing_menu {
|
||||
@@ -82,9 +82,6 @@ pub fn despawn_menu(
|
||||
.despawn();
|
||||
}
|
||||
|
||||
if let Some(menu_cam) = existing_menu_camera {
|
||||
commands.entity(*menu_cam).despawn();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn_menu(
|
||||
|
||||
Reference in New Issue
Block a user