Ragnarokkr/player_bullets.odin

86 lines
2.3 KiB
Odin

package main
import rl "vendor:raylib"
import "core:fmt"
import "core:math/rand"
import "core:slice"
import "core:math"
bullets : [dynamic]Bullet
Bullet :: struct{
pos: vec3,
vel: vec3,
radius: f32,
alive: bool,
}
bullet_spawn :: proc(pos: vec3, dir: f32) -> Bullet {
return Bullet {
pos = pos,
vel = get_vec_from_angle(dir) * 70,
alive = true,
radius = 0.7
}
}
bullet_process :: proc(bullet: ^Bullet, game: ^Game, delta: f32) {
bullet.vel = rl.Vector3MoveTowards(bullet.vel, {}, 60 * delta)
bullet.pos += bullet.vel * delta
if rl.Vector3LengthSqr(bullet.vel) < 0.2 {
bullet.alive = false
}
if rl.CheckCollisionCircles(bullet.pos.xy, bullet.radius, Head.pos.xy, Head.radius) {
bullet.alive = false
if game.snake_health == 0 {
diff := bullet.pos - Head.pos
diff_ang := math.atan2(-diff.y, diff.x)
angle := angle_cycle(Head.dir - diff_ang, -math.PI, math.PI)
if abs(angle) > math.PI / 3 {
rl.PlaySound(Res.Sfx.LightningHit)
explode(bullet.pos, 1, 0.6, rl.YELLOW)
Head.health -= 1
}
}
return
}
for &segment in Segments {
if rl.CheckCollisionCircles(bullet.pos.xy, bullet.radius, segment.pos.xy, segment.collider_radius) {
bullet.alive = false
rl.PlaySound(Res.Sfx.LightningHit)
if segment.health > 0 {
segment.health -= 1
explode(bullet.pos, 1, 0.6, rl.YELLOW)
if segment.health == 0 {
segment.collider_radius = 1.5
explode(segment.pos, 3, 0.7, rl.RED)
rl.PlaySound(Res.Sfx.SnakeSegmentExplode)
}
}
}
}
}
bullet_draw :: proc(bullet: ^Bullet, game: ^Game) {
rl.DrawSphere(bullet.pos, 0.5, rl.YELLOW)
line_count := 0
bdraw := slice.clone_to_dynamic(game.bullets[:])
rand.shuffle(bdraw[:])
for &bul in bdraw {
if &bul == bullet {
continue
}
if line_count > 0 {
break
}
if rl.Vector3LengthSqr(bul.pos - bullet.pos) > 70 {
continue
}
line_count += 1
rl.DrawLine3D(bullet.pos, bul.pos, rl.YELLOW)
}
}