3 void() havocbot_chooserole;
5 vector() havocbot_dodge =
8 local vector dodge, v, n;
9 local float danger, bestdanger, vl, d;
12 // check for dangerous objects near bot or approaching bot
13 head = findchainfloat(bot_dodge, TRUE);
16 if (head.owner != self)
18 vl = vlen(head.velocity);
19 if (vl > sv_maxspeed * 0.3)
21 n = normalize(head.velocity);
22 v = self.origin - head.origin;
24 if (d > (0 - head.bot_dodgerating))
25 if (d < (vl * 0.2 + head.bot_dodgerating))
27 // calculate direction and distance from the flight path, by removing the forward axis
28 v = v - (n * (v * n));
29 danger = head.bot_dodgerating - vlen(v);
30 if (bestdanger < danger)
33 // dodge to the side of the object
40 danger = head.bot_dodgerating - vlen(head.origin - self.origin);
41 if (bestdanger < danger)
44 dodge = normalize(self.origin - head.origin);
53 //.float havocbotignoretime;
54 void() havocbot_movetogoal =
62 local vector evadeobstacle;
63 local vector evadelava;
67 //if (self.goalentity)
68 // te_lightning2(self, self.origin, (self.goalentity.absmin + self.goalentity.absmax) * 0.5);
69 self.movement = '0 0 0';
70 if (self.goalcurrent == world)
72 navigation_poptouchedgoals();
73 if (self.goalcurrent == world)
75 // ran out of goals, rethink strategy as soon as possible
76 self.bot_strategytime = 0;
79 evadeobstacle = '0 0 0';
81 m1 = self.goalcurrent.origin + self.goalcurrent.mins;
82 m2 = self.goalcurrent.origin + self.goalcurrent.maxs;
83 destorg = self.origin;
84 destorg_x = bound(m1_x, destorg_x, m2_x);
85 destorg_y = bound(m1_y, destorg_y, m2_y);
86 destorg_z = bound(m1_z, destorg_z, m2_z);
87 diff = destorg - self.origin;
89 dir = normalize(diff);
90 flatdir = diff;flatdir_z = 0;
91 flatdir = normalize(flatdir);
94 if (!(self.flags & FL_ONGROUND))
96 // prevent goal checks when we can't walk
97 if (self.bot_strategytime < time + 0.1)
98 self.bot_strategytime = time + 0.1;
102 // jump if going toward an obstacle that doesn't look like stairs we
103 // can walk up directly
104 tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 0.2, FALSE, self);
105 if (trace_fraction < 1)
106 if (trace_plane_normal_z < 0.7)
109 tracebox(self.origin + '0 0 16', self.mins, self.maxs, self.origin + self.velocity * 0.2 + '0 0 16', FALSE, self);
110 if (trace_fraction < s + 0.01)
111 if (trace_plane_normal_z < 0.7)
114 tracebox(self.origin + '0 0 48', self.mins, self.maxs, self.origin + self.velocity * 0.2 + '0 0 48', FALSE, self);
115 if (trace_fraction > s)
120 traceline(self.origin + self.velocity * 0.3, self.origin + self.velocity * 0.3 + '0 0 -1000', TRUE, world);
121 s = pointcontents(trace_endpos + '0 0 1');
122 if (s == CONTENT_LAVA || s == CONTENT_SLIME)
123 evadelava = normalize(self.velocity) * -1;
127 dodge = havocbot_dodge();
128 dir = normalize(dir + dodge + evadeobstacle + evadelava) * 400;
129 makevectors(self.v_angle);
130 self.movement_x = dir * v_forward;
131 self.movement_y = dir * v_right;
132 self.movement_z = dir * v_up;
135 .float havocbot_chooseenemy_finished;
136 void() havocbot_chooseenemy =
138 local entity head, best;
139 local float rating, bestrating;
141 if (cvar("bot_nofire"))
146 if (time < self.havocbot_chooseenemy_finished)
148 self.havocbot_chooseenemy_finished = time + cvar("bot_ai_enemydetectioninterval");
149 eye = (self.origin + self.view_ofs);
151 bestrating = 100000000;
152 head = findchainfloat(bot_attack, TRUE);
155 v = (head.absmin + head.absmax) * 0.5;
156 rating = vlen(v - eye);
157 if (bestrating > rating)
158 if (bot_shouldattack(head))
160 traceline(eye, v, TRUE, self);
161 if (trace_ent == head || trace_fraction >= 1)
172 float(entity e) w_getbestweapon;
173 void() havocbot_chooseweapon =
175 self.switchweapon = w_getbestweapon(self);
179 void() havocbot_aim =
181 local vector selfvel, enemyvel;
182 if (time < self.nextaim)
184 self.nextaim = time + 0.1;
185 selfvel = self.velocity;
186 if (!self.waterlevel)
190 enemyvel = self.enemy.velocity;
191 if (!self.enemy.waterlevel)
193 lag_additem(time + self.ping, 0, 0, self.enemy, self.origin, selfvel, self.enemy.origin, enemyvel);
196 lag_additem(time + self.ping, 0, 0, world, self.origin, selfvel, self.goalcurrent.origin, '0 0 0');
201 if (bot_strategytoken == self)
202 self.havocbot_role();
203 havocbot_chooseenemy();
204 havocbot_chooseweapon();
207 if (self.bot_aimtarg)
208 weapon_action(self.weapon, WR_AIM);
209 else if (self.goalcurrent)
212 v = self.goalcurrent.origin - self.origin;
214 if (self.waterlevel < 2)
216 //dprint("walk at:", vtos(v), "\n");
217 //te_lightning2(world, self.origin, self.goalcurrent.origin);
220 havocbot_movetogoal();
223 void() havocbot_setupbot =
225 self.bot_ai = havocbot_ai;
226 // will be updated by think code
227 havocbot_chooserole();