Compare commits
10
Commits
ui_fix
..
b0954d25fb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0954d25fb | ||
|
|
b1203fe35b | ||
|
|
87fecddf5f | ||
|
|
2c66d43767 | ||
|
|
e83f1fda2c | ||
|
|
c9434f8ec2 | ||
|
|
d4bb3e2620 | ||
|
|
4a15b089ac | ||
|
|
d430eed641 | ||
|
|
86593fb0cd |
+2
-75
@@ -15,27 +15,6 @@ jobs:
|
|||||||
- name: Check out source
|
- name: Check out source
|
||||||
uses: actions/checkout@v4
|
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
|
- name: Install Rust toolchain
|
||||||
run: |
|
run: |
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
|
||||||
@@ -63,6 +42,7 @@ jobs:
|
|||||||
libxkbcommon-dev \
|
libxkbcommon-dev \
|
||||||
libxkbcommon-x11-0 \
|
libxkbcommon-x11-0 \
|
||||||
mesa-vulkan-drivers \
|
mesa-vulkan-drivers \
|
||||||
|
blender \
|
||||||
mold \
|
mold \
|
||||||
pkg-config
|
pkg-config
|
||||||
|
|
||||||
@@ -79,27 +59,6 @@ jobs:
|
|||||||
- name: Check out source
|
- name: Check out source
|
||||||
uses: actions/checkout@v4
|
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
|
- name: Install Rust toolchain
|
||||||
run: |
|
run: |
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
|
||||||
@@ -129,54 +88,22 @@ jobs:
|
|||||||
libusb-1.0-0-dev \
|
libusb-1.0-0-dev \
|
||||||
libwayland-dev \
|
libwayland-dev \
|
||||||
libx11-dev \
|
libx11-dev \
|
||||||
libxfixes3 \
|
|
||||||
libxi6 \
|
|
||||||
libxkbcommon-dev \
|
libxkbcommon-dev \
|
||||||
libxkbcommon-x11-0 \
|
libxkbcommon-x11-0 \
|
||||||
blender \
|
|
||||||
lld-19 \
|
lld-19 \
|
||||||
llvm-19 \
|
llvm-19 \
|
||||||
mesa-vulkan-drivers \
|
mesa-vulkan-drivers \
|
||||||
mold \
|
mold \
|
||||||
|
blender \
|
||||||
pkg-config
|
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
|
||||||
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"
|
echo "/usr/lib/llvm-19/bin" >> "$GITHUB_PATH"
|
||||||
rm -f "$HOME/.cache/cargo-xwin/clang-cl"
|
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
|
- name: Preprocess assets
|
||||||
run: cargo run --locked --bin process-assets --no-default-features --features debug_features -j 4
|
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
|
- name: Build production binary
|
||||||
run: cargo build --locked --profile production --no-default-features --features debug_features -j 4
|
run: cargo build --locked --profile production --no-default-features --features debug_features -j 4
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/target
|
/target
|
||||||
/.jackdaw
|
/.jackdaw
|
||||||
imported_assets
|
imported_assets
|
||||||
/assets/
|
|
||||||
|
|
||||||
# Local editor configuration
|
# Local editor configuration
|
||||||
**/.vscode/
|
**/.vscode/
|
||||||
|
|||||||
@@ -30,21 +30,4 @@ cargo run --locked \
|
|||||||
--bin process-assets --no-default-features --features debug_features
|
--bin process-assets --no-default-features --features debug_features
|
||||||
cargo build --locked \
|
cargo build --locked \
|
||||||
--profile production --no-default-features --features debug_features
|
--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.
|
After Width: | Height: | Size: 31 KiB |
@@ -0,0 +1,12 @@
|
|||||||
|
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);
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
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);
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
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.
@@ -0,0 +1,219 @@
|
|||||||
|
(
|
||||||
|
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"
|
||||||
|
),*/
|
||||||
|
]
|
||||||
|
)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
(
|
||||||
|
manifest_path: "fighters/test/test.fighter.ron",
|
||||||
|
)
|
||||||
Binary file not shown.
@@ -0,0 +1,128 @@
|
|||||||
|
(
|
||||||
|
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))
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
(
|
||||||
|
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.
|
After Width: | Height: | Size: 42 KiB |
@@ -0,0 +1,139 @@
|
|||||||
|
(
|
||||||
|
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.
|
After Width: | Height: | Size: 871 B |
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
@@ -0,0 +1,77 @@
|
|||||||
|
<?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>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -1,30 +0,0 @@
|
|||||||
#!/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
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#!/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
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
#!/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
|
|
||||||
+4
-22
@@ -84,11 +84,10 @@ impl AssetLoader for BlendSourceLoader {
|
|||||||
.arg(&blend_path)
|
.arg(&blend_path)
|
||||||
.arg("--python")
|
.arg("--python")
|
||||||
.arg(&script)
|
.arg(&script)
|
||||||
.arg("--")
|
.arg("--")
|
||||||
.arg(&output)
|
.arg(&output)
|
||||||
.arg(&actions_path)
|
.arg(&actions_path)
|
||||||
.arg(&blend_path)
|
.output()
|
||||||
.output()
|
|
||||||
.map_err(|error| io::Error::other(format!("failed to start Blender: {error}")))?;
|
.map_err(|error| io::Error::other(format!("failed to start Blender: {error}")))?;
|
||||||
if !result.status.success() {
|
if !result.status.success() {
|
||||||
return Err(io::Error::other(format!(
|
return Err(io::Error::other(format!(
|
||||||
@@ -107,7 +106,6 @@ impl AssetLoader for BlendSourceLoader {
|
|||||||
let mut dependencies = manifest.dependencies;
|
let mut dependencies = manifest.dependencies;
|
||||||
let document: serde_json::Value = serde_json::from_slice(&fs::read(&output)?)
|
let document: serde_json::Value = serde_json::from_slice(&fs::read(&output)?)
|
||||||
.map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
|
.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) {
|
if let Some(images) = document.get("images").and_then(serde_json::Value::as_array) {
|
||||||
for image in images {
|
for image in images {
|
||||||
if let Some(uri) = image.get("uri").and_then(serde_json::Value::as_str) {
|
if let Some(uri) = image.get("uri").and_then(serde_json::Value::as_str) {
|
||||||
@@ -144,22 +142,6 @@ 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(
|
async fn referenced_actions(
|
||||||
load_context: &mut LoadContext<'_>,
|
load_context: &mut LoadContext<'_>,
|
||||||
root: &Path,
|
root: &Path,
|
||||||
|
|||||||
@@ -7,15 +7,6 @@ import sys
|
|||||||
def main():
|
def main():
|
||||||
output = sys.argv[sys.argv.index("--") + 1]
|
output = sys.argv[sys.argv.index("--") + 1]
|
||||||
actions_path = sys.argv[sys.argv.index("--") + 2]
|
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:
|
with open(actions_path) as file:
|
||||||
actions_to_keep = set(json.load(file))
|
actions_to_keep = set(json.load(file))
|
||||||
|
|
||||||
|
|||||||
+4
-23
@@ -3,9 +3,11 @@
|
|||||||
use std::{collections::HashMap, time::Duration};
|
use std::{collections::HashMap, time::Duration};
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
camera::{CameraOutputMode, visibility::RenderLayers}, input::InputSystems, prelude::*, render::render_resource::BlendState, settings::{ReflectSettingsGroup, SaveSettingsDeferred, SettingsGroup},
|
input::InputSystems,
|
||||||
|
prelude::*,
|
||||||
|
settings::{ReflectSettingsGroup, SaveSettingsDeferred, SettingsGroup},
|
||||||
};
|
};
|
||||||
use bevy_egui::{EguiContexts, EguiGlobalSettings, EguiPrimaryContextPass, PrimaryEguiContext, egui};
|
use bevy_egui::{EguiContexts, EguiPrimaryContextPass, egui};
|
||||||
use bevy_ggrs::{RollbackFrameRate, RunGgrsSystems};
|
use bevy_ggrs::{RollbackFrameRate, RunGgrsSystems};
|
||||||
use enum_cycling::EnumCycle;
|
use enum_cycling::EnumCycle;
|
||||||
use enum_cycling_derive::EnumCycle;
|
use enum_cycling_derive::EnumCycle;
|
||||||
@@ -395,7 +397,6 @@ impl Plugin for DebugToolsPlugin {
|
|||||||
.before(RunGgrsSystems)
|
.before(RunGgrsSystems)
|
||||||
.run_if(in_state(AppState::InMatch)),
|
.run_if(in_state(AppState::InMatch)),
|
||||||
)
|
)
|
||||||
.add_systems(Startup, spawn_egui_camera)
|
|
||||||
.add_systems(PreUpdate, restore_frame_step_time.after(RunGgrsSystems))
|
.add_systems(PreUpdate, restore_frame_step_time.after(RunGgrsSystems))
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
@@ -407,26 +408,6 @@ 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> {
|
fn player_handles(players: &Query<&Player>) -> Vec<usize> {
|
||||||
let mut handles = players
|
let mut handles = players
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
use bevy::{picking::pointer::PointerId, prelude::*};
|
use bevy::{picking::pointer::PointerId, prelude::*};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState, fighter::manifest::{FighterManifest, FighterManifestRegistry}, game_settings::CommonAssets, input::{LocalInputAssignments, LocalInputSource}, menus::{
|
AppState,
|
||||||
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},
|
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},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -230,7 +241,7 @@ pub fn copy_cursor_transform_to_token(
|
|||||||
character_boxes: Query<(&CharacterBox, &ComputedNode, &UiGlobalTransform)>,
|
character_boxes: Query<(&CharacterBox, &ComputedNode, &UiGlobalTransform)>,
|
||||||
match_config: Res<MenuMatchConfig>,
|
match_config: Res<MenuMatchConfig>,
|
||||||
cursors: Query<&UiGlobalTransform, With<FGMenuCursor>>,
|
cursors: Query<&UiGlobalTransform, With<FGMenuCursor>>,
|
||||||
cam: Single<&Camera, With<MenuCameraMarker>>,
|
cam: Single<&Camera>,
|
||||||
ui_scale: Res<UiScale>,
|
ui_scale: Res<UiScale>,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
let camera = cam.into_inner();
|
let camera = cam.into_inner();
|
||||||
|
|||||||
+6
-3
@@ -9,8 +9,11 @@ use bevy::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
input::{LocalInputAssignments, LocalInputSource}, menus::{
|
input::{LocalInputAssignments, LocalInputSource},
|
||||||
MenuCameraMarker, input::{MenuInput, MenuInputState}, scaling, style::FGUiStyle,
|
menus::{
|
||||||
|
input::{MenuInput, MenuInputState},
|
||||||
|
scaling,
|
||||||
|
style::FGUiStyle,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,7 +181,7 @@ pub fn cursor_input(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_cursor_transform(
|
pub fn update_cursor_transform(
|
||||||
camera: Single<&Camera, With<MenuCameraMarker>>,
|
camera: Single<&Camera>,
|
||||||
query: Query<(&mut Node, &PointerLocation), With<FGMenuCursor>>,
|
query: Query<(&mut Node, &PointerLocation), With<FGMenuCursor>>,
|
||||||
ui_scale: Res<UiScale>,
|
ui_scale: Res<UiScale>,
|
||||||
) {
|
) {
|
||||||
|
|||||||
+4
-1
@@ -53,7 +53,6 @@ pub fn wrap_menu(menu: impl Scene) -> impl Scene {
|
|||||||
#MenuCamera
|
#MenuCamera
|
||||||
Camera
|
Camera
|
||||||
Camera2d
|
Camera2d
|
||||||
MenuCameraMarker
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
#MenuContainer
|
#MenuContainer
|
||||||
@@ -74,6 +73,7 @@ pub fn wrap_menu(menu: impl Scene) -> impl Scene {
|
|||||||
|
|
||||||
pub fn despawn_menu(
|
pub fn despawn_menu(
|
||||||
existing_menu: Option<Single<Entity, With<MenuMarker>>>,
|
existing_menu: Option<Single<Entity, With<MenuMarker>>>,
|
||||||
|
existing_menu_camera: Option<Single<Entity, With<MenuCameraMarker>>>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
) {
|
) {
|
||||||
if let Some(entity) = existing_menu {
|
if let Some(entity) = existing_menu {
|
||||||
@@ -82,6 +82,9 @@ pub fn despawn_menu(
|
|||||||
.despawn();
|
.despawn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(menu_cam) = existing_menu_camera {
|
||||||
|
commands.entity(*menu_cam).despawn();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_menu(
|
pub fn spawn_menu(
|
||||||
|
|||||||
Reference in New Issue
Block a user