Xonotic
ewheel.qc
Go to the documentation of this file.
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(turret_closetotarget(this, this.pathcurrent.origin))
21  {
22 #ifdef EWHEEL_FANCYPATH
23  if (this.pathcurrent.path_next == NULL)
24  {
25  // Path endpoint reached
26  pathlib_deletepath(this.pathcurrent.owner);
27  this.pathcurrent = NULL;
28 
29  if (this.pathgoal)
30  {
31  if (this.pathgoal.use)
32  this.pathgoal.use(this.pathgoal, NULL, NULL);
33 
34  if (this.pathgoal.enemy)
35  {
36  this.pathcurrent = pathlib_astar(this, this.pathgoal.origin,this.pathgoal.enemy.origin);
37  this.pathgoal = this.pathgoal.enemy;
38  }
39  }
40  else
41  this.pathgoal = NULL;
42  }
43  else
44  this.pathcurrent = this.pathcurrent.path_next;
45 #else
46  this.pathcurrent = this.pathcurrent.enemy;
47 #endif
48  }
49 
50  if (this.pathcurrent)
51  {
52  this.moveto = this.pathcurrent.origin;
53  this.steerto = steerlib_attract2(this, this.moveto, 0.5, 500, 0.95);
54 
55  movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
56  }
57 }
58 
59 void ewheel_move_enemy(entity this)
60 {
61  int newframe;
62 
63  this.steerto = steerlib_arrive(this, this.enemy.origin,this.target_range_optimal);
64 
65  this.moveto = this.origin + this.steerto * 128;
66 
67  if (this.tur_dist_enemy > this.target_range_optimal)
68  {
69  if ( this.tur_head.spawnshieldtime < 1 )
70  {
71  newframe = ewheel_anim_fwd_fast;
72  movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_fast), 0.4);
73  }
74  else if (this.tur_head.spawnshieldtime < 2)
75  {
76 
77  newframe = ewheel_anim_fwd_slow;
78  movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
79  }
80  else
81  {
82  newframe = ewheel_anim_fwd_slow;
83  movelib_move_simple(this, v_forward, (autocvar_g_turrets_unit_ewheel_speed_slower), 0.4);
84  }
85  }
86  else if (this.tur_dist_enemy < this.target_range_optimal * 0.5)
87  {
88  newframe = ewheel_anim_bck_slow;
89  movelib_move_simple(this, v_forward * -1, (autocvar_g_turrets_unit_ewheel_speed_slow), 0.4);
90  }
91  else
92  {
93  newframe = ewheel_anim_stop;
94  movelib_brake_simple(this, (autocvar_g_turrets_unit_ewheel_speed_stop));
95  }
96 
97  turrets_setframe(this, newframe, false);
98 }
99 
100 void ewheel_move_idle(entity this)
101 {
102  if(this.frame != 0)
103  {
104  this.SendFlags |= TNSF_ANIM;
105  this.anim_start_time = time;
106  }
107 
108  this.frame = 0;
109  if(this.velocity)
110  movelib_brake_simple(this, (autocvar_g_turrets_unit_ewheel_speed_stop));
111 }
112 
113 void ewheel_findtarget(entity this)
114 {
115  entity e = find(NULL, targetname, this.target);
116  if (!e)
117  {
118  LOG_TRACE("Initital waypoint for ewheel does NOT exist, fix your map!");
119  this.target = "";
120  }
121 
122  if (e.classname != "turret_checkpoint")
123  LOG_TRACE("Warning: not a turret path");
124  else
125  {
126 
127 #ifdef EWHEEL_FANCYPATH
128  this.pathcurrent = pathlib_astar(this, this.origin, e.origin);
129  this.pathgoal = e;
130 #else
131  this.pathcurrent = e;
132 #endif
133  }
134 }
135 
136 spawnfunc(turret_ewheel) { if(!turret_initialize(this, TUR_EWHEEL)) delete(this); }
137 
138 METHOD(EWheel, tr_think, void(EWheel thistur, entity it))
139 {
140  vector wish_angle, real_angle;
141 
142  float vz = it.velocity_z;
143 
144  it.angles_x = anglemods(it.angles_x);
145  it.angles_y = anglemods(it.angles_y);
146 
147  fixedmakevectors(it.angles);
148 
149  wish_angle = normalize(it.steerto);
150  wish_angle = vectoangles(wish_angle);
151  real_angle = wish_angle - it.angles;
152  real_angle = shortangle_vxy(real_angle, it.tur_head.angles);
153 
154  it.tur_head.spawnshieldtime = fabs(real_angle_y);
155  real_angle_y = bound(-it.tur_head.aim_speed, real_angle_y, it.tur_head.aim_speed);
156  it.angles_y = (it.angles_y + real_angle_y);
157 
158  if(it.enemy)
159  ewheel_move_enemy(it);
160  else if(it.pathcurrent)
161  ewheel_move_path(it);
162  else
163  ewheel_move_idle(it);
164 
165  it.velocity_z = vz;
166 
167  if(it.velocity)
168  it.SendFlags |= TNSF_MOVE;
169 }
170 
171 METHOD(EWheel, tr_death, void(EWheel this, entity it))
172 {
173  it.velocity = '0 0 0';
174 
175 #ifdef EWHEEL_FANCYPATH
176  if (it.pathcurrent)
177  pathlib_deletepath(it.pathcurrent.owner);
178 #endif
179  it.pathcurrent = NULL;
180 }
181 
182 METHOD(EWheel, tr_setup, void(EWheel this, entity it))
183 {
184  if(it.move_movetype == MOVETYPE_WALK)
185  {
186  it.velocity = '0 0 0';
187  it.enemy = NULL;
188 
189  setorigin(it, it.pos1);
190 
191  if (it.target != "")
192  InitializeEntity(it, ewheel_findtarget, INITPRIO_FINDTARGET);
193  }
194 
195  it.iscreature = true;
196  it.teleportable = TELEPORT_NORMAL;
197  if(!it.damagedbycontents)
199  it.damagedbycontents = true;
201  it.solid = SOLID_SLIDEBOX;
202  it.takedamage = DAMAGE_AIM;
203  it.idle_aim = '0 0 0';
204  it.pos1 = it.origin;
207  it.frame = it.tur_head.frame = 1;
209 
210  // Convert from dgr / sec to dgr / tic
211  it.tur_head.aim_speed = (autocvar_g_turrets_unit_ewheel_turnrate);
212  it.tur_head.aim_speed = it.tur_head.aim_speed / (1 / it.ticrate);
213 }
214 
215 #endif // SVQC
216 #ifdef CSQC
217 
218 void ewheel_draw(entity this)
219 {
220  float dt;
221 
222  dt = time - this.move_time;
223  this.move_time = time;
224  if(dt <= 0)
225  return;
226 
227  fixedmakevectors(this.angles);
228  setorigin(this, this.origin + this.velocity * dt);
229  this.tur_head.angles += dt * this.tur_head.avelocity;
230 
231  if(GetResource(this, RES_HEALTH) < 127)
232  if(random() < 0.05)
233  te_spark(this.origin + '0 0 40', randomvec() * 256 + '0 0 256', 16);
234 }
235 
236 METHOD(EWheel, tr_setup, void(EWheel this, entity it))
237 {
238  it.gravity = 1;
240  it.move_time = time;
241  it.draw = ewheel_draw;
242 }
243 
244 #endif // CSQC
const float SOLID_SLIDEBOX
Definition: csprogsdefs.qc:247
float MOVETYPE_WALK
Definition: progsdefs.qc:249
ERASEABLE float anglemods(float v)
Definition: angle.qc:13
entity pathgoal
Definition: sv_turrets.qh:89
const int TNSF_ANIM
Definition: turret.qh:174
const int TELEPORT_NORMAL
Definition: teleporters.qh:26
entity pathlib_astar(entity this, vector from, vector to)
Definition: main.qc:353
vector steerto
Definition: steerlib.qh:3
entity tur_head
Definition: sv_turrets.qh:29
IntrusiveList g_damagedbycontents
Definition: damage.qh:155
entity() spawn
float DAMAGE_AIM
Definition: progsdefs.qc:284
bool turret_initialize(entity this, Turret tur)
spawnfunc(info_player_attacker)
Definition: sv_assault.qc:283
origin
Definition: ent_cs.qc:114
void turrets_setframe(entity this, float _frame, float client_only)
float MOVETYPE_BOUNCE
Definition: progsdefs.qc:256
#define METHOD(cname, name, prototype)
Definition: oo.qh:257
const int TFL_AMMO_RECHARGE
Definition: turret.qh:143
float tur_dist_enemy
Definition: sv_turrets.qh:35
const int TFL_TARGETSELECT_PLAYERS
Definition: turret.qh:65
const int TFL_TARGETSELECT_LOS
Definition: turret.qh:64
RES_HEALTH
Definition: ent_cs.qc:126
entity enemy
Definition: sv_ctf.qh:143
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define NULL
Definition: post.qh:17
float anim_start_time
Definition: turret.qh:173
const int TFL_AMMO_RECIEVE
Definition: turret.qh:144
entity pathcurrent
Definition: sv_turrets.qh:87
vector steerlib_arrive(entity this, vector point, float maximal_distance)
Pull toward a point, The further away, the stronger the pull.
Definition: steerlib.qc:27
vector(float skel, float bonenum) _skel_get_boneabs_hidden
const int TFL_TARGETSELECT_TEAMCHECK
Definition: turret.qh:70
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
Definition: cl_resources.qc:10
void InitializeEntity(entity e, void(entity this) func, int order)
Definition: world.qc:2146
float move_time
Definition: movetypes.qh:77
#define LOG_TRACE(...)
Definition: log.qh:81
vector steerlib_attract2(entity this, vector point, float min_influense, float max_distance, float max_influense)
Definition: steerlib.qc:45
bool turret_closetotarget(entity this, vector targ)
const int TFL_AMMO_ENERGY
Definition: turret.qh:140
string targetname
Definition: progsdefs.qc:194
float frame
primary framegroup animation (strength = 1 - lerpfrac - lerpfrac3 - lerpfrac4)
Definition: anim.qh:6
setorigin(ent, v)
vector angles
Definition: csprogsdefs.qc:104
ERASEABLE vector shortangle_vxy(vector ang1, vector ang2)
Definition: angle.qc:58
string target
Definition: progsdefs.qc:193
void pathlib_deletepath(entity start)
Definition: main.qc:10
float time
Definition: csprogsdefs.qc:16
vector velocity
Definition: csprogsdefs.qc:103
const int TNSF_MOVE
Definition: turret.qh:172
#define fixedmakevectors
void set_movetype(entity this, int mt)
const int TFL_TARGETSELECT_RANGELIMITS
Definition: turret.qh:69
Definition: ewheel.qh:7
vector v_forward
Definition: csprogsdefs.qc:31