use super::*;
use crate::physics::behaviors::BehaviorBlock;
use crate::physics::classes::{ReplicationClass, SimulationMode};
use crate::physics::collision::{CollisionMode, CollisionPolicy, CollisionResponse};
use crate::physics::emitter::*;
use crate::physics::promotion::{PromotionAuthority, PromotionPolicy, PromotionRule, PromotionTarget};
use crate::physics::render_mode::{RenderMode, RepresentationMode};
use crate::physics::render_policy::RenderPolicy;
use crate::physics::semantic_binding::SemanticBinding;
fn base_entry(id: &str, name: &str) -> PresetCatalogEntry {
PresetCatalogEntry {
id: id.into(),
name: name.into(),
family: PresetFamily::Promoted,
authority: AuthorityProfile::PromotionCapable,
semantics: SemanticBinding {
trait_tags: vec!["isDebris".into(), "isPickupable".into()],
..SemanticBinding::default()
},
shape: SpawnShape::Sphere { radius: 0.3 },
spawn: SpawnPolicy {
mode: SpawnMode::Burst,
rate_per_sec: 0.0,
burst_count: 5,
max_live: 20,
warmup_seconds: 0.0,
looped: false,
seed: 0,
density_scale_lod: false,
},
initialize: InitPolicy::default(),
simulate: SimPolicy {
mode: SimulationMode::Full,
gravity: [0.0, -9.81, 0.0],
drag: 0.05,
damping: 0.03,
noise: None,
forces: vec![],
lifetime: LifetimePolicy {
seconds: 10.0,
random_range: None,
},
behaviors: vec![BehaviorBlock::Settle],
},
collision: CollisionPolicy {
mode: CollisionMode::Plane,
response: CollisionResponse::Bounce,
restitution: 0.2,
friction: 0.6,
..CollisionPolicy::default()
},
render: RenderPolicy {
mode: RenderMode::MeshInstance,
lit: true,
cast_shadows: true,
..RenderPolicy::default()
},
promotion: PromotionPolicy {
enabled: true,
target: PromotionTarget::Pickup,
authority: PromotionAuthority::ClientSuggestsServerConfirms,
rules: vec![PromotionRule {
when: "resting".into(),
min_age: 1.5,
requires_tags: vec!["isDebris".into()],
set_tags: vec!["isPickupable".into(), "signal.promoted".into()],
}],
},
budgets: BudgetPolicy {
max_gpu_particles: 50,
importance: "High".into(),
offscreen_mode: SimulationMode::Frozen,
},
replication: ReplicationPolicy {
class: ReplicationClass::PromotionOnly,
},
supported_views: vec![RepresentationMode::World3D, RepresentationMode::Sprite2D],
tags: vec!["promoted".into()],
}
}
pub fn catalog() -> Vec<PresetCatalogEntry> {
vec![
{
let mut e = base_entry("promo_common_salvage", "Common Salvage");
e.initialize.color = [0.7, 0.7, 0.7, 1.0];
e.tags.push("common".into());
e
},
{
let mut e = base_entry("promo_uncommon_salvage", "Uncommon Salvage");
e.initialize.color = [0.3, 0.8, 0.3, 1.0];
e.tags.push("uncommon".into());
e
},
{
let mut e = base_entry("promo_rare_salvage", "Rare Salvage");
e.initialize.color = [0.3, 0.5, 1.0, 1.0];
e.tags.push("rare".into());
e
},
{
let mut e = base_entry("promo_epic_salvage", "Epic Salvage");
e.initialize.color = [0.7, 0.3, 1.0, 1.0];
e.tags.push("epic".into());
e
},
{
let mut e = base_entry("promo_legendary_salvage", "Legendary Salvage");
e.initialize.color = [1.0, 0.7, 0.0, 1.0];
e.simulate.behaviors = vec![BehaviorBlock::Settle, BehaviorBlock::Hover];
e.tags.push("legendary".into());
e
},
{
let mut e = base_entry("promo_resource_shard", "Resource Shard");
e.promotion.target = PromotionTarget::ResourceNode;
e.render.mode = RenderMode::ShardInstance;
e.initialize.color = [0.5, 0.8, 0.9, 0.9];
e.semantics.trait_tags = vec!["isResourceNode".into(), "isDebris".into()];
e.tags.push("resource".into());
e
},
{
let mut e = base_entry("promo_gem_drop", "Gem Drop");
e.spawn.burst_count = 3;
e.render.mode = RenderMode::ShardInstance;
e.initialize.color = [0.9, 0.2, 0.4, 1.0];
e.tags.push("gem".into());
e
},
{
let mut e = base_entry("promo_ore_chunk", "Ore Chunk");
e.spawn.burst_count = 4;
e.initialize.color = [0.5, 0.45, 0.4, 1.0];
e.semantics.trait_tags = vec!["isMetal".into(), "isDebris".into(), "isPickupable".into()];
e.tags.push("ore".into());
e
},
{
let mut e = base_entry("promo_wood_scrap", "Wood Scrap");
e.spawn.burst_count = 6;
e.initialize.color = [0.55, 0.35, 0.15, 1.0];
e.semantics.trait_tags = vec!["isWood".into(), "isDebris".into(), "isPickupable".into()];
e.tags.push("wood".into());
e
},
{
let mut e = base_entry("promo_fabric_scrap", "Fabric Scrap");
e.spawn.burst_count = 4;
e.simulate.drag = 0.15;
e.initialize.color = [0.6, 0.5, 0.7, 1.0];
e.semantics.trait_tags = vec!["isOrganic".into(), "isDebris".into(), "isPickupable".into()];
e.tags.push("fabric".into());
e
},
{
let mut e = base_entry("promo_bone_fragment", "Bone Fragment");
e.spawn.burst_count = 3;
e.initialize.color = [0.9, 0.88, 0.8, 1.0];
e.semantics.trait_tags = vec!["isOrganic".into(), "isDebris".into(), "isPickupable".into()];
e.tags.push("bone".into());
e
},
{
let mut e = base_entry("promo_crystal_shard", "Crystal Shard");
e.spawn.burst_count = 2;
e.render.mode = RenderMode::ShardInstance;
e.initialize.color = [0.6, 0.4, 1.0, 0.9];
e.tags.push("crystal".into());
e
},
{
let mut e = base_entry("promo_persistent_rubble", "Persistent Rubble");
e.spawn.burst_count = 10;
e.promotion.target = PromotionTarget::PersistentDebris;
e.simulate.lifetime.seconds = 30.0;
e.initialize.color = [0.6, 0.58, 0.52, 1.0];
e.semantics.trait_tags = vec!["isStone".into(), "isDebris".into()];
e.tags.push("rubble".into());
e
},
{
let mut e = base_entry("promo_world_scar", "World Scar");
e.spawn.burst_count = 1;
e.promotion.target = PromotionTarget::WorldScar;
e.simulate.lifetime.seconds = 60.0;
e.simulate.gravity = [0.0, 0.0, 0.0];
e.collision.mode = CollisionMode::None;
e.initialize.color = [0.3, 0.1, 0.0, 0.8];
e.tags.push("scar".into());
e
},
{
let mut e = base_entry("promo_hazard_zone", "Hazard Zone");
e.spawn.burst_count = 1;
e.promotion.target = PromotionTarget::Hazard;
e.simulate.lifetime.seconds = 30.0;
e.simulate.gravity = [0.0, 0.0, 0.0];
e.collision.mode = CollisionMode::None;
e.initialize.color = [1.0, 0.3, 0.0, 0.6];
e.semantics.trait_tags = vec!["isHazard".into()];
e.tags.push("hazard".into());
e
},
]
}