summaryrefslogtreecommitdiff
path: root/godot/scripts/vehicles/Airplane.gd
blob: aa1f4922ea9140183f139cbe30e295cb250fd79d (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
extends VehicleBody

var countdown
var boosting = false
var boost_pressed = false
const booster_force = 2500
const brake_force = 50
var brake_control : float = 0.0
const boost_length = 8
const turn_constant = 0.45
const roll_constant = 0.5
const pitch_constant = 0.9
const drag_constant = 0.4
const v_angle_max = 1.0472 #60 deg, also top and bottom of regular steering
const v_angle_min = -1.45626 #-85 deg
const roll_angle_max = 1.22173 #70 deg
var roll_dir = 0 #right = 1, left = -1
var pitch_dir = 0 #up = 1, down = -1
var v_angle
var roll_angle
var vel_slow
var parentvel = [Vector3.ZERO, Vector3.ZERO]
export var roll_curve : CurveTexture

#net machine variables
var in_use : bool = false
var user = null
var world = null

func get_init_info():
	return {"." : 0}

func mp_init(init_info):
	pass

remote func update_phys_transform(t, lv, av):
	transform = t
	linear_velocity = lv
	angular_velocity = av

remotesync func net_apply_impulse(impulse_v):
	apply_central_impulse(impulse_v)

remotesync func set_net_owner(id, char_name):
	set_network_master(id)
	if id == 1 and char_name == "NONE": #not under control
		on_no_control()
		if user != null:
			user.lose_machine()
		user = null
		in_use = false
	else:
		in_use = true
		user = world.get_node("PLAYERS/"+char_name)
		user.take_control_of_machine(self)
		if is_network_master():
			on_new_control()

func relinquish_control():
	rpc("set_net_owner", 1, "NONE")

#TO BE OVERRIDDEN BY CHILDREN
func on_new_control():
	pass#user.add_collision_exception_with(self)
	#user.global_transform.origin = $Cockpit.global_transform.origin

func on_no_control():
	pass#user.remove_collision_exception_with(self)
	#user.global_transform.origin = $PilotExit.global_transform.origin

func attack1():
	pass

func attack2():
	pass
	
func direction_input(fwd,bwd,left,right,_left2,_right2):
	roll_dir  = left - right
	pitch_dir = bwd - fwd

func misc_input(_ctrl,space,shift):
	brake_control = shift
	if space > 0.1 and !boosting: #if boost is pressed
		trigger_boost()

func mouse_input(_m1,_m3,_m2): #used for long-press actions
	pass

func _ready():
	world = get_tree().get_root().find_node("GAMEWORLD", true, false)
	countdown = boost_length
	brake = 5

func trigger_boost():
	print("boosting")
	boosting = true
	$"%RocketTrail".emitting = true

func _process(delta):
	if is_network_master():
		if boosting and countdown <= 0:
			$"%RocketTrail".emitting = false
			print("stopped boosting")
			boosting = false
			countdown = boost_length
		
func _physics_process(delta):
	if in_use and user.get_network_master() == world.client_id:
		user.global_transform.origin = $Cockpit.global_transform.origin
		user.global_transform.basis = $Cockpit.global_transform.basis.orthonormalized()
	if is_network_master():
		$rearwheel.brake = lerp($rearwheel.brake, brake_force*brake_control, 0.05)
		v_angle = atan2(global_transform.basis.x.y,sqrt(global_transform.basis.x.z*global_transform.basis.x.z + global_transform.basis.x.x*global_transform.basis.x.x))
		roll_angle = global_transform.basis.x.cross(Vector3.UP).angle_to($rightaileron.global_transform.origin-$wingcenter.global_transform.origin)
		if $rightaileron.global_transform.origin.y < $leftaileron.global_transform.origin.y:
			roll_angle *= -1
		if boosting:
			add_force(global_transform.basis.x*booster_force,Vector3.ZERO)
			countdown -= delta
		
		#print(linear_velocity.length())
		#slow plane by drag and gravity
		if linear_velocity.length() > 16 and linear_velocity.angle_to(global_transform.basis.x) < 0.25:
			var v_dir = 1 if linear_velocity.y > 0 else -1
			vel_slow = v_dir*sqrt(abs(2*9.8*linear_velocity.y*delta)) + drag_constant + brake_control*5
			add_force(-1*linear_velocity.normalized()*vel_slow*mass,Vector3.ZERO)
		
func _integrate_forces(state):
	if is_network_master():
		if linear_velocity.length() > 25:
			#linear_velocity = linear_velocity.normalized()*(linear_velocity.length()-vel_slow)
			var ang_vel_target = Vector3.ZERO
			#pitch plane
			if pitch_dir == 1: #up, rotate toward maximum vertical angle
				ang_vel_target += pitch_constant*(v_angle_max-v_angle)*global_transform.basis.z
			elif pitch_dir == -1: #down, rotate toward minimum vertical angle
				ang_vel_target += pitch_constant*(v_angle_min-v_angle)*global_transform.basis.z
			
			#roll (rotate around lengthwise axis)
			var is_returning = 3 if roll_dir == 0 else 1 #return to flat quicker
			print(roll_constant*is_returning*(roll_dir*roll_curve.curve.interpolate((roll_angle_max-roll_angle)/roll_angle_max))*global_transform.basis.x)
			ang_vel_target += roll_constant*is_returning*(roll_dir*roll_curve.curve.interpolate(roll_angle_max-roll_angle))*global_transform.basis.x
			
			#turn (based on how much the plane is rolled (need to add
			ang_vel_target += turn_constant*Vector3.UP*roll_angle
			
			#apply angular velocity
			angular_velocity = ang_vel_target#lerp(angular_velocity,ang_vel_target,0.1)
			if linear_velocity.angle_to(global_transform.basis.x) < 0.25:
				set_linear_velocity(get_linear_velocity().slerp(transform.basis.x*linear_velocity.length(),0.1))
		#linear_velocity += parentvel[0]; angular_velocity += parentvel[1]
		rpc("update_phys_transform", transform, linear_velocity, angular_velocity)