Compare commits
10 Commits
13a74f7620
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a3a83b071 | |||
| 69215bdb91 | |||
| 9f8d1888ec | |||
| ebae1599f1 | |||
| 8bf58bb04c | |||
| f342970228 | |||
| fca907aee4 | |||
| f9e96cc74b | |||
| 3551ecfde8 | |||
| 227b654e50 |
140
.github/workflows/ci.yaml
vendored
Normal file
140
.github/workflows/ci.yaml
vendored
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
pull_request:
|
||||||
|
branches: [master]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Reduce compile time and cache size.
|
||||||
|
RUSTFLAGS: -Zshare-generics=y -Zthreads=0
|
||||||
|
RUSTDOCFLAGS: -Zshare-generics=y -Zthreads=0
|
||||||
|
# Use the same Rust toolchain across jobs so they can share a cache.
|
||||||
|
toolchain: nightly-2025-04-03
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Run Clippy lints.
|
||||||
|
clippy-lints:
|
||||||
|
name: Clippy lints
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
RUSTFLAGS: "-Dwarnings"
|
||||||
|
timeout-minutes: 20
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: dtolnay/rust-toolchain@master
|
||||||
|
with:
|
||||||
|
toolchain: ${{ env.toolchain }}
|
||||||
|
components: clippy
|
||||||
|
|
||||||
|
- name: Restore Rust cache
|
||||||
|
id: cache
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
shared-key: ci
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
|
- name: Install build dependencies
|
||||||
|
if: steps.cache.outputs.cache-hit != 'true'
|
||||||
|
run: sudo apt-get -y update; sudo apt-get -y install --no-install-recommends libasound2-dev libudev-dev libwayland-dev
|
||||||
|
|
||||||
|
- name: Run Clippy lints
|
||||||
|
run: cargo clippy --locked --workspace --all-targets --profile ci --all-features
|
||||||
|
|
||||||
|
# Run Bevy lints.
|
||||||
|
bevy-lints:
|
||||||
|
name: Bevy lints
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
RUSTFLAGS: "-Dwarnings"
|
||||||
|
timeout-minutes: 20
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Rust toolchain (plus bevy_lint)
|
||||||
|
uses: TheBevyFlock/bevy_cli/bevy_lint@lint-v0.3.0
|
||||||
|
|
||||||
|
- name: Restore Rust cache
|
||||||
|
id: cache
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
shared-key: ci
|
||||||
|
save-if: false
|
||||||
|
|
||||||
|
- name: Install build dependencies
|
||||||
|
if: steps.cache.outputs.cache-hit != 'true'
|
||||||
|
run: sudo apt-get -y update; sudo apt-get -y install --no-install-recommends libasound2-dev libudev-dev libwayland-dev
|
||||||
|
|
||||||
|
- name: Run Bevy lints
|
||||||
|
run: bevy_lint --locked --workspace --all-targets --profile ci --all-features
|
||||||
|
|
||||||
|
# Run tests.
|
||||||
|
tests:
|
||||||
|
name: Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 40
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up environment
|
||||||
|
run: echo "RUSTFLAGS=${RUSTFLAGS:+$RUSTFLAGS }-Zcodegen-backend=cranelift" >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: dtolnay/rust-toolchain@master
|
||||||
|
with:
|
||||||
|
toolchain: ${{ env.toolchain }}
|
||||||
|
components: rustc-codegen-cranelift-preview
|
||||||
|
|
||||||
|
- name: Restore Rust cache
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
shared-key: test
|
||||||
|
cache-directories: ${{ env.LD_LIBRARY_PATH }}
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
|
- name: Install build dependencies
|
||||||
|
run: sudo apt-get -y update; sudo apt-get -y install --no-install-recommends libasound2-dev libudev-dev libwayland-dev
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: cargo test --locked --workspace --all-targets --profile ci --no-fail-fast
|
||||||
|
|
||||||
|
# Check that the web build compiles.
|
||||||
|
# check-web:
|
||||||
|
# name: Check web
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# env:
|
||||||
|
# RUSTFLAGS: -Zshare-generics=y -Zthreads=0 --cfg getrandom_backend="wasm_js"
|
||||||
|
# timeout-minutes: 20
|
||||||
|
# steps:
|
||||||
|
# - name: Checkout repository
|
||||||
|
# uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# - name: Install Rust toolchain
|
||||||
|
# uses: dtolnay/rust-toolchain@master
|
||||||
|
# with:
|
||||||
|
# toolchain: ${{ env.toolchain }}
|
||||||
|
# targets: wasm32-unknown-unknown
|
||||||
|
|
||||||
|
# - name: Restore Rust cache
|
||||||
|
# id: cache
|
||||||
|
# uses: Swatinem/rust-cache@v2
|
||||||
|
# with:
|
||||||
|
# shared-key: web-ci
|
||||||
|
# save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
|
# - name: Install build dependencies
|
||||||
|
# if: steps.cache.outputs.cache-hit != 'true'
|
||||||
|
# run: sudo apt-get -y update; sudo apt-get -y install --no-install-recommends libasound2-dev libudev-dev libwayland-dev
|
||||||
|
|
||||||
|
# - name: Check web
|
||||||
|
# run: cargo check --config 'profile.web.inherits="dev"' --profile ci --no-default-features --features "dev web" --target wasm32-unknown-unknown
|
||||||
335
.github/workflows/release.yaml
vendored
Normal file
335
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,335 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Trigger this workflow when a tag is pushed in the format `v1.2.3`.
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
# Pattern syntax: <https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet>.
|
||||||
|
- "v[0-9]+.[0-9]+.[0-9]+*"
|
||||||
|
# Trigger this workflow manually via workflow dispatch.
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: "Version number in the format `v1.2.3`"
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
# Configure the release workflow by editing the following values.
|
||||||
|
env:
|
||||||
|
# The base filename of the binary produced by `cargo build`.
|
||||||
|
cargo_build_binary_name: phos
|
||||||
|
|
||||||
|
# The path to the assets directory.
|
||||||
|
assets_path: assets
|
||||||
|
|
||||||
|
# Whether to build and package a release for a given target platform.
|
||||||
|
build_for_web: false
|
||||||
|
build_for_linux: true
|
||||||
|
build_for_windows: true
|
||||||
|
build_for_macos: false
|
||||||
|
|
||||||
|
# Whether to upload the packages produced by this workflow to a GitHub release.
|
||||||
|
upload_to_github: true
|
||||||
|
|
||||||
|
# The itch.io project to upload to in the format `user-name/project-name`.
|
||||||
|
# There will be no upload to itch.io if this is commented out.
|
||||||
|
# upload_to_itch: amatsugu/phos
|
||||||
|
|
||||||
|
############
|
||||||
|
# ADVANCED #
|
||||||
|
############
|
||||||
|
|
||||||
|
# The ID of the app produced by this workflow.
|
||||||
|
# Applies to macOS releases.
|
||||||
|
# Must contain only A-Z, a-z, 0-9, hyphen, and period: <https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleidentifier>.
|
||||||
|
app_id: amatsugu.phos
|
||||||
|
|
||||||
|
# The base filename of the binary in the package produced by this workflow.
|
||||||
|
# Applies to Windows, macOS, and Linux releases.
|
||||||
|
# Defaults to `cargo_build_binary_name` if commented out.
|
||||||
|
#app_binary_name: bevy_jam_6
|
||||||
|
|
||||||
|
# The name of the `.zip` or `.dmg` file produced by this workflow.
|
||||||
|
# Defaults to `app_binary_name` if commented out.
|
||||||
|
#app_package_name: bevy-new-2d
|
||||||
|
|
||||||
|
# The display name of the app produced by this workflow.
|
||||||
|
# Applies to macOS releases.
|
||||||
|
# Defaults to `app_package_name` if commented out.
|
||||||
|
app_display_name: phos
|
||||||
|
|
||||||
|
# The short display name of the app produced by this workflow.
|
||||||
|
# Applies to macOS releases.
|
||||||
|
# Must be 15 or fewer characters: <https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundlename>.
|
||||||
|
# Defaults to `app_display_name` if commented out.
|
||||||
|
#app_short_name: Phos
|
||||||
|
|
||||||
|
# Before enabling LFS, please take a look at GitHub's documentation for costs and quota limits:
|
||||||
|
# <https://docs.github.com/en/repositories/working-with-files/managing-large-files/about-storage-and-bandwidth-usage>
|
||||||
|
git_lfs: false
|
||||||
|
|
||||||
|
# Enabling this only helps with consecutive releases to the same tag (and takes up cache storage space).
|
||||||
|
# See: <https://github.com/orgs/community/discussions/27059>.
|
||||||
|
use_github_cache: false
|
||||||
|
|
||||||
|
# Reduce compile time.
|
||||||
|
RUSTFLAGS: -Zshare-generics=y -Zthreads=0
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Forward some environment variables as outputs of this job.
|
||||||
|
# This is needed because the `env` context can't be used in the `if:` condition of a job:
|
||||||
|
# <https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability>
|
||||||
|
forward-env:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Do nothing
|
||||||
|
run: "true"
|
||||||
|
outputs:
|
||||||
|
upload_to_itch: ${{ env.upload_to_itch }}
|
||||||
|
|
||||||
|
# Determine the version number for this workflow.
|
||||||
|
get-version:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Determine version number
|
||||||
|
id: tag
|
||||||
|
run: echo "tag=${GITHUB_REF#refs/tags/}" >> "${GITHUB_OUTPUT}"
|
||||||
|
outputs:
|
||||||
|
# Use the input from workflow dispatch, or fall back to the git tag.
|
||||||
|
version: ${{ inputs.version || steps.tag.outputs.tag }}
|
||||||
|
|
||||||
|
# Build and package a release for each platform.
|
||||||
|
build:
|
||||||
|
needs:
|
||||||
|
- get-version
|
||||||
|
env:
|
||||||
|
version: ${{ needs.get-version.outputs.version }}
|
||||||
|
# Avoid rate-limiting. See: <https://github.com/cargo-bins/cargo-binstall/issues/2045>.
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- platform: web
|
||||||
|
targets: wasm32-unknown-unknown
|
||||||
|
package_ext: .zip
|
||||||
|
runner: ubuntu-latest
|
||||||
|
|
||||||
|
- platform: linux
|
||||||
|
targets: x86_64-unknown-linux-gnu
|
||||||
|
package_ext: .zip
|
||||||
|
runner: ubuntu-latest
|
||||||
|
|
||||||
|
- platform: windows
|
||||||
|
targets: x86_64-pc-windows-msvc
|
||||||
|
binary_ext: .exe
|
||||||
|
package_ext: .zip
|
||||||
|
runner: windows-latest
|
||||||
|
|
||||||
|
- platform: macos
|
||||||
|
targets: x86_64-apple-darwin aarch64-apple-darwin
|
||||||
|
app_suffix: .app/Contents/MacOS
|
||||||
|
package_ext: .dmg
|
||||||
|
runner: macos-latest
|
||||||
|
runs-on: ${{ matrix.runner }}
|
||||||
|
permissions:
|
||||||
|
# Required to create a GitHub release: <https://docs.github.com/en/rest/releases/releases#create-a-release>.
|
||||||
|
contents: write
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up environment
|
||||||
|
run: |
|
||||||
|
# Default values:
|
||||||
|
echo "app_binary_name=${app_binary_name:=${{ env.cargo_build_binary_name }}}" >> "${GITHUB_ENV}"
|
||||||
|
echo "app_package_name=${app_package_name:=${app_binary_name}}" >> "${GITHUB_ENV}"
|
||||||
|
echo "app_display_name=${app_display_name:=${app_package_name}}" >> "${GITHUB_ENV}"
|
||||||
|
echo "app_short_name=${app_short_name:=${app_display_name}}" >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
|
# File paths:
|
||||||
|
echo "app=tmp/app/${app_package_name}"'${{ matrix.app_suffix }}' >> "${GITHUB_ENV}"
|
||||||
|
echo "package=${app_package_name}-"'${{ matrix.platform }}${{ matrix.package_ext }}' >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
|
# macOS environment:
|
||||||
|
if [ '${{ matrix.platform }}' = 'macos' ]; then
|
||||||
|
echo 'MACOSX_DEPLOYMENT_TARGET=11.0' >> "${GITHUB_ENV}" # macOS 11.0 Big Sur is the first version to support universal binaries.
|
||||||
|
echo "SDKROOT=$(xcrun --sdk macosx --show-sdk-path)" >> "${GITHUB_ENV}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if building for this platform is enabled.
|
||||||
|
echo 'is_platform_enabled=${{
|
||||||
|
(matrix.platform == 'web' && env.build_for_web == 'true') ||
|
||||||
|
(matrix.platform == 'linux' && env.build_for_linux == 'true') ||
|
||||||
|
(matrix.platform == 'windows' && env.build_for_windows == 'true') ||
|
||||||
|
(matrix.platform == 'macos' && env.build_for_macos == 'true')
|
||||||
|
}}' >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
|
- name: Checkout repository
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
lfs: ${{ env.git_lfs }}
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
uses: dtolnay/rust-toolchain@nightly
|
||||||
|
with:
|
||||||
|
targets: ${{ matrix.targets }}
|
||||||
|
|
||||||
|
- name: Restore Rust cache
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && env.use_github_cache == 'true' }}
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
shared-key: release
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
|
- name: Install build dependencies (Linux)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'linux' }}
|
||||||
|
run: sudo apt-get -y update; sudo apt-get -y install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev
|
||||||
|
|
||||||
|
- name: Prepare output directories
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
run: rm -rf tmp; mkdir -p tmp/binary '${{ env.app }}'
|
||||||
|
|
||||||
|
- name: Install cargo-binstall
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
uses: cargo-bins/cargo-binstall@main
|
||||||
|
|
||||||
|
- name: Install Bevy CLI
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
run: cargo binstall --locked --no-confirm --force --git='https://github.com/TheBevyFlock/bevy_cli' bevy_cli
|
||||||
|
|
||||||
|
- name: Build and add web bundle to app (Web)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'web' }}
|
||||||
|
run: |
|
||||||
|
cargo binstall --locked --no-confirm --force wasm-bindgen-cli
|
||||||
|
cargo binstall --locked --no-confirm --force wasm-opt
|
||||||
|
RUSTFLAGS='-Zshare-generics=y -Zthreads=0 --cfg getrandom_backend="wasm_js"' bevy build --locked --release --features='${{ matrix.features }} web' --yes web --bundle
|
||||||
|
mv 'target/bevy_web/web-release/${{ env.cargo_build_binary_name }}' '${{ env.app }}'
|
||||||
|
|
||||||
|
- name: Build and add binaries to app (non-Web)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'web' }}
|
||||||
|
run: |
|
||||||
|
for target in ${{ matrix.targets }}; do
|
||||||
|
bevy build --locked --release --target="${target}" --features='${{ matrix.features }}'
|
||||||
|
mv target/"${target}"/release/'${{ env.cargo_build_binary_name }}${{ matrix.binary_ext }}' tmp/binary/"${target}"'${{ matrix.binary_ext }}'
|
||||||
|
done
|
||||||
|
if [ '${{ matrix.platform }}' = 'macos' ]; then
|
||||||
|
lipo tmp/binary/*'${{ matrix.binary_ext }}' -create -output '${{ env.app }}/${{ env.app_binary_name }}${{ matrix.binary_ext }}'
|
||||||
|
else
|
||||||
|
mv tmp/binary/*'${{ matrix.binary_ext }}' '${{ env.app }}/${{ env.app_binary_name }}${{ matrix.binary_ext }}'
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Add assets to app (non-Web)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'web' }}
|
||||||
|
run: cp -R ./'${{ env.assets_path }}' '${{ env.app }}' || true # Ignore error if assets folder does not exist.
|
||||||
|
|
||||||
|
- name: Add metadata to app (macOS)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'macos' }}
|
||||||
|
run: |
|
||||||
|
cat >'${{ env.app }}/../Info.plist' <<EOF
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>${{ env.app_display_name }}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${{ env.app_binary_name }}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${{ env.app_id }}</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${{ env.app_short_name }}</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${{ env.version }}</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${{ env.version }}</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleSupportedPlatforms</key>
|
||||||
|
<array>
|
||||||
|
<string>MacOSX</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Package app (non-Windows)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'windows' }}
|
||||||
|
working-directory: tmp/app
|
||||||
|
run: |
|
||||||
|
if [ '${{ matrix.platform }}' = 'macos' ]; then
|
||||||
|
ln -s /Applications .
|
||||||
|
hdiutil create -fs HFS+ -volname '${{ env.app_package_name }}' -srcfolder . '${{ env.package }}'
|
||||||
|
else
|
||||||
|
zip --recurse-paths '${{ env.package }}' '${{ env.app_package_name }}'
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Package app (Windows)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'windows' }}
|
||||||
|
working-directory: tmp/app
|
||||||
|
shell: pwsh
|
||||||
|
run: Compress-Archive -Path '${{ env.app_package_name }}' -DestinationPath '${{ env.package }}'
|
||||||
|
|
||||||
|
- name: Upload package to workflow artifacts
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
path: tmp/app/${{ env.package }}
|
||||||
|
name: package-${{ matrix.platform }}
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
|
- name: Upload package to GitHub release
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && env.upload_to_github == 'true' }}
|
||||||
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
with:
|
||||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
file: tmp/app/${{ env.package }}
|
||||||
|
asset_name: ${{ env.package }}
|
||||||
|
release_name: ${{ env.version }}
|
||||||
|
tag: ${{ env.version }}
|
||||||
|
overwrite: true
|
||||||
|
|
||||||
|
# Upload all packages to itch.io.
|
||||||
|
upload-to-itch:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- forward-env
|
||||||
|
- get-version
|
||||||
|
- build
|
||||||
|
if: ${{ needs.forward-env.outputs.upload_to_itch != '' }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Download all packages
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: package-*
|
||||||
|
path: tmp
|
||||||
|
|
||||||
|
- name: Install butler
|
||||||
|
run: |
|
||||||
|
curl -L -o butler.zip 'https://broth.itch.zone/butler/linux-amd64/LATEST/archive/default'
|
||||||
|
unzip butler.zip
|
||||||
|
chmod +x butler
|
||||||
|
./butler -V
|
||||||
|
|
||||||
|
- name: Upload all packages to itch.io
|
||||||
|
env:
|
||||||
|
BUTLER_API_KEY: ${{ secrets.BUTLER_CREDENTIALS }}
|
||||||
|
run: |
|
||||||
|
for channel in $(ls tmp); do
|
||||||
|
./butler push \
|
||||||
|
--fix-permissions \
|
||||||
|
--userversion='${{ needs.get-version.outputs.version }}' \
|
||||||
|
tmp/"${channel}"/* \
|
||||||
|
'${{ env.upload_to_itch }}':"${channel#package-}"
|
||||||
|
done
|
||||||
347
.github/workflows/release.yaml.template
vendored
Normal file
347
.github/workflows/release.yaml.template
vendored
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Trigger this workflow when a tag is pushed in the format `v1.2.3`.
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
# Pattern syntax: <https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet>.
|
||||||
|
- "v[0-9]+.[0-9]+.[0-9]+*"
|
||||||
|
# Trigger this workflow manually via workflow dispatch.
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: "Version number in the format `v1.2.3`"
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
{% raw -%}
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
{%- endraw %}
|
||||||
|
|
||||||
|
# Configure the release workflow by editing the following values.
|
||||||
|
env:
|
||||||
|
# The base filename of the binary produced by `cargo build`.
|
||||||
|
cargo_build_binary_name: {{project-name}}
|
||||||
|
|
||||||
|
# The path to the assets directory.
|
||||||
|
assets_path: assets
|
||||||
|
|
||||||
|
# Whether to build and package a release for a given target platform.
|
||||||
|
build_for_web: true
|
||||||
|
build_for_linux: true
|
||||||
|
build_for_windows: true
|
||||||
|
build_for_macos: true
|
||||||
|
|
||||||
|
# Whether to upload the packages produced by this workflow to a GitHub release.
|
||||||
|
upload_to_github: true
|
||||||
|
|
||||||
|
# The itch.io project to upload to in the format `user-name/project-name`.
|
||||||
|
# There will be no upload to itch.io if this is commented out.
|
||||||
|
{%- if itch_username != "" %}
|
||||||
|
{%- if itch_project != "" %}
|
||||||
|
upload_to_itch: {{itch_username}}/{{itch_project}}
|
||||||
|
{%- else %}
|
||||||
|
upload_to_itch: {{itch_username}}/{{project-name}}
|
||||||
|
{%- endif %}
|
||||||
|
{%- else %}
|
||||||
|
#upload_to_itch: your-itch-username/{{project-name}}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
############
|
||||||
|
# ADVANCED #
|
||||||
|
############
|
||||||
|
|
||||||
|
# The ID of the app produced by this workflow.
|
||||||
|
# Applies to macOS releases.
|
||||||
|
# Must contain only A-Z, a-z, 0-9, hyphen, and period: <https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleidentifier>.
|
||||||
|
app_id: {{itch_username | kebab_case}}.{{project-name | kebab_case}}
|
||||||
|
|
||||||
|
# The base filename of the binary in the package produced by this workflow.
|
||||||
|
# Applies to Windows, macOS, and Linux releases.
|
||||||
|
# Defaults to `cargo_build_binary_name` if commented out.
|
||||||
|
#app_binary_name: {{project-name}}
|
||||||
|
|
||||||
|
# The name of the `.zip` or `.dmg` file produced by this workflow.
|
||||||
|
# Defaults to `app_binary_name` if commented out.
|
||||||
|
#app_package_name: {{project-name | kebab_case}}
|
||||||
|
|
||||||
|
# The display name of the app produced by this workflow.
|
||||||
|
# Applies to macOS releases.
|
||||||
|
# Defaults to `app_package_name` if commented out.
|
||||||
|
#app_display_name: {{project-name | title_case}}
|
||||||
|
|
||||||
|
# The short display name of the app produced by this workflow.
|
||||||
|
# Applies to macOS releases.
|
||||||
|
# Must be 15 or fewer characters: <https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundlename>.
|
||||||
|
# Defaults to `app_display_name` if commented out.
|
||||||
|
#app_short_name: {{project-name | title_case | truncate: 15, "…"}}
|
||||||
|
|
||||||
|
# Before enabling LFS, please take a look at GitHub's documentation for costs and quota limits:
|
||||||
|
# <https://docs.github.com/en/repositories/working-with-files/managing-large-files/about-storage-and-bandwidth-usage>
|
||||||
|
git_lfs: false
|
||||||
|
|
||||||
|
# Enabling this only helps with consecutive releases to the same tag (and takes up cache storage space).
|
||||||
|
# See: <https://github.com/orgs/community/discussions/27059>.
|
||||||
|
use_github_cache: false
|
||||||
|
|
||||||
|
# Reduce compile time.
|
||||||
|
RUSTFLAGS: -Dwarnings -Zshare-generics=y -Zthreads=0
|
||||||
|
|
||||||
|
{% raw -%}
|
||||||
|
jobs:
|
||||||
|
# Forward some environment variables as outputs of this job.
|
||||||
|
# This is needed because the `env` context can't be used in the `if:` condition of a job:
|
||||||
|
# <https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability>
|
||||||
|
forward-env:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Do nothing
|
||||||
|
run: "true"
|
||||||
|
outputs:
|
||||||
|
upload_to_itch: ${{ env.upload_to_itch }}
|
||||||
|
|
||||||
|
# Determine the version number for this workflow.
|
||||||
|
get-version:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Determine version number
|
||||||
|
id: tag
|
||||||
|
run: echo "tag=${GITHUB_REF#refs/tags/}" >> "${GITHUB_OUTPUT}"
|
||||||
|
outputs:
|
||||||
|
# Use the input from workflow dispatch, or fall back to the git tag.
|
||||||
|
version: ${{ inputs.version || steps.tag.outputs.tag }}
|
||||||
|
|
||||||
|
# Build and package a release for each platform.
|
||||||
|
build:
|
||||||
|
needs:
|
||||||
|
- get-version
|
||||||
|
env:
|
||||||
|
version: ${{ needs.get-version.outputs.version }}
|
||||||
|
# Avoid rate-limiting. See: <https://github.com/cargo-bins/cargo-binstall/issues/2045>.
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- platform: web
|
||||||
|
targets: wasm32-unknown-unknown
|
||||||
|
package_ext: .zip
|
||||||
|
runner: ubuntu-latest
|
||||||
|
|
||||||
|
- platform: linux
|
||||||
|
targets: x86_64-unknown-linux-gnu
|
||||||
|
package_ext: .zip
|
||||||
|
runner: ubuntu-latest
|
||||||
|
|
||||||
|
- platform: windows
|
||||||
|
targets: x86_64-pc-windows-msvc
|
||||||
|
binary_ext: .exe
|
||||||
|
package_ext: .zip
|
||||||
|
runner: windows-latest
|
||||||
|
|
||||||
|
- platform: macos
|
||||||
|
targets: x86_64-apple-darwin aarch64-apple-darwin
|
||||||
|
app_suffix: .app/Contents/MacOS
|
||||||
|
package_ext: .dmg
|
||||||
|
runner: macos-latest
|
||||||
|
runs-on: ${{ matrix.runner }}
|
||||||
|
permissions:
|
||||||
|
# Required to create a GitHub release: <https://docs.github.com/en/rest/releases/releases#create-a-release>.
|
||||||
|
contents: write
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up environment
|
||||||
|
run: |
|
||||||
|
# Default values:
|
||||||
|
echo "app_binary_name=${app_binary_name:=${{ env.cargo_build_binary_name }}}" >> "${GITHUB_ENV}"
|
||||||
|
echo "app_package_name=${app_package_name:=${app_binary_name}}" >> "${GITHUB_ENV}"
|
||||||
|
echo "app_display_name=${app_display_name:=${app_package_name}}" >> "${GITHUB_ENV}"
|
||||||
|
echo "app_short_name=${app_short_name:=${app_display_name}}" >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
|
# File paths:
|
||||||
|
echo "app=tmp/app/${app_package_name}"'${{ matrix.app_suffix }}' >> "${GITHUB_ENV}"
|
||||||
|
echo "package=${app_package_name}-"'${{ matrix.platform }}${{ matrix.package_ext }}' >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
|
# macOS environment:
|
||||||
|
if [ '${{ matrix.platform }}' = 'macos' ]; then
|
||||||
|
echo 'MACOSX_DEPLOYMENT_TARGET=11.0' >> "${GITHUB_ENV}" # macOS 11.0 Big Sur is the first version to support universal binaries.
|
||||||
|
echo "SDKROOT=$(xcrun --sdk macosx --show-sdk-path)" >> "${GITHUB_ENV}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if building for this platform is enabled.
|
||||||
|
echo 'is_platform_enabled=${{
|
||||||
|
(matrix.platform == 'web' && env.build_for_web == 'true') ||
|
||||||
|
(matrix.platform == 'linux' && env.build_for_linux == 'true') ||
|
||||||
|
(matrix.platform == 'windows' && env.build_for_windows == 'true') ||
|
||||||
|
(matrix.platform == 'macos' && env.build_for_macos == 'true')
|
||||||
|
}}' >> "${GITHUB_ENV}"
|
||||||
|
|
||||||
|
- name: Checkout repository
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
lfs: ${{ env.git_lfs }}
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
uses: dtolnay/rust-toolchain@nightly
|
||||||
|
with:
|
||||||
|
targets: ${{ matrix.targets }}
|
||||||
|
|
||||||
|
- name: Restore Rust cache
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && env.use_github_cache == 'true' }}
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
shared-key: release
|
||||||
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
|
- name: Install build dependencies (Linux)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'linux' }}
|
||||||
|
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev
|
||||||
|
|
||||||
|
- name: Prepare output directories
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
run: rm -rf tmp; mkdir -p tmp/binary '${{ env.app }}'
|
||||||
|
|
||||||
|
- name: Install cargo-binstall
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
uses: cargo-bins/cargo-binstall@main
|
||||||
|
|
||||||
|
- name: Install Bevy CLI
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
run: cargo binstall --locked --no-confirm --force --git='https://github.com/TheBevyFlock/bevy_cli' bevy_cli
|
||||||
|
|
||||||
|
- name: Build and add web bundle to app (Web)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'web' }}
|
||||||
|
run: |
|
||||||
|
cargo binstall --locked --no-confirm --force wasm-bindgen-cli
|
||||||
|
cargo binstall --locked --no-confirm --force wasm-opt
|
||||||
|
bevy build --locked --release --features='${{ matrix.features }}' --yes web --bundle
|
||||||
|
mv 'target/bevy_web/web-release/${{ env.cargo_build_binary_name }}' '${{ env.app }}'
|
||||||
|
|
||||||
|
- name: Build and add binaries to app (non-Web)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'web' }}
|
||||||
|
run: |
|
||||||
|
for target in ${{ matrix.targets }}; do
|
||||||
|
bevy build --locked --release --target="${target}" --features='${{ matrix.features }}'
|
||||||
|
mv target/"${target}"/release/'${{ env.cargo_build_binary_name }}${{ matrix.binary_ext }}' tmp/binary/"${target}"'${{ matrix.binary_ext }}'
|
||||||
|
done
|
||||||
|
if [ '${{ matrix.platform }}' = 'macos' ]; then
|
||||||
|
lipo tmp/binary/*'${{ matrix.binary_ext }}' -create -output '${{ env.app }}/${{ env.app_binary_name }}${{ matrix.binary_ext }}'
|
||||||
|
else
|
||||||
|
mv tmp/binary/*'${{ matrix.binary_ext }}' '${{ env.app }}/${{ env.app_binary_name }}${{ matrix.binary_ext }}'
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Add assets to app (non-Web)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'web' }}
|
||||||
|
run: cp -R ./'${{ env.assets_path }}' '${{ env.app }}' || true # Ignore error if assets folder does not exist.
|
||||||
|
|
||||||
|
- name: Add metadata to app (macOS)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'macos' }}
|
||||||
|
run: |
|
||||||
|
cat >'${{ env.app }}/../Info.plist' <<EOF
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>${{ env.app_display_name }}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${{ env.app_binary_name }}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${{ env.app_id }}</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${{ env.app_short_name }}</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${{ env.version }}</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${{ env.version }}</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleSupportedPlatforms</key>
|
||||||
|
<array>
|
||||||
|
<string>MacOSX</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Package app (non-Windows)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform != 'windows' }}
|
||||||
|
working-directory: tmp/app
|
||||||
|
run: |
|
||||||
|
if [ '${{ matrix.platform }}' = 'macos' ]; then
|
||||||
|
ln -s /Applications .
|
||||||
|
hdiutil create -fs HFS+ -volname '${{ env.app_package_name }}' -srcfolder . '${{ env.package }}'
|
||||||
|
else
|
||||||
|
zip --recurse-paths '${{ env.package }}' '${{ env.app_package_name }}'
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Package app (Windows)
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && matrix.platform == 'windows' }}
|
||||||
|
working-directory: tmp/app
|
||||||
|
shell: pwsh
|
||||||
|
run: Compress-Archive -Path '${{ env.app_package_name }}' -DestinationPath '${{ env.package }}'
|
||||||
|
|
||||||
|
- name: Upload package to workflow artifacts
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' }}
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
path: tmp/app/${{ env.package }}
|
||||||
|
name: package-${{ matrix.platform }}
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
|
- name: Upload package to GitHub release
|
||||||
|
if: ${{ env.is_platform_enabled == 'true' && env.upload_to_github == 'true' }}
|
||||||
|
uses: svenstaro/upload-release-action@v2
|
||||||
|
with:
|
||||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
file: tmp/app/${{ env.package }}
|
||||||
|
asset_name: ${{ env.package }}
|
||||||
|
release_name: ${{ env.version }}
|
||||||
|
tag: ${{ env.version }}
|
||||||
|
overwrite: true
|
||||||
|
|
||||||
|
# Upload all packages to itch.io.
|
||||||
|
upload-to-itch:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- forward-env
|
||||||
|
- get-version
|
||||||
|
- build
|
||||||
|
if: ${{ needs.forward-env.outputs.upload_to_itch != '' }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Download all packages
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: package-*
|
||||||
|
path: tmp
|
||||||
|
|
||||||
|
- name: Install butler
|
||||||
|
run: |
|
||||||
|
curl -L -o butler.zip 'https://broth.itch.zone/butler/linux-amd64/LATEST/archive/default'
|
||||||
|
unzip butler.zip
|
||||||
|
chmod +x butler
|
||||||
|
./butler -V
|
||||||
|
|
||||||
|
- name: Upload all packages to itch.io
|
||||||
|
env:
|
||||||
|
BUTLER_API_KEY: ${{ secrets.BUTLER_CREDENTIALS }}
|
||||||
|
run: |
|
||||||
|
for channel in $(ls tmp); do
|
||||||
|
./butler push \
|
||||||
|
--fix-permissions \
|
||||||
|
--userversion='${{ needs.get-version.outputs.version }}' \
|
||||||
|
tmp/"${channel}"/* \
|
||||||
|
'${{ env.upload_to_itch }}':"${channel#package-}"
|
||||||
|
done
|
||||||
|
{%- endraw %}
|
||||||
24
.github/workflows/rust.yml
vendored
24
.github/workflows/rust.yml
vendored
@@ -1,24 +0,0 @@
|
|||||||
name: Rust
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "master" ]
|
|
||||||
|
|
||||||
env:
|
|
||||||
CARGO_TERM_COLOR: always
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Install deps
|
|
||||||
run: sudo apt install libasound2-dev libudev-dev
|
|
||||||
- name: Build
|
|
||||||
run: cargo build
|
|
||||||
- name: Run tests
|
|
||||||
run: cargo test
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
# Phos
|
# Phos
|
||||||
|
|
||||||
You play as a robot colonizer that has been sent out to an alien planet with one goal. Harvest its resources and send them back home. To accomplish this you must build a base on the planet. As your base develops you will be able to build more advanced structures to harvest at an increased scale. And eventually you will be able to accomplish your goal of sending resources back to your mother planet. But your invasion wont go unchallenged. The native inhabitants of the planet won’t sit idly by as you strip their world of its resources.
|
You play as a robot colonizer that has been sent out to an alien planet with one goal. Harvest its resources and send them back home. To accomplish this you must build a base on the planet. As your base develops you will be able to build more advanced structures to harvest at an increased scale. And eventually you will be able to accomplish your goal of sending resources back to your mother planet. But your invasion wont go unchallenged. The native inhabitants of the planet won’t sit idly by as you strip their world of its resources.
|
||||||
|
|
||||||
|

|
||||||
|
|||||||
@@ -103,7 +103,7 @@ impl HexCoord
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_grid_pos(x: usize, z: usize) -> Self
|
pub fn from_offset_pos(x: usize, z: usize) -> Self
|
||||||
{
|
{
|
||||||
return HexCoord::new(x as i32 - (z as i32 / 2), z as i32);
|
return HexCoord::new(x as i32 - (z as i32 / 2), z as i32);
|
||||||
}
|
}
|
||||||
@@ -250,9 +250,9 @@ impl HexCoord
|
|||||||
return (hex * -1).zxy();
|
return (hex * -1).zxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scale(&self, dir: i32, radius: usize) -> HexCoord
|
pub fn scale(&self, dir: usize, radius: usize) -> HexCoord
|
||||||
{
|
{
|
||||||
let s = Self::DIRECTIONS[(dir % 6) as usize] * radius as i32;
|
let s = Self::DIRECTIONS[dir % 6] * radius as i32;
|
||||||
return Self::from_axial(self.hex.xy() + s.xy());
|
return Self::from_axial(self.hex.xy() + s.xy());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,9 @@ use super::prelude::*;
|
|||||||
#[test]
|
#[test]
|
||||||
fn create_coord()
|
fn create_coord()
|
||||||
{
|
{
|
||||||
let coord = HexCoord::from_grid_pos(3, 3);
|
let center = HexCoord::from_offset_pos(3, 3);
|
||||||
|
for dir in 0..6
|
||||||
|
{
|
||||||
|
assert_eq!(center.get_neighbor(dir).get_neighbor(dir), center.scale(dir, 2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ pub fn generate_chunk_collider(chunk: &MeshChunkData) -> (Vec<Vec3>, Vec<[u32; 3
|
|||||||
for x in 0..Chunk::SIZE
|
for x in 0..Chunk::SIZE
|
||||||
{
|
{
|
||||||
let height = chunk.heights[x + z * Chunk::SIZE];
|
let height = chunk.heights[x + z * Chunk::SIZE];
|
||||||
let coord = HexCoord::from_grid_pos(x, z);
|
let coord = HexCoord::from_offset_pos(x, z);
|
||||||
let neighbors = chunk.get_neighbors(&coord);
|
let neighbors = chunk.get_neighbors(&coord);
|
||||||
let off_pos = Vec3::new(x as f32, height, z as f32);
|
let off_pos = Vec3::new(x as f32, height, z as f32);
|
||||||
let tile_pos = offset3d_to_world(off_pos);
|
let tile_pos = offset3d_to_world(off_pos);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ pub fn generate_chunk_mesh(chunk: &MeshChunkData) -> Mesh
|
|||||||
let height = chunk.heights[idx];
|
let height = chunk.heights[idx];
|
||||||
let off_pos = Vec3::new(x as f32, height, z as f32);
|
let off_pos = Vec3::new(x as f32, height, z as f32);
|
||||||
let tile_pos = offset3d_to_world(off_pos);
|
let tile_pos = offset3d_to_world(off_pos);
|
||||||
let coord = HexCoord::from_grid_pos(x, z);
|
let coord = HexCoord::from_offset_pos(x, z);
|
||||||
let n = chunk.get_neighbors(&coord);
|
let n = chunk.get_neighbors(&coord);
|
||||||
|
|
||||||
create_tile(
|
create_tile(
|
||||||
@@ -121,7 +121,7 @@ pub fn generate_chunk_water_mesh(chunk: &MeshChunkData, sealevel: f32, map_width
|
|||||||
}
|
}
|
||||||
let off_pos = Vec3::new(x as f32, sealevel, z as f32);
|
let off_pos = Vec3::new(x as f32, sealevel, z as f32);
|
||||||
let tile_pos = offset3d_to_world(off_pos);
|
let tile_pos = offset3d_to_world(off_pos);
|
||||||
let coord = HexCoord::from_grid_pos(x, z);
|
let coord = HexCoord::from_offset_pos(x, z);
|
||||||
let (n, neighbor_has_land) = chunk.get_neighbors_with_water_info(&coord);
|
let (n, neighbor_has_land) = chunk.get_neighbors_with_water_info(&coord);
|
||||||
|
|
||||||
create_tile_water_surface(
|
create_tile_water_surface(
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pub fn generate_packed_chunk_mesh(chunk: &MeshChunkData) -> Mesh
|
|||||||
{
|
{
|
||||||
let idx = x + z * Chunk::SIZE;
|
let idx = x + z * Chunk::SIZE;
|
||||||
let height = chunk.heights[idx];
|
let height = chunk.heights[idx];
|
||||||
let coord = HexCoord::from_grid_pos(x, z);
|
let coord = HexCoord::from_offset_pos(x, z);
|
||||||
let n = chunk.get_neighbors(&coord);
|
let n = chunk.get_neighbors(&coord);
|
||||||
|
|
||||||
create_packed_tile(
|
create_packed_tile(
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ impl Map
|
|||||||
{
|
{
|
||||||
for x in 0..Chunk::SIZE
|
for x in 0..Chunk::SIZE
|
||||||
{
|
{
|
||||||
let coord = HexCoord::from_grid_pos(x + cx, z + cz);
|
let coord = HexCoord::from_offset_pos(x + cx, z + cz);
|
||||||
let index = coord.to_chunk_local_index();
|
let index = coord.to_chunk_local_index();
|
||||||
|
|
||||||
if !self.is_in_bounds(&coord)
|
if !self.is_in_bounds(&coord)
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ pub fn render_map(map: &Map, smooth: f32) -> ImageBuffer<image::Rgba<u8>, Vec<u8
|
|||||||
pub fn update_map(map: &Map, smooth: f32, image: &mut ImageBuffer<image::Rgba<u8>, Vec<u8>>)
|
pub fn update_map(map: &Map, smooth: f32, image: &mut ImageBuffer<image::Rgba<u8>, Vec<u8>>)
|
||||||
{
|
{
|
||||||
image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
|
image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
|
||||||
let coord = HexCoord::from_grid_pos(x as usize, y as usize);
|
let coord = HexCoord::from_offset_pos(x as usize, y as usize);
|
||||||
let right = coord.get_neighbor(1);
|
let right = coord.get_neighbor(1);
|
||||||
let height = map.sample_height(&coord);
|
let height = map.sample_height(&coord);
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ pub fn update_biome_map(map: &Map, biome_map: &BiomeMap, image: &mut ImageBuffer
|
|||||||
{
|
{
|
||||||
let map_biome_count = map.biome_count as f32;
|
let map_biome_count = map.biome_count as f32;
|
||||||
image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
|
image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
|
||||||
let coord = HexCoord::from_grid_pos(x as usize, y as usize);
|
let coord = HexCoord::from_offset_pos(x as usize, y as usize);
|
||||||
let biome_blend = biome_map.get_biome(x as i32, y as i32).unwrap();
|
let biome_blend = biome_map.get_biome(x as i32, y as i32).unwrap();
|
||||||
let right = coord.get_neighbor(1);
|
let right = coord.get_neighbor(1);
|
||||||
let mut color = Oklaba::BLACK;
|
let mut color = Oklaba::BLACK;
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ impl MeshChunkData
|
|||||||
{
|
{
|
||||||
for x in 0..Chunk::SIZE
|
for x in 0..Chunk::SIZE
|
||||||
{
|
{
|
||||||
let coord = HexCoord::from_grid_pos(x + offset_x, z + offset_z);
|
let coord = HexCoord::from_offset_pos(x + offset_x, z + offset_z);
|
||||||
let idx = coord.to_chunk_local_index();
|
let idx = coord.to_chunk_local_index();
|
||||||
let h = self.heights[idx];
|
let h = self.heights[idx];
|
||||||
self.distance_to_land[idx] = if h > self.sealevel { 0.0 } else { 4.0 };
|
self.distance_to_land[idx] = if h > self.sealevel { 0.0 } else { 4.0 };
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
use asset_loader::create_asset_loader;
|
use asset_loader::create_asset_loader;
|
||||||
use bevy::{
|
use bevy::{
|
||||||
|
ecs::relationship::RelatedSpawnerCommands,
|
||||||
gltf::{GltfMesh, GltfNode},
|
gltf::{GltfMesh, GltfNode},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use shared::identifiers::ResourceIdentifier;
|
use shared::{component_defination::ComponentDefination, identifiers::ResourceIdentifier};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
buildings::{
|
buildings::{
|
||||||
conduit_building::ResourceConduitInfo, factory_building::FactoryBuildingInfo,
|
basic_building::BasicBuildingInfo, conduit_building::ResourceConduitInfo,
|
||||||
resource_gathering::ResourceGatheringBuildingInfo,
|
factory_building::FactoryBuildingInfo, resource_gathering::ResourceGatheringBuildingInfo,
|
||||||
|
tech_building::TechBuildingInfo,
|
||||||
},
|
},
|
||||||
footprint::BuildingFootprint,
|
footprint::BuildingFootprint,
|
||||||
|
prelude::Building,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Asset, TypePath, Debug, Serialize, Deserialize)]
|
#[derive(Asset, TypePath, Debug, Serialize, Deserialize)]
|
||||||
@@ -32,7 +35,7 @@ pub struct BuildingAsset
|
|||||||
pub health: u32,
|
pub health: u32,
|
||||||
|
|
||||||
pub building_type: BuildingType,
|
pub building_type: BuildingType,
|
||||||
// pub components: Option<Vec<ComponentDefination>>,
|
pub components: Option<Vec<ComponentDefination>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuildingAsset
|
impl BuildingAsset
|
||||||
@@ -48,87 +51,101 @@ impl BuildingAsset
|
|||||||
nodes: &Assets<GltfNode>,
|
nodes: &Assets<GltfNode>,
|
||||||
) -> Option<Entity>
|
) -> Option<Entity>
|
||||||
{
|
{
|
||||||
todo!("Update building spawning");
|
let base_node = &gltf.named_nodes[&self.base_mesh_path.clone().into_boxed_str()];
|
||||||
// let base_node = &gltf.named_nodes[&self.base_mesh_path.clone().into_boxed_str()];
|
if let Some(node) = nodes.get(base_node.id()) {
|
||||||
// if let Some(node) = nodes.get(base_node.id()) {
|
if let Some(mesh_handle) = &node.mesh {
|
||||||
// if let Some(mesh_handle) = &node.mesh {
|
if let Some(gltf_mesh) = meshes.get(mesh_handle.id()) {
|
||||||
// if let Some(gltf_mesh) = meshes.get(mesh_handle.id()) {
|
if let Some(primitive) = gltf_mesh.primitives.first() {
|
||||||
// let (mesh, mat) = gltf_mesh.unpack();
|
let mesh = primitive.mesh.clone();
|
||||||
// let mut entity = commands.spawn((
|
let mat = primitive
|
||||||
// Mesh3d(mesh),
|
.material
|
||||||
// MeshMaterial3d(mat),
|
.clone()
|
||||||
// Transform::from_translation(pos).with_rotation(rot),
|
.expect(format!("Mesh '{}' does not have a meterial", primitive.name.as_str()).as_str());
|
||||||
// Building,
|
let mut entity = commands.spawn((
|
||||||
// ));
|
Mesh3d(mesh),
|
||||||
// entity.with_children(|b| {
|
MeshMaterial3d(mat),
|
||||||
// for child in &node.children {
|
Transform::from_translation(pos).with_rotation(rot),
|
||||||
// let child_node = nodes.get(child.id());
|
Building,
|
||||||
// if child_node.is_none() {
|
));
|
||||||
// continue;
|
entity.with_children(|b| {
|
||||||
// }
|
for child in &node.children {
|
||||||
// self.process_node(child_node.unwrap(), meshes, nodes, b, &node.name);
|
let child_node = nodes.get(child.id());
|
||||||
// }
|
if child_node.is_none() {
|
||||||
// });
|
continue;
|
||||||
// if let Some(component) = self.get_component_def(&format!("/{0}", &node.name)) {
|
}
|
||||||
// component.apply(&mut entity);
|
self.process_node(child_node.unwrap(), meshes, nodes, b, &node.name);
|
||||||
// }
|
}
|
||||||
// return Some(entity.id());
|
});
|
||||||
// }
|
if let Some(component) = self.get_component_def(&format!("/{0}", &node.name)) {
|
||||||
// }
|
component.apply(&mut entity);
|
||||||
// }
|
}
|
||||||
// return None;
|
return Some(entity.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn process_node(
|
fn process_node(
|
||||||
// &self,
|
&self,
|
||||||
// node: &GltfNode,
|
node: &GltfNode,
|
||||||
// meshes: &Assets<GltfMesh>,
|
meshes: &Assets<GltfMesh>,
|
||||||
// nodes: &Assets<GltfNode>,
|
nodes: &Assets<GltfNode>,
|
||||||
// commands: &mut ChildBuilder,
|
commands: &mut RelatedSpawnerCommands<ChildOf>,
|
||||||
// parent: &String,
|
parent: &String,
|
||||||
// ) -> Option<Entity> {
|
) -> Option<Entity>
|
||||||
// let path = format!("{0}/{1}", parent, node.name);
|
{
|
||||||
// if let Some(mesh) = &node.mesh {
|
let path = format!("{0}/{1}", parent, node.name);
|
||||||
// if let Some(gltf_mesh) = meshes.get(mesh.id()) {
|
if let Some(mesh) = &node.mesh {
|
||||||
// let (mesh, mat) = gltf_mesh.unpack();
|
if let Some(gltf_mesh) = meshes.get(mesh.id()) {
|
||||||
// let mut entity = commands.spawn((Mesh3d(mesh), MeshMaterial3d(mat), node.transform, Building));
|
if let Some(primitive) = gltf_mesh.primitives.first() {
|
||||||
// entity.with_children(|b| {
|
let mesh = primitive.mesh.clone();
|
||||||
// for child in &node.children {
|
let mat = primitive
|
||||||
// let child_node = nodes.get(child.id());
|
.material
|
||||||
// if child_node.is_none() {
|
.clone()
|
||||||
// continue;
|
.expect(format!("Mesh '{}' does not have a meterial", primitive.name.as_str()).as_str());
|
||||||
// }
|
let mut entity = commands.spawn((Mesh3d(mesh), MeshMaterial3d(mat), node.transform, Building));
|
||||||
// self.process_node(child_node.unwrap(), meshes, nodes, b, &path);
|
entity.with_children(|b| {
|
||||||
// }
|
for child in &node.children {
|
||||||
// });
|
let child_node = nodes.get(child.id());
|
||||||
// if let Some(component) = self.get_component_def(&path) {
|
if child_node.is_none() {
|
||||||
// component.apply(&mut entity);
|
continue;
|
||||||
// }
|
}
|
||||||
// return Some(entity.id());
|
self.process_node(child_node.unwrap(), meshes, nodes, b, &path);
|
||||||
// }
|
}
|
||||||
// }
|
});
|
||||||
// return None;
|
if let Some(component) = self.get_component_def(&path) {
|
||||||
// }
|
component.apply(&mut entity);
|
||||||
|
}
|
||||||
|
return Some(entity.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
// fn get_component_def(&self, path: &String) -> Option<&ComponentDefination> {
|
fn get_component_def(&self, path: &String) -> Option<&ComponentDefination>
|
||||||
// if let Some(components) = &self.components {
|
{
|
||||||
// for c in components {
|
if let Some(components) = &self.components {
|
||||||
// if c.path.ends_with(path) {
|
for c in components {
|
||||||
// return Some(c);
|
if c.path.ends_with(path) {
|
||||||
// }
|
return Some(c);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// return None;
|
}
|
||||||
// }
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, TypePath)]
|
#[derive(Serialize, Deserialize, Debug, TypePath)]
|
||||||
pub enum BuildingType
|
pub enum BuildingType
|
||||||
{
|
{
|
||||||
Basic,
|
Basic(BasicBuildingInfo),
|
||||||
Gathering(ResourceGatheringBuildingInfo),
|
Gathering(ResourceGatheringBuildingInfo),
|
||||||
FactoryBuildingInfo(FactoryBuildingInfo),
|
FactoryBuildingInfo(FactoryBuildingInfo),
|
||||||
ResourceConduit(ResourceConduitInfo),
|
ResourceConduit(ResourceConduitInfo),
|
||||||
|
Tech(TechBuildingInfo),
|
||||||
}
|
}
|
||||||
|
|
||||||
create_asset_loader!(
|
create_asset_loader!(
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct BasicBuildingInfo {}
|
pub struct BasicBuildingInfo
|
||||||
|
{
|
||||||
|
health: u32,
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ hex = { path = "../../engine/hex" }
|
|||||||
# bevy_lunex = "0.2.4"
|
# bevy_lunex = "0.2.4"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
editor = []
|
||||||
tracing = [
|
tracing = [
|
||||||
"bevy/trace_tracy",
|
"bevy/trace_tracy",
|
||||||
"world_generation/tracing",
|
"world_generation/tracing",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use bevy::anti_alias::taa::TemporalAntiAliasing;
|
use bevy::anti_alias::taa::TemporalAntiAliasing;
|
||||||
|
use bevy::camera::visibility::RenderLayers;
|
||||||
use bevy::core_pipeline::prepass::DepthPrepass;
|
use bevy::core_pipeline::prepass::DepthPrepass;
|
||||||
use bevy::input::mouse::{MouseMotion, MouseScrollUnit, MouseWheel};
|
use bevy::input::mouse::{MouseMotion, MouseScrollUnit, MouseWheel};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
@@ -53,10 +54,8 @@ fn setup(mut commands: Commands)
|
|||||||
PhosOrbitCamera::default(),
|
PhosOrbitCamera::default(),
|
||||||
TemporalAntiAliasing::default(),
|
TemporalAntiAliasing::default(),
|
||||||
))
|
))
|
||||||
.insert(Msaa::Off);
|
.insert(Msaa::Off)
|
||||||
// .insert(RenderLayers::layer(0))
|
.insert(RenderLayers::default());
|
||||||
|
|
||||||
// *msaa = Msaa::Off;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn orbit_camera_upate(
|
fn orbit_camera_upate(
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use crate::camera_system::components::PhosCamera;
|
|||||||
use crate::map_rendering::map_init::MapInitPlugin;
|
use crate::map_rendering::map_init::MapInitPlugin;
|
||||||
use crate::map_rendering::render_distance_system::RenderDistancePlugin;
|
use crate::map_rendering::render_distance_system::RenderDistancePlugin;
|
||||||
use crate::ui::build_ui::BuildUIPlugin;
|
use crate::ui::build_ui::BuildUIPlugin;
|
||||||
use crate::utlis::editor_plugin::EditorPlugin;
|
|
||||||
use crate::utlis::tile_selection_plugin::TileSelectionPlugin;
|
use crate::utlis::tile_selection_plugin::TileSelectionPlugin;
|
||||||
use crate::{camera_system::camera_plugin::PhosCameraPlugin, utlis::debug_plugin::DebugPlugin};
|
use crate::{camera_system::camera_plugin::PhosCameraPlugin, utlis::debug_plugin::DebugPlugin};
|
||||||
use bevy::diagnostic::{EntityCountDiagnosticsPlugin, FrameTimeDiagnosticsPlugin};
|
use bevy::diagnostic::{EntityCountDiagnosticsPlugin, FrameTimeDiagnosticsPlugin};
|
||||||
@@ -12,13 +11,9 @@ use bevy_asset_loader::prelude::*;
|
|||||||
use bevy_rapier3d::dynamics::{Ccd, RigidBody, Velocity};
|
use bevy_rapier3d::dynamics::{Ccd, RigidBody, Velocity};
|
||||||
use bevy_rapier3d::geometry::Collider;
|
use bevy_rapier3d::geometry::Collider;
|
||||||
use bevy_rapier3d::plugin::{NoUserData, RapierPhysicsPlugin};
|
use bevy_rapier3d::plugin::{NoUserData, RapierPhysicsPlugin};
|
||||||
// use buildings::BuildingPugin;
|
|
||||||
// use iyes_perf_ui::prelude::*;
|
|
||||||
// use shared::animation_plugin::SimpleAnimationPlugin;
|
|
||||||
use shared::sets::GameplaySet;
|
use shared::sets::GameplaySet;
|
||||||
use shared::states::{GameplayState, MenuState};
|
use shared::states::{GameplayState, MenuState};
|
||||||
use shared::{despawn::DespawnPuglin, states::AssetLoadState};
|
use shared::{despawn::DespawnPuglin, states::AssetLoadState};
|
||||||
// use units::units_plugin::UnitsPlugin;
|
|
||||||
use world_generation::states::GeneratorState;
|
use world_generation::states::GeneratorState;
|
||||||
|
|
||||||
pub struct PhosGamePlugin;
|
pub struct PhosGamePlugin;
|
||||||
@@ -45,8 +40,8 @@ impl Plugin for PhosGamePlugin
|
|||||||
// UnitsPlugin,
|
// UnitsPlugin,
|
||||||
DespawnPuglin,
|
DespawnPuglin,
|
||||||
TileSelectionPlugin,
|
TileSelectionPlugin,
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(feature = "editor")]
|
||||||
EditorPlugin,
|
crate::utlis::editor_plugin::EditorPlugin,
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
DebugPlugin,
|
DebugPlugin,
|
||||||
));
|
));
|
||||||
@@ -146,8 +141,7 @@ fn spawn_sphere(
|
|||||||
mat: Res<SphereMat>,
|
mat: Res<SphereMat>,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if keyboard_input.just_pressed(KeyCode::KeyF)
|
if keyboard_input.just_pressed(KeyCode::KeyF) {
|
||||||
{
|
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Mesh3d(meshes.add(Sphere::new(0.3))),
|
Mesh3d(meshes.add(Sphere::new(0.3))),
|
||||||
MeshMaterial3d(mat.0.clone()),
|
MeshMaterial3d(mat.0.clone()),
|
||||||
|
|||||||
@@ -1,39 +1,223 @@
|
|||||||
use bevy::{camera::visibility::RenderLayers, prelude::*};
|
use bevy::{
|
||||||
|
camera::{visibility::RenderLayers, CameraOutputMode},
|
||||||
|
prelude::*,
|
||||||
|
render::render_resource::BlendState,
|
||||||
|
};
|
||||||
use shared::states::AssetLoadState;
|
use shared::states::AssetLoadState;
|
||||||
|
|
||||||
|
use crate::ui::states::BuildUIState;
|
||||||
pub struct BuildUIPlugin;
|
pub struct BuildUIPlugin;
|
||||||
|
|
||||||
|
#[derive(Component, Default)]
|
||||||
|
struct BuildUIItem;
|
||||||
|
|
||||||
|
#[derive(Component, Default)]
|
||||||
|
#[require(BuildUIItem)]
|
||||||
|
struct BuildUIMenuItem;
|
||||||
|
|
||||||
|
#[derive(Component, Default)]
|
||||||
|
struct BuildMenuRoot;
|
||||||
|
|
||||||
|
#[derive(Resource, Reflect, Debug, Default)]
|
||||||
|
struct BuildUIInfo
|
||||||
|
{
|
||||||
|
menu: BuildUIMenu,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Reflect, Debug)]
|
||||||
|
enum BuildUIMenu
|
||||||
|
{
|
||||||
|
#[default]
|
||||||
|
Structure,
|
||||||
|
Defense,
|
||||||
|
}
|
||||||
|
|
||||||
impl Plugin for BuildUIPlugin
|
impl Plugin for BuildUIPlugin
|
||||||
{
|
{
|
||||||
fn build(&self, app: &mut App)
|
fn build(&self, app: &mut App)
|
||||||
{
|
{
|
||||||
app.add_systems(Startup, setup_cameras);
|
app.add_systems(Startup, setup_cameras);
|
||||||
app.add_systems(Update, spawn_ui.run_if(in_state(AssetLoadState::LoadComplete)));
|
app.init_resource::<BuildUIInfo>();
|
||||||
|
app.insert_state(BuildUIState::Init);
|
||||||
|
app.add_systems(
|
||||||
|
Update,
|
||||||
|
(
|
||||||
|
spawn_ui.run_if(in_state(AssetLoadState::LoadComplete).and(in_state(BuildUIState::Init))),
|
||||||
|
draw_menu_ui.run_if(in_state(AssetLoadState::LoadComplete).and(in_state(BuildUIState::DrawMenu))),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
app.add_systems(PostUpdate, cleanup_ui.run_if(in_state(BuildUIState::Cleanup)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_cameras(mut commands: Commands)
|
fn setup_cameras(mut commands: Commands)
|
||||||
{
|
{
|
||||||
commands.spawn((Camera2d, IsDefaultUiCamera, RenderLayers::layer(2)));
|
commands
|
||||||
|
.spawn((
|
||||||
|
Camera2d,
|
||||||
|
Camera {
|
||||||
|
order: 1,
|
||||||
|
clear_color: ClearColorConfig::None,
|
||||||
|
msaa_writeback: MsaaWriteback::Always,
|
||||||
|
output_mode: CameraOutputMode::Write {
|
||||||
|
blend_state: Some(BlendState::ALPHA_BLENDING),
|
||||||
|
clear_color: ClearColorConfig::None,
|
||||||
|
},
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
IsDefaultUiCamera,
|
||||||
|
))
|
||||||
|
.insert(RenderLayers::layer(1))
|
||||||
|
.insert(Msaa::Off);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_ui(mut commands: Commands)
|
fn spawn_ui(mut commands: Commands, mut next_state: ResMut<NextState<BuildUIState>>)
|
||||||
{
|
{
|
||||||
commands
|
commands
|
||||||
.spawn((Node {
|
.spawn((
|
||||||
|
Node {
|
||||||
width: Val::Percent(100.),
|
width: Val::Percent(100.),
|
||||||
height: Val::Percent(100.),
|
height: Val::Percent(100.),
|
||||||
justify_content: JustifyContent::Center,
|
justify_content: JustifyContent::Center,
|
||||||
align_items: AlignItems::End,
|
align_items: AlignItems::End,
|
||||||
..default()
|
..default()
|
||||||
},))
|
},
|
||||||
|
RenderLayers::layer(1),
|
||||||
|
Name::new("Build UI Root"),
|
||||||
|
BuildUIItem,
|
||||||
|
))
|
||||||
// .insert(PickingBehavior::IGNORE)
|
// .insert(PickingBehavior::IGNORE)
|
||||||
.with_children(|parent| {
|
.with_children(|build_root| {
|
||||||
parent.spawn((
|
build_root
|
||||||
|
.spawn((
|
||||||
|
Name::new("Build UI"),
|
||||||
Node {
|
Node {
|
||||||
width: Val::Px(500.),
|
width: Val::Px(500.),
|
||||||
..Default::default()
|
height: Val::Px(100.),
|
||||||
|
justify_content: JustifyContent::Stretch,
|
||||||
|
flex_direction: FlexDirection::Column,
|
||||||
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(LinearRgba::GREEN.into()),
|
BackgroundColor(LinearRgba::GREEN.into()),
|
||||||
|
))
|
||||||
|
.with_children(|build_ui| {
|
||||||
|
build_ui.spawn((
|
||||||
|
Name::new("Menu Root"),
|
||||||
|
BuildMenuRoot,
|
||||||
|
Node {
|
||||||
|
width: Val::Percent(100.),
|
||||||
|
height: Val::Px(70.),
|
||||||
|
column_gap: Val::Px(5.),
|
||||||
|
padding: UiRect::all(Val::Px(2.)),
|
||||||
|
flex_direction: FlexDirection::Row,
|
||||||
|
overflow: Overflow::scroll_x(),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
));
|
));
|
||||||
|
build_ui
|
||||||
|
.spawn((
|
||||||
|
Name::new("Toolbar"),
|
||||||
|
Node {
|
||||||
|
width: Val::Percent(100.),
|
||||||
|
height: Val::Px(30.),
|
||||||
|
column_gap: Val::Px(5.),
|
||||||
|
padding: UiRect::horizontal(Val::Px(10.)),
|
||||||
|
justify_content: JustifyContent::Stretch,
|
||||||
|
align_self: AlignSelf::End,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
BackgroundColor(LinearRgba::BLUE.into()),
|
||||||
|
))
|
||||||
|
.with_children(|toolbar| {
|
||||||
|
for i in 0..6
|
||||||
|
{
|
||||||
|
toolbar.spawn((
|
||||||
|
Name::new(format!("Button {}", i)),
|
||||||
|
Button,
|
||||||
|
Node {
|
||||||
|
height: Val::Percent(100.),
|
||||||
|
width: Val::Percent(100.),
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
BackgroundColor(LinearRgba::WHITE.into()),
|
||||||
|
children![(
|
||||||
|
Text::new(format!("Button {}", i)),
|
||||||
|
TextFont {
|
||||||
|
font_size: 15.,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
TextColor(LinearRgba::BLACK.into()),
|
||||||
|
TextShadow {
|
||||||
|
offset: Vec2::splat(2.),
|
||||||
|
..default()
|
||||||
|
}
|
||||||
|
)],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
next_state.set(BuildUIState::DrawMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_menu_ui(
|
||||||
|
mut commands: Commands,
|
||||||
|
menu_root: Single<Entity, With<BuildMenuRoot>>,
|
||||||
|
menu_items: Query<Entity, With<BuildUIMenuItem>>,
|
||||||
|
menu_info: Res<BuildUIInfo>,
|
||||||
|
mut next: ResMut<NextState<BuildUIState>>,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for entity in menu_items.iter()
|
||||||
|
{
|
||||||
|
commands.entity(entity).despawn();
|
||||||
|
}
|
||||||
|
info!("Draw Menu");
|
||||||
|
match menu_info.menu
|
||||||
|
{
|
||||||
|
BuildUIMenu::Structure => draw_structure_ui(commands, menu_root.into_inner()),
|
||||||
|
BuildUIMenu::Defense => (),
|
||||||
|
}
|
||||||
|
next.set(BuildUIState::Update);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_structure_ui(mut commands: Commands, root: Entity)
|
||||||
|
{
|
||||||
|
commands.entity(root).with_children(|root| {
|
||||||
|
for i in 0..10
|
||||||
|
{
|
||||||
|
root.spawn((
|
||||||
|
BuildUIMenuItem,
|
||||||
|
Node {
|
||||||
|
height: Val::Percent(100.),
|
||||||
|
width: Val::Px(100.),
|
||||||
|
display: Display::Grid,
|
||||||
|
grid_template_rows: vec![RepeatedGridTrack::px(1, 100.), RepeatedGridTrack::fr(1, 1.)],
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
children![
|
||||||
|
(
|
||||||
|
Node {
|
||||||
|
height: Val::Px(100.),
|
||||||
|
width: Val::Px(100.),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
BackgroundColor(LinearRgba::RED.into())
|
||||||
|
),
|
||||||
|
(Text::new(format!("Icon {}", i))),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cleanup_ui(mut commands: Commands, ui_items: Query<Entity, With<BuildUIItem>>)
|
||||||
|
{
|
||||||
|
for entity in ui_items.iter()
|
||||||
|
{
|
||||||
|
commands.entity(entity).despawn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
pub mod build_ui;
|
pub mod build_ui;
|
||||||
|
pub mod states;
|
||||||
|
|||||||
10
game/main/src/ui/states.rs
Normal file
10
game/main/src/ui/states.rs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
#[derive(States, Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum BuildUIState
|
||||||
|
{
|
||||||
|
Init,
|
||||||
|
DrawMenu,
|
||||||
|
Update,
|
||||||
|
Cleanup,
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
use bevy::asset::RenderAssetUsages;
|
use bevy::asset::RenderAssetUsages;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_inspector_egui::bevy_egui::EguiContexts;
|
use bevy_inspector_egui::bevy_egui::{EguiContexts, EguiTextureHandle};
|
||||||
use bevy_inspector_egui::egui::{self};
|
use bevy_inspector_egui::egui::{self};
|
||||||
use image::{ImageBuffer, Rgba};
|
use image::{ImageBuffer, Rgba};
|
||||||
use world_generation::biome_asset::BiomeAsset;
|
use world_generation::biome_asset::BiomeAsset;
|
||||||
@@ -92,14 +92,14 @@ fn asset_reloaded(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render_map_ui(
|
fn render_map_ui(
|
||||||
// image: Res<MapImage>,
|
image: Res<MapImage>,
|
||||||
heightmap: Res<Map>,
|
heightmap: Res<Map>,
|
||||||
biome_map: Res<BiomeMap>,
|
biome_map: Res<BiomeMap>,
|
||||||
mut contexts: EguiContexts,
|
mut contexts: EguiContexts,
|
||||||
mut state: ResMut<UIState>,
|
mut state: ResMut<UIState>,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// let id = contexts.add_image(image.0.);
|
let id = contexts.add_image(EguiTextureHandle::Weak(image.0.id()));
|
||||||
let mut map_type = state.target_map_type;
|
let mut map_type = state.target_map_type;
|
||||||
let ctx = contexts.ctx_mut().expect("Failed to get egui context");
|
let ctx = contexts.ctx_mut().expect("Failed to get egui context");
|
||||||
egui::Window::new("Map").open(&mut state.is_open).show(ctx, |ui| {
|
egui::Window::new("Map").open(&mut state.is_open).show(ctx, |ui| {
|
||||||
@@ -127,10 +127,10 @@ fn render_map_ui(
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ui.add(egui::widgets::Image::new(egui::load::SizedTexture::new(
|
ui.add(egui::widgets::Image::new(egui::load::SizedTexture::new(
|
||||||
// id,
|
id,
|
||||||
// [512.0, 512.0],
|
[512.0, 512.0],
|
||||||
// )));
|
)));
|
||||||
|
|
||||||
if ui.button("Save Image").clicked()
|
if ui.button("Save Image").clicked()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
pub mod chunk_utils;
|
pub mod chunk_utils;
|
||||||
pub mod debug_plugin;
|
pub mod debug_plugin;
|
||||||
|
#[cfg(feature = "editor")]
|
||||||
pub mod editor_plugin;
|
pub mod editor_plugin;
|
||||||
pub mod tile_selection_plugin;
|
pub mod tile_selection_plugin;
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
use bevy::{
|
use bevy::{ecs::system::EntityCommands, prelude::*};
|
||||||
ecs::system::EntityCommands, math::{Quat, Vec3}, prelude::*
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::prefab_defination::AnimationComponent;
|
use crate::prefab_defination::AnimationComponent;
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct ComponentDefination {
|
pub struct ComponentDefination
|
||||||
|
{
|
||||||
pub path: String,
|
pub path: String,
|
||||||
pub animations: Vec<AnimationComponent>,
|
pub animations: Vec<AnimationComponent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ComponentDefination
|
||||||
impl ComponentDefination {
|
{
|
||||||
pub fn apply(&self, commands: &mut EntityCommands){
|
pub fn apply(&self, commands: &mut EntityCommands)
|
||||||
|
{
|
||||||
for c in &self.animations {
|
for c in &self.animations {
|
||||||
c.apply(commands);
|
c.apply(commands);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
use bevy::reflect::Reflect;
|
use bevy::reflect::Reflect;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub mod animation_plugin;
|
||||||
pub mod building;
|
pub mod building;
|
||||||
|
pub mod component_defination;
|
||||||
pub mod coords;
|
pub mod coords;
|
||||||
pub mod despawn;
|
pub mod despawn;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
pub mod identifiers;
|
pub mod identifiers;
|
||||||
|
pub mod prefab_defination;
|
||||||
pub mod resources;
|
pub mod resources;
|
||||||
pub mod sets;
|
pub mod sets;
|
||||||
pub mod states;
|
pub mod states;
|
||||||
pub mod tags;
|
pub mod tags;
|
||||||
// pub mod prefab_defination;
|
|
||||||
// pub mod animation_plugin;
|
|
||||||
// pub mod component_defination;
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub enum Tier
|
pub enum Tier
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
use bevy::{
|
use bevy::{
|
||||||
ecs::system::{EntityCommand, EntityCommands},
|
ecs::{relationship::RelatedSpawnerCommands, system::EntityCommands},
|
||||||
gltf::{Gltf, GltfMesh},
|
gltf::{Gltf, GltfMesh},
|
||||||
math::{Quat, Vec3},
|
math::{Quat, Vec3},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct PrefabDefination {
|
pub struct PrefabDefination
|
||||||
|
{
|
||||||
pub path: String,
|
pub path: String,
|
||||||
pub pos: Vec3,
|
pub pos: Vec3,
|
||||||
pub rot: Vec3,
|
pub rot: Vec3,
|
||||||
@@ -14,13 +15,25 @@ pub struct PrefabDefination {
|
|||||||
pub animations: Option<Vec<AnimationComponent>>,
|
pub animations: Option<Vec<AnimationComponent>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrefabDefination {
|
impl PrefabDefination
|
||||||
pub fn spawn_recursive(&self, gltf: &Gltf, commands: &mut ChildBuilder, meshes: &Assets<GltfMesh>) {
|
{
|
||||||
|
pub fn spawn_recursive(
|
||||||
|
&self,
|
||||||
|
gltf: &Gltf,
|
||||||
|
commands: &mut RelatedSpawnerCommands<ChildOf>,
|
||||||
|
meshes: &Assets<GltfMesh>,
|
||||||
|
)
|
||||||
|
{
|
||||||
let mesh_handle = &gltf.named_meshes[&self.path.clone().into_boxed_str()];
|
let mesh_handle = &gltf.named_meshes[&self.path.clone().into_boxed_str()];
|
||||||
if let Some(gltf_mesh) = meshes.get(mesh_handle.id()) {
|
if let Some(gltf_mesh) = meshes.get(mesh_handle.id()) {
|
||||||
let (m, mat) = gltf_mesh.unpack();
|
if let Some(primitive) = gltf_mesh.primitives.first() {
|
||||||
|
let mesh = primitive.mesh.clone();
|
||||||
|
let mat = primitive
|
||||||
|
.material
|
||||||
|
.clone()
|
||||||
|
.expect(format!("Mesh '{}' does not have a meterial", primitive.name.as_str()).as_str());
|
||||||
let mut entity = commands.spawn((
|
let mut entity = commands.spawn((
|
||||||
Mesh3d(m),
|
Mesh3d(mesh),
|
||||||
MeshMaterial3d(mat),
|
MeshMaterial3d(mat),
|
||||||
Transform::from_translation(self.pos).with_rotation(Quat::from_euler(
|
Transform::from_translation(self.pos).with_rotation(Quat::from_euler(
|
||||||
bevy::math::EulerRot::XYZ,
|
bevy::math::EulerRot::XYZ,
|
||||||
@@ -38,14 +51,18 @@ impl PrefabDefination {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait UnpackGltfMesh {
|
pub trait UnpackGltfMesh
|
||||||
|
{
|
||||||
fn unpack(&self) -> (Handle<Mesh>, Handle<StandardMaterial>);
|
fn unpack(&self) -> (Handle<Mesh>, Handle<StandardMaterial>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnpackGltfMesh for GltfMesh {
|
impl UnpackGltfMesh for GltfMesh
|
||||||
fn unpack(&self) -> (Handle<Mesh>, Handle<StandardMaterial>) {
|
{
|
||||||
|
fn unpack(&self) -> (Handle<Mesh>, Handle<StandardMaterial>)
|
||||||
|
{
|
||||||
let p = &self.primitives[0];
|
let p = &self.primitives[0];
|
||||||
let mut mat: Handle<StandardMaterial> = default();
|
let mut mat: Handle<StandardMaterial> = default();
|
||||||
if let Some(mesh_material) = &p.material {
|
if let Some(mesh_material) = &p.material {
|
||||||
@@ -56,19 +73,23 @@ impl UnpackGltfMesh for GltfMesh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub enum AnimationComponent {
|
pub enum AnimationComponent
|
||||||
|
{
|
||||||
Rotation(RotationAnimation),
|
Rotation(RotationAnimation),
|
||||||
Slider,
|
Slider,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Component, Clone, Copy)]
|
#[derive(Serialize, Deserialize, Debug, Component, Clone, Copy)]
|
||||||
pub struct RotationAnimation {
|
pub struct RotationAnimation
|
||||||
|
{
|
||||||
pub axis: Vec3,
|
pub axis: Vec3,
|
||||||
pub speed: f32,
|
pub speed: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnimationComponent {
|
impl AnimationComponent
|
||||||
pub fn apply(&self, commands: &mut EntityCommands) {
|
{
|
||||||
|
pub fn apply(&self, commands: &mut EntityCommands)
|
||||||
|
{
|
||||||
match self {
|
match self {
|
||||||
AnimationComponent::Rotation(comp) => {
|
AnimationComponent::Rotation(comp) => {
|
||||||
commands.insert(comp.clone());
|
commands.insert(comp.clone());
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
#[derive(States, Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(States, Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum MenuState {
|
pub enum MenuState
|
||||||
|
{
|
||||||
Loading,
|
Loading,
|
||||||
Startup,
|
Startup,
|
||||||
MainMenu,
|
MainMenu,
|
||||||
@@ -10,14 +11,16 @@ pub enum MenuState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(States, Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(States, Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum GameplayState {
|
pub enum GameplayState
|
||||||
|
{
|
||||||
Waiting,
|
Waiting,
|
||||||
PlaceHQ,
|
PlaceHQ,
|
||||||
Playing,
|
Playing,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(States, Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(States, Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum AssetLoadState {
|
pub enum AssetLoadState
|
||||||
|
{
|
||||||
Loading,
|
Loading,
|
||||||
FinalizeAssets,
|
FinalizeAssets,
|
||||||
LoadComplete,
|
LoadComplete,
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ impl NavData
|
|||||||
{
|
{
|
||||||
for x in 0..w
|
for x in 0..w
|
||||||
{
|
{
|
||||||
let coord = HexCoord::from_grid_pos(x, y);
|
let coord = HexCoord::from_offset_pos(x, y);
|
||||||
let height = map.sample_height(&coord);
|
let height = map.sample_height(&coord);
|
||||||
let tile = NavTile {
|
let tile = NavTile {
|
||||||
coord,
|
coord,
|
||||||
@@ -83,7 +83,7 @@ impl NavData
|
|||||||
{
|
{
|
||||||
for x in 0..w
|
for x in 0..w
|
||||||
{
|
{
|
||||||
let coord = HexCoord::from_grid_pos(x, y);
|
let coord = HexCoord::from_offset_pos(x, y);
|
||||||
let height = map.sample_height(&coord);
|
let height = map.sample_height(&coord);
|
||||||
let tile = NavTile {
|
let tile = NavTile {
|
||||||
coord,
|
coord,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
hard_tabs = true
|
hard_tabs = true
|
||||||
max_width = 120
|
max_width = 120
|
||||||
brace_style = "AlwaysNextLine"
|
brace_style = "AlwaysNextLine"
|
||||||
control_brace_style = "AlwaysNextLine"
|
|
||||||
Reference in New Issue
Block a user