2 MauveBot v1.0 for Nexuiz
5 float intermission_running;
13 float THREAT_UNFLAGGED = 0;
14 float THREAT_IGNORE = -1;
16 float DODGE_DIST = 500;
17 float SEARCH_DIST = 1000;
23 string(float r) BotName =
27 self.playermodel = "models/player/visitant.zym";
28 self.playerskin = "0";
33 self.playermodel = "models/player/marine.zym";
34 self.playerskin = "0";
39 self.playermodel = "models/player/specop.zym";
40 self.playerskin = "0";
45 self.playermodel = "models/player/nexus.zym";
46 self.playerskin = "0";
51 self.playermodel = "models/player/skadi.zym";
52 self.playerskin = "0";
57 self.playermodel = "models/player/lurk.zym";
58 self.playerskin = "0";
63 self.playermodel = "models/player/headhunter.zym";
64 self.playerskin = "0";
69 self.playermodel = "models/player/carni.zym";
70 self.playerskin = "0";
75 self.playermodel = "models/player/grunt.zym";
76 self.playerskin = "0";
81 self.playermodel = "models/player/insurrectionist.zym";
82 self.playerskin = "0";
83 return "Insurrectionist";
87 self.playermodel = "models/player/jeandarc.zym";
88 self.playerskin = "0";
93 self.playermodel = "models/player/lycanthrope.zym";
94 self.playerskin = "0";
99 self.playermodel = "models/player/pyria.zym";
100 self.playerskin = "0";
105 self.playermodel = "models/player/shock.zym";
106 self.playerskin = "0";
111 self.playermodel = "models/player/marine.zym";
112 self.playerskin = "1";
117 self.playermodel = "models/player/nexus.zym";
118 self.playerskin = "1";
123 self.playermodel = "models/player/skadi.zym";
124 self.playerskin = "1";
129 self.playermodel = "models/player/lurk.zym";
130 self.playerskin = "1";
135 self.playermodel = "models/player/crash.zym";
136 self.playerskin = "2";
141 self.playermodel = "models/player/crash.zym";
142 self.playerskin = "1";
147 self.playermodel = "models/player/insurrectionist.zym";
148 self.playerskin = "1";
153 self.playermodel = "models/player/jeandarc.zym";
154 self.playerskin = "1";
159 self.playermodel = "models/player/lycanthrope.zym";
160 self.playerskin = "1";
165 self.playermodel = "models/player/pyria.zym";
166 self.playerskin = "1";
171 self.playermodel = "models/player/shock.zym";
172 self.playerskin = "1";
177 self.playermodel = "models/player/crash.zym";
178 self.playerskin = "0";
184 string () PickARandomName =
190 t = find(world, classname, "player");
193 if (clienttype(self) == CLIENTTYPE_BOT)
195 t = find(t, classname, "player");
200 self.playermodel = "models/player/marine.zym";
201 self.playerskin = "0";
208 test = ceil(random() * 25);
210 t = find(world, netname, h);
217 // Adds a bot to the server
218 void() add_MauveBot =
220 local entity oldself;
225 self = spawnclient();
228 bprint("Can not add bot, server full.\n");
229 str = ftos(bot_number);
230 cvar_set("bot_number", str);
235 flo = floor(random() * 5);
237 self.clientcolors = 0;
239 self.clientcolors = 3;
241 self.clientcolors = 4;
243 self.clientcolors = 12;
245 self.clientcolors = 13;
246 self.clientcolors = self.clientcolors + self.clientcolors * 16;
248 self.netname = PickARandomName();
251 self.classname = "player";
253 self.autoswitch = 1; // bots currently need autoswitching
254 self.skill_level = cvar("skill");
255 if (self.skill_level > 10)
256 self.skill_level = 10;
257 if (self.skill_level < 1)
258 self.skill_level = 1;
261 bot_number = bot_number + 1;
264 void() remove_MauveBot =
269 flo = floor(random() * bot_number);
271 ent = find(world, classname, "player");
275 if (clienttype(ent) == CLIENTTYPE_BOT)
280 // decrease player count for lms
282 // bot was dead, so decrease dead count too
283 if(cvar("g_lms") && self.frags < 1)
286 bot_number = bot_number - 1;
291 ent = find(ent, classname, "player");
295 float (entity targ) visible =
297 local vector start, end, org;
299 // if (self.skill_level < 3)
300 // if (random() > self.skill_level / 10)
305 org = (targ.absmin + targ.absmax) * 0.5;
307 start = self.origin + self.view_ofs;
309 traceline (start, end, TRUE, self);
310 if (!(trace_inopen && trace_inwater))
311 if (trace_fraction == 1)
316 void(entity ent) bot_set_angle =
324 view = (ent.absmin + ent.absmax) * 0.5;
326 if (self.skill_level < 6)
327 view = view - ent.velocity * (0.5 / self.skill_level);
329 flo = vlen(ent.origin - self.origin) / (self.skill_level * 4);
331 view_x = view_x + (random() * flo * 2) - flo;
332 view_y = view_y + (random() * flo * 2) - flo;
333 view_z = view_z + (random() * flo * 2) - flo;
335 view = view - (self.origin + self.view_ofs);
336 self.v_angle = vectoangles(view);
337 self.v_angle_x = self.v_angle_x * -1;
338 self.angles = self.v_angle;
339 self.angles_x = self.angles_x * -1;
340 if (self.angles_x > 180)
341 self.angles_x = self.angles_x - 360;
342 if (self.angles_x != 0)
343 self.angles_x = self.angles_x / 6;
346 self.angles_x = 0;// hack!
351 local vector vec, en, diff, dir;
358 diff = en - self.origin;
360 diff = self.goalentity.origin - self.origin;
362 if (self.search_time < time)
364 self.goalentity.search_time = time + 20;
365 self.goalentity = world;
369 dir = normalize(diff);
370 dir = dir * cvar("sv_maxspeed");// - (self.velocity - dir * (self.velocity * dir));
372 makevectors(self.v_angle);
373 self.movement_x = dir * v_forward;
374 self.movement_y = dir * v_right;
375 self.movement_z = dir * v_up;
378 void() look_for_stuff =
380 local entity item, best, best2, best3;
381 local float dist, tdist, dist2, topthreat;
383 item = findradius(self.origin, 1000);
385 if (self.search_time < time)
388 if (self.enemy.health < 0)
391 if (self.enemy.deadflag)
394 dist = dist2 = SEARCH_DIST;
399 if (item.flags & FL_CLIENT)
401 if (item != self && !(cvar("teamplay") && (item.clientcolors == self.clientcolors)))
403 if ((item.health > 0) && (!item.deadflag))
407 tdist = vlen(item.origin - self.origin);
417 else if (( (item.flags & FL_ITEM) && item.model != string_null) && (item.search_time < time))
421 tdist = vlen(item.origin - self.origin);
429 if (item.threat == THREAT_UNFLAGGED)
431 if (item.classname == "missile")
433 else if (item.classname == "laserbolt")
435 else if (item.classname == "grenade")
437 else if (item.classname == "plasma")
439 else if (item.classname == "spike")
442 item.threat = THREAT_IGNORE;
446 if ((item.owner != self) || (item.velocity == '0 0 0'))
448 tdist = vlen(item.origin - self.origin);
449 if (tdist < DODGE_DIST)
451 if (item.threat / tdist > topthreat)
453 topthreat = item.threat / tdist;
461 if ((best != self.enemy) && (best != world))
463 if ((best2 != self.goalentity) && (best2 != world))
465 self.goalentity = best2;
466 self.search_time = time + 5;
468 self.dodgeent = best3;
471 void() DodgeProjectile =
475 vec = vectoangles(self.dodgeent.origin - self.origin);
478 self.goalentity = spawn();
480 if (self.dodgeent.velocity != '0 0 0')
481 setorigin(self.goalentity, self.origin + v_right * 50);
483 setorigin(self.goalentity, self.origin - v_forward * 50);
487 remove(self.goalentity);
488 self.goalentity = world;
494 if (clienttype(self) != CLIENTTYPE_BOT)
501 botnumbercvar = cvar("bot_number");
502 flo = rint(botnumbercvar);
503 if(flo != botnumbercvar)
504 cvar_set("bot_number", ftos(flo));
506 if (flo > bot_number)
508 else if (flo < bot_number)
520 self.movement = '0 0 0';
522 if (self.deadflag == DEAD_RESPAWNABLE)
527 else if (self.deadflag)
530 if (self.goalentity.model == string_null)
531 self.goalentity = world;
533 if (time > self.ai_time)
535 self.ai_time = time + (0.5 / self.skill_level) + (random() * (1 / self.skill_level));
541 bot_set_angle(self.enemy);
542 if (visible(self.enemy))
545 self.search_time = 100000;
547 else if (self.search_time == 100000)
548 self.search_time = time + 5;
549 if (self.goalentity == world)
553 self.goalentity = self.enemy;
554 if (vlen(self.enemy.origin - self.origin) < 300)
555 self.dodgeent = self.enemy;
559 else if (self.goalentity)
560 bot_set_angle(self.goalentity);
567 if (self.skill_level > 3)
569 if (visible(self.enemy))
572 self.search_time = 100000;
577 if (self.dodgeent != world)
579 else if (self.goalentity != world)