]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/turrets/turret/ewheel.qc
take3: format 903 files
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / turrets / turret / ewheel.qc
1 #include "ewheel.qh"
2
3 #ifdef SVQC
4
5 float autocvar_g_turrets_unit_ewheel_speed_fast;
6 float autocvar_g_turrets_unit_ewheel_speed_slow;
7 float autocvar_g_turrets_unit_ewheel_speed_slower;
8 float autocvar_g_turrets_unit_ewheel_speed_stop;
9 float autocvar_g_turrets_unit_ewheel_turnrate;
10
11 const int ewheel_anim_stop     = 0;
12 const int ewheel_anim_fwd_slow = 1;
13 const int ewheel_anim_fwd_fast = 2;
14 const int ewheel_anim_bck_slow = 3;
15 const int ewheel_anim_bck_fast = 4;
16
17 void ewheel_move_path(entity this)
18 {
19         // Are we close enough to a path node to switch to the next?
20         if (vdist(this.origin - this.pathcurrent.origin, <, 64)) {
21 #ifdef EWHEEL_FANCYPATH
22                 if (this.pathcurrent.path_next == NULL) {
23                         // Path endpoint reached
24                         pathlib_deletepath(this.pathcurrent.owner);
25                         this.pathcurrent = NULL;
26
27                         if (this.pathgoal) {
28                                 if (this.pathgoal.use) {
29                                         this.pathgoal.use(this.pathgoal, NULL, NULL);
30                                 }
31
32                                 if (this.pathgoal.enemy) {
33                                         this.pathcurrent = pathlib_astar(this, this.pathgoal.origin, this.pathgoal.enemy.origin);
34                                         this.pathgoal = this.pathgoal.enemy;
35                                 }
36                         } else {
37                                 this.pathgoal = NULL;
38                         }
39                 } else {
40                         this.pathcurrent = this.pathcurrent.path_next;
41                 }
42 #else
43                 this.pathcurrent = this.pathcurrent.enemy;
44 #endif
45         }
46
47         if (this.pathcurrent) {
48                 this.moveto = this.pathcurrent.origin;
49                 this.steerto = steerlib_attract2(this, this.moveto, 0.5, 500, 0.95);
50
51                 movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
52         }
53 }
54
55 void ewheel_move_enemy(entity this)
56 {
57         int newframe;
58
59         this.steerto = steerlib_arrive(this, this.enemy.origin, this.target_range_optimal);
60
61         this.moveto = this.origin + this.steerto * 128;
62
63         if (this.tur_dist_enemy > this.target_range_optimal) {
64                 if (this.tur_head.spawnshieldtime < 1) {
65                         newframe = ewheel_anim_fwd_fast;
66                         movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
67                 } else if (this.tur_head.spawnshieldtime < 2) {
68                         newframe = ewheel_anim_fwd_slow;
69                         movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
70                 } else {
71                         newframe = ewheel_anim_fwd_slow;
72                         movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
73                 }
74         } else if (this.tur_dist_enemy < this.target_range_optimal * 0.5) {
75                 newframe = ewheel_anim_bck_slow;
76                 movelib_move_simple(this, v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
77         } else {
78                 newframe = ewheel_anim_stop;
79                 movelib_brake_simple(this, (autocvar_g_turrets_unit_ewheel_speed_stop));
80         }
81
82         turrets_setframe(this, newframe, false);
83 }
84
85 void ewheel_move_idle(entity this)
86 {
87         if (this.frame != 0) {
88                 this.SendFlags |= TNSF_ANIM;
89                 this.anim_start_time = time;
90         }
91
92         this.frame = 0;
93         if (this.velocity) {
94                 movelib_brake_simple(this, (autocvar_g_turrets_unit_ewheel_speed_stop));
95         }
96 }
97
98 void ewheel_findtarget(entity this)
99 {
100         entity e = find(NULL, targetname, this.target);
101         if (!e) {
102                 LOG_TRACE("Initital waypoint for ewheel does NOT exist, fix your map!");
103                 this.target = "";
104         }
105
106         if (e.classname != "turret_checkpoint") {
107                 LOG_TRACE("Warning: not a turret path");
108         } else {
109 #ifdef EWHEEL_FANCYPATH
110                 this.pathcurrent = pathlib_astar(this, this.origin, e.origin);
111                 this.pathgoal = e;
112 #else
113                 this.pathcurrent  = e;
114 #endif
115         }
116 }
117
118 spawnfunc(turret_ewheel)
119 {
120         if (!turret_initialize(this, TUR_EWHEEL)) {
121                 delete(this);
122         }
123 }
124
125 METHOD(EWheel, tr_think, void(EWheel thistur, entity it))
126 {
127         vector wish_angle, real_angle;
128
129         float vz = it.velocity_z;
130
131         it.angles_x = anglemods(it.angles_x);
132         it.angles_y = anglemods(it.angles_y);
133
134         fixedmakevectors(it.angles);
135
136         wish_angle = normalize(it.steerto);
137         wish_angle = vectoangles(wish_angle);
138         real_angle = wish_angle - it.angles;
139         real_angle = shortangle_vxy(real_angle, it.tur_head.angles);
140
141         it.tur_head.spawnshieldtime = fabs(real_angle_y);
142         real_angle_y  = bound(-it.tur_head.aim_speed, real_angle_y, it.tur_head.aim_speed);
143         it.angles_y = (it.angles_y + real_angle_y);
144
145         if (it.enemy) {
146                 ewheel_move_enemy(it);
147         } else if (it.pathcurrent) {
148                 ewheel_move_path(it);
149         } else {
150                 ewheel_move_idle(it);
151         }
152
153         it.velocity_z = vz;
154
155         if (it.velocity) {
156                 it.SendFlags |= TNSF_MOVE;
157         }
158 }
159
160 METHOD(EWheel, tr_death, void(EWheel this, entity it))
161 {
162         it.velocity = '0 0 0';
163
164 #ifdef EWHEEL_FANCYPATH
165         if (it.pathcurrent) {
166                 pathlib_deletepath(it.pathcurrent.owner);
167         }
168 #endif
169         it.pathcurrent = NULL;
170 }
171
172 METHOD(EWheel, tr_setup, void(EWheel this, entity it))
173 {
174         if (it.move_movetype == MOVETYPE_WALK) {
175                 it.velocity = '0 0 0';
176                 it.enemy = NULL;
177
178                 setorigin(it, it.pos1);
179
180                 if (it.target != "") {
181                         InitializeEntity(it, ewheel_findtarget, INITPRIO_FINDTARGET);
182                 }
183         }
184
185         it.iscreature               = true;
186         it.teleportable         = TELEPORT_NORMAL;
187         if (!it.damagedbycontents) {
188                 IL_PUSH(g_damagedbycontents, it);
189         }
190         it.damagedbycontents        = true;
191         set_movetype(it, MOVETYPE_WALK);
192         it.solid                    = SOLID_SLIDEBOX;
193         it.takedamage               = DAMAGE_AIM;
194         it.idle_aim             = '0 0 0';
195         it.pos1                 = it.origin;
196         it.target_select_flags  = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
197         it.target_validate_flags    = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMITS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
198         it.frame                    = it.tur_head.frame = 1;
199         it.ammo_flags               = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIEVE;
200
201         // Convert from dgr / sec to dgr / tic
202         it.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate);
203         it.tur_head.aim_speed = it.tur_head.aim_speed / (1 / it.ticrate);
204 }
205
206 #endif // SVQC
207 #ifdef CSQC
208
209 void ewheel_draw(entity this)
210 {
211         float dt;
212
213         dt = time - this.move_time;
214         this.move_time = time;
215         if (dt <= 0) {
216                 return;
217         }
218
219         fixedmakevectors(this.angles);
220         setorigin(this, this.origin + this.velocity * dt);
221         this.tur_head.angles += dt * this.tur_head.avelocity;
222
223         if (this.health < 127) {
224                 if (random() < 0.05) {
225                         te_spark(this.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
226                 }
227         }
228 }
229
230 METHOD(EWheel, tr_setup, void(EWheel this, entity it))
231 {
232         it.gravity      = 1;
233         set_movetype(it, MOVETYPE_BOUNCE);
234         it.move_time        = time;
235         it.draw         = ewheel_draw;
236 }
237
238 #endif // CSQC