| @@ -203,12 +203,26 @@ fn clear_structures(mut commands: Commands, structures: Query<Entity, With<Struc |
| 203 |
203 |
} |
| 204 |
204 |
} |
| 205 |
205 |
|
|
206 |
+type Part = (Handle<Mesh>, Handle<ColorMaterial>); |
|
207 |
+ |
| 206 |
208 |
#[derive(Resource, Default)] |
| 207 |
209 |
pub struct StructureAssets { |
| 208 |
|
- ring: (Handle<Mesh>, Handle<ColorMaterial>), |
| 209 |
|
- flame: (Handle<Mesh>, Handle<ColorMaterial>), |
| 210 |
|
- stick: (Handle<Mesh>, Handle<ColorMaterial>), |
| 211 |
|
- torch_flame: (Handle<Mesh>, Handle<ColorMaterial>), |
|
210 |
+ stone: Part, |
|
211 |
+ log: Part, |
|
212 |
+ flame: Part, |
|
213 |
+ flame_core: Part, |
|
214 |
+ stick: Part, |
|
215 |
+} |
|
216 |
+ |
|
217 |
+const CAMPFIRE_STONES: usize = 7; |
|
218 |
+ |
|
219 |
+fn flame_mesh(width: f32, height: f32) -> Mesh { |
|
220 |
+ Triangle2d::new( |
|
221 |
+ Vec2::new(-width / 2.0, -height / 2.0), |
|
222 |
+ Vec2::new(width / 2.0, -height / 2.0), |
|
223 |
+ Vec2::new(0.0, height / 2.0), |
|
224 |
+ ) |
|
225 |
+ .into() |
| 212 |
226 |
} |
| 213 |
227 |
|
| 214 |
228 |
fn create_structure_assets( |
| @@ -218,38 +232,43 @@ fn create_structure_assets( |
| 218 |
232 |
) { |
| 219 |
233 |
let mut part = |mesh: Mesh, color: Color| (meshes.add(mesh), materials.add(color)); |
| 220 |
234 |
commands.insert_resource(StructureAssets { |
| 221 |
|
- ring: part( |
| 222 |
|
- Circle::new(TILE_SIZE * 0.45).into(), |
| 223 |
|
- Color::srgb_u8(90, 86, 80), |
|
235 |
+ stone: part( |
|
236 |
+ Circle::new(TILE_SIZE * 0.09).into(), |
|
237 |
+ Color::srgb_u8(120, 116, 110), |
|
238 |
+ ), |
|
239 |
+ log: part( |
|
240 |
+ Rectangle::new(TILE_SIZE * 0.7, TILE_SIZE * 0.14).into(), |
|
241 |
+ Color::srgb_u8(110, 74, 42), |
| 224 |
242 |
), |
| 225 |
243 |
flame: part( |
| 226 |
|
- Circle::new(TILE_SIZE * 0.28).into(), |
| 227 |
|
- Color::srgb_u8(255, 150, 40), |
|
244 |
+ flame_mesh(TILE_SIZE * 0.36, TILE_SIZE * 0.5), |
|
245 |
+ Color::srgb_u8(240, 110, 30), |
|
246 |
+ ), |
|
247 |
+ flame_core: part( |
|
248 |
+ flame_mesh(TILE_SIZE * 0.18, TILE_SIZE * 0.28), |
|
249 |
+ Color::srgb_u8(255, 220, 90), |
| 228 |
250 |
), |
| 229 |
251 |
stick: part( |
| 230 |
252 |
Rectangle::new(TILE_SIZE * 0.12, TILE_SIZE * 0.5).into(), |
| 231 |
253 |
Color::srgb_u8(100, 70, 40), |
| 232 |
254 |
), |
| 233 |
|
- torch_flame: part( |
| 234 |
|
- Circle::new(TILE_SIZE * 0.16).into(), |
| 235 |
|
- Color::srgb_u8(255, 200, 70), |
| 236 |
|
- ), |
| 237 |
255 |
}); |
| 238 |
256 |
} |
| 239 |
257 |
|
|
258 |
+fn part_bundle((mesh, material): &Part, transform: Transform) -> impl Bundle { |
|
259 |
+ ( |
|
260 |
+ Mesh2d(mesh.clone()), |
|
261 |
+ MeshMaterial2d(material.clone()), |
|
262 |
+ transform, |
|
263 |
+ ) |
|
264 |
+} |
|
265 |
+ |
| 240 |
266 |
pub fn spawn_structure( |
| 241 |
267 |
commands: &mut Commands, |
| 242 |
268 |
assets: &StructureAssets, |
| 243 |
269 |
tile: UVec2, |
| 244 |
270 |
kind: StructureKind, |
| 245 |
271 |
) { |
| 246 |
|
- let part = |(mesh, material): &(Handle<Mesh>, Handle<ColorMaterial>), offset: Vec3| { |
| 247 |
|
- ( |
| 248 |
|
- Mesh2d(mesh.clone()), |
| 249 |
|
- MeshMaterial2d(material.clone()), |
| 250 |
|
- Transform::from_translation(offset), |
| 251 |
|
- ) |
| 252 |
|
- }; |
| 253 |
272 |
let mut entity = commands.spawn(( |
| 254 |
273 |
Name::new(format!("{kind:?}")), |
| 255 |
274 |
Structure { |
| @@ -259,16 +278,31 @@ pub fn spawn_structure( |
| 259 |
278 |
TilePos(tile), |
| 260 |
279 |
Transform::from_translation(WorldMap::tile_center(tile).extend(0.8)), |
| 261 |
280 |
)); |
|
281 |
+ let at = |x: f32, y: f32, z: f32| Transform::from_xyz(x * TILE_SIZE, y * TILE_SIZE, z); |
| 262 |
282 |
match kind { |
| 263 |
283 |
StructureKind::Campfire => entity.with_children(|c| { |
| 264 |
|
- c.spawn(part(&assets.ring, Vec3::ZERO)); |
| 265 |
|
- c.spawn(part(&assets.flame, Vec3::Z * 0.01)); |
|
284 |
+ for i in 0..CAMPFIRE_STONES { |
|
285 |
+ let angle = i as f32 / CAMPFIRE_STONES as f32 * std::f32::consts::TAU; |
|
286 |
+ let pos = Vec2::from_angle(angle) * 0.38; |
|
287 |
+ c.spawn(part_bundle(&assets.stone, at(pos.x, pos.y, 0.0))); |
|
288 |
+ } |
|
289 |
+ for angle in [0.6_f32, -0.6] { |
|
290 |
+ let log = at(0.0, -0.08, 0.01).with_rotation(Quat::from_rotation_z(angle)); |
|
291 |
+ c.spawn(part_bundle(&assets.log, log)); |
|
292 |
+ } |
|
293 |
+ c.spawn(part_bundle(&assets.flame, at(0.0, 0.08, 0.02))); |
|
294 |
+ c.spawn(part_bundle(&assets.flame_core, at(0.0, 0.03, 0.03))); |
| 266 |
295 |
}), |
| 267 |
296 |
StructureKind::Torch => entity.with_children(|c| { |
| 268 |
|
- c.spawn(part(&assets.stick, Vec3::new(0.0, -TILE_SIZE * 0.1, 0.0))); |
| 269 |
|
- c.spawn(part( |
| 270 |
|
- &assets.torch_flame, |
| 271 |
|
- Vec3::new(0.0, TILE_SIZE * 0.2, 0.01), |
|
297 |
+ c.spawn(part_bundle(&assets.stick, at(0.0, -0.15, 0.0))); |
|
298 |
+ let small = Vec3::splat(0.6); |
|
299 |
+ c.spawn(part_bundle( |
|
300 |
+ &assets.flame, |
|
301 |
+ at(0.0, 0.18, 0.01).with_scale(small), |
|
302 |
+ )); |
|
303 |
+ c.spawn(part_bundle( |
|
304 |
+ &assets.flame_core, |
|
305 |
+ at(0.0, 0.15, 0.02).with_scale(small), |
| 272 |
306 |
)); |
| 273 |
307 |
}), |
| 274 |
308 |
}; |