AUJ2XCCYHCUBG3IZCLD4WGBINY56S4QWGJDLUQJVUGMJOESXYGIQC QMQSIKACOMY55Y3FCVCPCBIM5KODNE6GAKRRGORSMNZQT2ONPDDQC OFSXWOK6YNCYCKXRPOLAQQOYANOMDOL3ZDUXMDM65UTKVOA4LAXAC 57S64Z47SHSHO23K7VPUFBJETNVYBPK47BSIHJCW572KIUVF52HQC 6YIJ6ZQ6EOSZCK4K422ZUDXSMXKBEAWNA2MKCDS6B7NR2BGB3M2AC ZTXU3KDWJAP47BPTRDJGQSR3C2YNKJE5NKFBYZKXR7N6LWGJWC7QC D5PGHFSZDX3WUCLIJXRKCYH4MXULSP7JILSBY5QZ4WG6HX5YZHPQC use std::time::{Duration, Instant};use bevy::prelude::*;use bevy_xpbd_2d::components::{AngularVelocity, LinearVelocity};pub struct UndertakerPlugin;impl Plugin for UndertakerPlugin {fn build(&self, app: &mut App) {app.init_resource::<UndertakerConfig>().add_event::<Undertaken>().add_systems(Update, (undertaker_debug_line, update_mortals));}}/// Event that occurs when something is undertaken#[derive(Event)]pub struct Undertaken {position: Vec3,}#[derive(Resource)]pub struct UndertakerConfig {pub under_y: f32,pub max_time_under: Duration,}impl Default for UndertakerConfig {fn default() -> Self {Self {under_y: 0.0,max_time_under: Duration::from_secs(1),}}}#[derive(Component, Default)]pub struct Mortal {// Z might have info, so allow it to be controlled/// If [`None`], entity is destroyed. Otherwise/// move the entity to a valid location close to the/// given point, and zero any velocity.pub respawn: Option<Vec3>,instant_under: Option<Instant>,}impl Mortal {pub fn respawnable(respawn: Vec3) -> Self {Self {respawn: Some(respawn),..default()}}}#[allow(clippy::type_complexity)]fn update_mortals(mut query: Query<(Entity,&mut Mortal,&mut Transform,&GlobalTransform,Option<&mut LinearVelocity>,Option<&mut AngularVelocity>,)>,config: Res<UndertakerConfig>,mut commands: Commands,mut writer: EventWriter<Undertaken>,) {for (entity, mut mortality, mut transform, global_transform, lin_vel, ang_vel) inquery.iter_mut(){if global_transform.translation().y >= config.under_y {mortality.instant_under = None;} else {let mortal_instant = mortality.instant_under.unwrap_or(Instant::now());if mortal_instant.elapsed() > config.max_time_under {if let Some(declared_respawn) = mortality.respawn {let respawn_point = Vec3::new(declared_respawn.x,declared_respawn.y.max(config.under_y),declared_respawn.z,);transform.translation = respawn_point;if let Some(mut linear) = lin_vel {linear.0 = Vec2::ZERO;}if let Some(mut angular) = ang_vel {angular.0 = 0.;}writer.send(Undertaken {position: global_transform.translation(),});mortality.instant_under = None;} else {commands.entity(entity).despawn_recursive();}} else {mortality.instant_under = Some(mortal_instant);}}}}fn undertaker_debug_line(mut gizmos: Gizmos, config: Res<UndertakerConfig>) {gizmos.primitive_2d(Plane2d::new(Vec2::Y),Vec2::Y * config.under_y,0.,Color::ORANGE_RED,);}
DefaultPlugins.set(WindowPlugin {primary_window: Some(Window {title: "Bulle".to_string(),resolution: WindowResolution::new(LOGICAL_WIDTH as f32, LOGICAL_HEIGHT as f32),
DefaultPlugins.set(WindowPlugin {primary_window: Some(Window {title: "Bulle".to_string(),resolution: WindowResolution::new(LOGICAL_WIDTH as f32,LOGICAL_HEIGHT as f32,),..default()}),
}mod layered {use bevy::prelude::*;use bevy_xpbd_2d::{components::CollisionLayers, prelude::*};pub struct LayeredPlugin;#[derive(SystemSet, Debug, Clone, Copy, PartialEq, Eq, Hash)]pub enum LayeredPluginSet {PreUpdate,Update,}impl Plugin for LayeredPlugin {fn build(&self, app: &mut App) {app.add_systems(Update,update_collision_layers.in_set(LayeredPluginSet::Update),).configure_sets(Update,(LayeredPluginSet::PreUpdate, LayeredPluginSet::Update).chain(),);}}#[derive(PhysicsLayer, Clone, Copy)]pub enum GameLayer {Ground,LayerA,LayerB,ProjectileA,ProjectileB,}impl GameLayer {/// Switch layers into the proper projectile layer////// `Ground` is a special-case value meaning both A and Bpub fn into_projectile(self) -> Self {match self {Self::Ground => Self::Ground,Self::LayerA | Self::ProjectileA => Self::ProjectileA,Self::LayerB | Self::ProjectileB => Self::ProjectileB,}}}#[derive(Component, Clone, Copy, Debug)]pub enum Layered {Ground,A,B,}impl Layered {/// Get the layer-swapped version of this [`Layered`]pub fn swapped(self) -> Self {match self {Self::Ground => Self::Ground,Self::A => Self::B,Self::B => Self::A,}}/// Get the corresponding [`GameLayer`]pub fn layer(self) -> GameLayer {match self {Self::Ground => GameLayer::Ground,Self::A => GameLayer::LayerA,Self::B => GameLayer::LayerB,}}}fn layer_a_collision_layers() -> CollisionLayers {CollisionLayers::new([GameLayer::LayerA],[GameLayer::LayerA, GameLayer::ProjectileA, GameLayer::Ground],)}// NOTE Projectiles (generally) do not interact with each otherfn layer_a_projectile_collision_layers(self_interact: bool) -> CollisionLayers {CollisionLayers::new(GameLayer::ProjectileA,if !self_interact {Into::<LayerMask>::into([GameLayer::Ground, GameLayer::LayerA])} else {[GameLayer::Ground, GameLayer::LayerA, GameLayer::ProjectileA].into()},)}fn layer_b_collision_layers() -> CollisionLayers {CollisionLayers::new([GameLayer::LayerB],[GameLayer::LayerB, GameLayer::ProjectileB, GameLayer::Ground],)}fn layer_b_projectile_collision_layers(self_interact: bool) -> CollisionLayers {CollisionLayers::new(GameLayer::ProjectileB,if !self_interact {Into::<LayerMask>::into([GameLayer::Ground, GameLayer::LayerB])} else {[GameLayer::Ground, GameLayer::LayerB, GameLayer::ProjectileB].into()},)}fn ground_collision_layers() -> CollisionLayers {CollisionLayers::new(GameLayer::Ground, LayerMask::ALL)}fn wide_projectile_collision_layers(self_interact: bool) -> CollisionLayers {CollisionLayers::new([GameLayer::ProjectileA, GameLayer::ProjectileB],if !self_interact {Into::<LayerMask>::into([GameLayer::Ground, GameLayer::LayerA, GameLayer::LayerB])} else {[GameLayer::Ground,GameLayer::LayerA,GameLayer::LayerB,GameLayer::ProjectileA,GameLayer::ProjectileB,].into()},)}fn update_collision_layers(query: Query<(Entity, Ref<Layered>)>, mut commands: Commands) {for (entity, layered) in query.iter() {match &*layered {Layered::A => {commands.entity(entity).try_insert(layer_a_collision_layers());}Layered::B => {commands.entity(entity).try_insert(layer_b_collision_layers());}Layered::Ground => {commands.entity(entity).try_insert(ground_collision_layers());}}}}
Collider::capsule(32.0, 32.0),Restitution::new(1.0),TnuaConfig {max_speed: 5000.,air_actions: 2,walk: TnuaBuiltinWalk {acceleration: 2000.,air_acceleration: 1500.,float_height: 64.0,..default()},jump: TnuaBuiltinJump {height: 128.,reschedule_cooldown: Some(0.1),// Defaults x 10upslope_extra_gravity: 300.0,// takeoff_extra_gravity: 300.0,// takeoff_above_velocity: 64.0,fall_extra_gravity: 200.0,shorten_extra_gravity: 600.0,peak_prevention_at_upward_velocity: 10.0,peak_prevention_extra_gravity: 200.0,..default()},},TnuaControllerBundle::default(),// TnuaXpbd2dSensorShape(Collider::circle(32.0)),TnuaSimpleAirActionsCounter::default(),
Collider::capsule(64.0, 48.0),layered::Layered::A,undertaker::Mortal::respawnable(Vec3::new(320.0, 640.0, 0.0)),
struct AiContext {desired_movement: Vec2,
commands.spawn((camera::CameraTarget(1),layered::Layered::B,RigidBody::Dynamic,Collider::capsule(32.0, 32.0),undertaker::Mortal::default(),MaterialMesh2dBundle {mesh: Mesh2dHandle(meshes.add(Capsule2d::new(32.0, 32.0))),material: materials.add(Color::hsl(5., 0.6, 0.75)),transform: Transform::from_xyz(320.0, 960.0, 0.0),..default()},));
struct Behaved {runner: simple_bt::BehaviorRunner<AiContext>,}
struct LayerTextureSwap(Handle<ColorMaterial>);#[allow(clippy::type_complexity)]fn action_state_swap_layers(mut query: Query<(Entity,&ActionState<PlayerMovement>,&GlobalTransform,&mut layered::Layered,Option<&mut LayerTextureSwap>,Option<&mut Handle<ColorMaterial>>,)>,spatial_query: SpatialQuery,) {for (ent, action_state, gtransform, mut layer, mut maybe_lts, mut maybe_mat) in query.iter_mut(){if action_state.just_pressed(&PlayerMovement::Swap) {// Attempt to swap layerslet blocker_collider = Collider::circle(32. * 2.);let blockers = spatial_query.shape_intersections(&blocker_collider,gtransform.translation().truncate(),0.,SpatialQueryFilter::from_mask(layer.swapped().layer()),);
fn input_behaved(mut query: Query<(&mut Behaved,), Without<Player>>) {for (mut behaved,) in query.iter_mut() {let mut context = AiContext {desired_movement: Vec2::ZERO,};behaved.runner.proceed(&mut context);let x_movement = context.desired_movement.x;if x_movement > 0.001 {// action_state.press(&PlayerMovement::Walk);
if blockers.is_empty() {*layer = layer.swapped();if let Some(mut lts) = maybe_lts {let new_mat = lts.0.clone();if let Some(mat) = maybe_mat.as_mut() {lts.0 = mat.clone();*mat.as_mut() = new_mat;}}}
//! Lua scripts to attach behavior trees to things.//!//! We use piccolo cuz I wanna get an idea of how to use it//! and be able to contribute to it.
#import "@preview/gentle-clues:0.7.1": *#set par(justify: true)#set document(title: "IO: Game Design Document",author: {"Jengamon"},)#show "IO": name => box[#box(image("important.jpg", height: 0.7em)) #name]#align(center)[= IO== #smallcaps[Game Design Document]_#smallcaps[by jengamon]_]#line(length: 100%)In this report, we will explore the various factorsthat influence _fluid dynamics_ in glaciers and how theycontribute to the formation and behavior of these natural structures.The most important structure is shown in @skibi_miku.+ The climate- Temperature+ Fahrenheit+ Celsius- Precipitation+ The topography+ The geology#info[ This is an info!#figure(image("important.jpg", width: 70%),caption: [_Skibidi Miku_ is a paragon of virtue.]) <skibi_miku>]#tip(title: "Best title evah...")[Check this out\~]If/when I need math, the equation $Q = rho A v + C$ looks pretty cool...It can also look like: $ Q = rho A v + C $ or$ Q = rho A v + "time offset" $Some environmental science:$ 7.32 beta + sum_(i=0)^nabla Q_i / 2 $A cool vector: $ v := vec(x_1, x_2, x_3) in cal(S) $Some variants: $ a arrow.squiggly b $
gdd:typst watch notes/gdd.typ
bevy = { version = "0.13" }
bevy = { version = "0.13", default-features = false, features = ["animation","bevy_asset","bevy_gilrs","bevy_scene","bevy_winit","bevy_core_pipeline","bevy_pbr","bevy_gltf","bevy_render","bevy_sprite","bevy_text","bevy_ui","multi-threaded","png","hdr","x11","bevy_gizmos","tonemapping_luts","default_font","webgl2","bevy_debug_stepping",]}bevy_kira_audio = { version = "0.19" }
][[package]]name = "bevy_audio"version = "0.13.2"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "b0f12495e230cd5cf59c6051cdd820c97d7fe4f0597d4d9c3240c62e9c65b485"dependencies = ["bevy_app","bevy_asset","bevy_derive","bevy_ecs","bevy_math","bevy_reflect","bevy_transform","bevy_utils","cpal","rodio",
name = "bevy_kira_audio"version = "0.19.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "1bf58fed4b6fd13df35e77002821cf459948131de4ac262c3b6a175d8fe28fd3"dependencies = ["anyhow","bevy","kira","parking_lot","ron","serde","thiserror","uuid",][[package]]
][[package]]name = "darling"version = "0.20.8"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391"dependencies = ["darling_core","darling_macro",][[package]]name = "darling_core"version = "0.20.8"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f"dependencies = ["fnv","ident_case","proc-macro2","quote","strsim","syn 2.0.59",
[[package]]name = "derive_builder"version = "0.20.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7"dependencies = ["derive_builder_macro",][[package]]name = "derive_builder_core"version = "0.20.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d"dependencies = ["darling","proc-macro2","quote","syn 2.0.59",][[package]]name = "derive_builder_macro"version = "0.20.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b"dependencies = ["derive_builder_core","syn 2.0.59",]
][[package]]name = "gc-arena"version = "0.5.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "57b2e43b3fc51b9900cc9ced1c4630dcbfae1859573102a84d2231ac744c1208"dependencies = ["allocator-api2","gc-arena-derive","hashbrown","sptr",][[package]]name = "gc-arena-derive"version = "0.5.0"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "96f3c487d429eaa928334f7f2ca7b14734f1c2f4020d2b08c1f0b4d9c70e4f17"dependencies = ["proc-macro2","quote","syn 2.0.59","synstructure",
name = "kira"version = "0.8.7"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "8968f1eda49cdf4f6406fd5ffe590c3ca2778a1b0e50b5684974b138a99dfb2f"dependencies = ["atomic-arena","cpal","glam","mint","ringbuf","send_wrapper","serde","symphonia",][[package]]
][[package]]name = "piccolo"version = "0.3.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "93dd1815b42446904bb2689d1c5d7680e8c68113d5b15a5a3297ba6c7a5f84af"dependencies = ["ahash","allocator-api2","anyhow","gc-arena","hashbrown","rand","thiserror",
[[package]]name = "rand"version = "0.8.5"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"dependencies = ["libc","rand_chacha","rand_core",][[package]]name = "rand_chacha"version = "0.3.1"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"dependencies = ["ppv-lite86","rand_core",][[package]]name = "rand_core"version = "0.6.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"dependencies = ["getrandom",]
[[package]]name = "symphonia"version = "0.5.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "815c942ae7ee74737bb00f965fa5b5a2ac2ce7b6c01c0cc169bbeaf7abd5f5a9"dependencies = ["lazy_static","symphonia-bundle-flac","symphonia-codec-vorbis","symphonia-core","symphonia-format-ogg","symphonia-metadata",][[package]]name = "symphonia-bundle-flac"version = "0.5.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "72e34f34298a7308d4397a6c7fbf5b84c5d491231ce3dd379707ba673ab3bd97"dependencies = ["log","symphonia-core","symphonia-metadata","symphonia-utils-xiph",][[package]]name = "symphonia-codec-vorbis"version = "0.5.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "5a98765fb46a0a6732b007f7e2870c2129b6f78d87db7987e6533c8f164a9f30"dependencies = ["log","symphonia-core","symphonia-utils-xiph",][[package]]name = "symphonia-core"version = "0.5.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "798306779e3dc7d5231bd5691f5a813496dc79d3f56bf82e25789f2094e022c3"dependencies = ["arrayvec","bitflags 1.3.2","bytemuck","lazy_static","log",][[package]]name = "symphonia-format-ogg"version = "0.5.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "ada3505789516bcf00fc1157c67729eded428b455c27ca370e41f4d785bfa931"dependencies = ["log","symphonia-core","symphonia-metadata","symphonia-utils-xiph",]
name = "symphonia-metadata"version = "0.5.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "bc622b9841a10089c5b18e99eb904f4341615d5aa55bbf4eedde1be721a4023c"dependencies = ["encoding_rs","lazy_static","log","symphonia-core",][[package]]name = "symphonia-utils-xiph"version = "0.5.4"source = "registry+https://github.com/rust-lang/crates.io-index"checksum = "484472580fa49991afda5f6550ece662237b00c6f562c7d9638d1b086ed010fe"dependencies = ["symphonia-core","symphonia-metadata",][[package]]