aboutsummaryrefslogtreecommitdiff
path: root/scripts/bullet.gd
blob: 86319bb7c0b4f058602170e8518e28e0c3ae21bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
extends Spatial

var _enemies_holder
var _fx_holder
var load_scenes
var shooter

var damage = 0
var aoe = 0
var slowness_effect = 0
var slowness_time = 0

var timer = 0
var time_life = 3
var speed = 7
var hit_something = false
var bounce = false
var hitlist = []

var ignore_collisions = false

func _ready():
	var root = get_tree().root.get_node("world")
	_enemies_holder = root.get_node("enemies")
	_fx_holder = root.get_node("fx")
	var _err = $Area.connect("body_entered", self, "collided")
	var saveload = root.get_node("saveload")
	load_scenes = saveload.get_node("load_scenes")
	
func bounce_physics (delta):
	var forward_dir = -global_transform.basis.z.normalized()
	var space: PhysicsDirectSpaceState = get_world().direct_space_state
	var from = transform.origin 
	var to = transform.origin + forward_dir * speed * delta
	var mask = 0b0101
	var result = space.intersect_ray(from, to, [], mask)
	if result.size() > 0:
		hitlist.clear()
		var bounced = forward_dir.bounce(result.normal).normalized()
		var z = -bounced;
		var x = bounced.cross(result.normal).normalized();
		var y = x.cross(z).normalized();
		var basis = Basis(x, y, z);
		global_transform.basis = basis
		forward_dir = -global_transform.basis.z.normalized()
		var dist = transform.origin.distance_to(result.position)
		transform.origin = result.position
		var amt = speed * delta - dist
		global_translate(forward_dir * amt)
	else:
		global_translate(forward_dir * speed * delta)

func _physics_process(delta):
	timer += delta
	if timer >= time_life:
		if aoe > 0: explode()
		queue_free()
		return
	
	if bounce:
		bounce_physics(delta)
	else:
		var forward_dir = -global_transform.basis.z.normalized()
		global_translate(forward_dir * speed * delta)
		

func explode ():
	var space = get_world().direct_space_state
	
	var shape = SphereShape.new()
	shape.radius = aoe
	
	var params: = PhysicsShapeQueryParameters.new()
	params.set_shape(shape)
	params.collision_mask = 0b1000
	params.transform = transform
	
	var result = space.intersect_shape(params)
	for body in result:
		apply_damage(body.collider.get_parent().name)
		
	var fx_ex = load_scenes.fx_explosion.instance()
	fx_ex.transform = transform
	fx_ex.transform.basis = fx_ex.transform.basis.scaled(Vector3.ONE * aoe)
	fx_ex.time_life = 0.2
	_fx_holder.add_child(fx_ex)

func collided(body):
	var parent = body.get_parent()
	if parent == shooter: return
	if parent in hitlist: return
	
	if hit_something == false:
		var groups = parent.get_groups()
		## TODO design? aoe damages twice: on hit and aoe
		if "enemies" in groups: apply_damage(parent.name)
		if aoe > 0: explode()
			
	if !bounce:
		hit_something = true
		if aoe > 0: explode()
		queue_free()
	else:
		hitlist.append(parent)

func apply_damage (enemyname):
	_enemies_holder.damage(enemyname, damage, slowness_effect, slowness_time)