Guest User

Bot_fight.qc from SDQuake

a guest
Apr 29th, 2010
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.47 KB | None | 0 0
  1. /***********************************************
  2. *                                              *
  3. *             FrikBot Fight Code               *
  4. *      "Because I ain't no Ghandi code"        *
  5. *                                              *
  6. ***********************************************/
  7.  
  8. /*
  9.  
  10. This program is in the Public Domain. My crack legal
  11. team would like to add:
  12.  
  13. RYAN "FRIKAC" SMITH IS PROVIDING THIS SOFTWARE "AS IS"
  14. AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE
  15. ACCURACY, CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR
  16. FUNCTIONING OF THIS SOFTWARE AND/OR DOCUMENTATION. IN
  17. NO EVENT WILL RYAN "FRIKAC" SMITH BE LIABLE FOR ANY
  18. GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL,
  19. EXEMPLARY, OR SPECIAL DAMAGES, EVEN IF RYAN "FRIKAC"
  20. SMITH HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  21. DAMAGES, IRRESPECTIVE OF THE CAUSE OF SUCH DAMAGES.
  22.  
  23. You accept this software on the condition that you
  24. indemnify and hold harmless Ryan "FrikaC" Smith from
  25. any and all liability or damages to third parties,
  26. including attorney fees, court costs, and other
  27. related costs and expenses, arising out of your use
  28. of this software irrespective of the cause of said
  29. liability.
  30.  
  31. The export from the United States or the subsequent
  32. reexport of this software is subject to compliance
  33. with United States export control and munitions
  34. control restrictions. You agree that in the event you
  35. seek to export this software, you assume full
  36. responsibility for obtaining all necessary export
  37. licenses and approvals and for assuring compliance
  38. with applicable reexport restrictions.
  39.  
  40. Any reproduction of this software must contain
  41. this notice in its entirety.
  42.  
  43. */
  44.  
  45. .entity avoid;
  46.  
  47. float(entity e) bot_size_player =
  48. {
  49.     local float sz;
  50.  
  51.     sz = e.health + e.armorvalue * e.armortype;
  52.     if (e.weapon == 32)
  53.         sz = sz + 60;
  54.     else if (e.weapon == 64)
  55.         sz = sz + 60;
  56.     else if (e.weapon == 16)
  57.         sz = sz + 50;
  58.     else if (e.weapon == 8)
  59.         sz = sz + 50;
  60.     else if (e.weapon == 4)
  61.         sz = sz + 40;
  62.     else if (e.weapon == 2)
  63.         sz = sz + 40;
  64.     else if (e.weapon == 1)
  65.         sz = sz + 10;
  66.     else if (e.weapon == 4096)
  67.         sz = sz - 50;
  68.     if ((e.items & 4194304) || (e.ringofpower_time))// Quad
  69.         sz = sz + 200;
  70.     if (e.items & 1048576) // Invul
  71.         sz = sz + 300;
  72.     if (e.items & 524288) // Invis
  73.         sz = sz + 250;
  74.     return sz;
  75. };
  76.  
  77. void() bot_dodge_stuff =
  78. {
  79.     local entity foe;
  80.     local float foedist, avdist, scandist, foesz, flen, tsz;
  81.     local vector v;
  82.  
  83.     if (waypoint_mode > WM_LOADED)
  84.         return;
  85.  
  86.     self.avoid = world;
  87.  
  88.  
  89.     if (self.enemy)
  90.     {
  91.         v = self.origin - realorigin(self.enemy);
  92.         foedist = vlen(v);
  93.         foesz = bot_size_player(self.enemy);
  94.     }
  95.     else
  96.     {
  97.         foedist = 3000;
  98.         foesz = 9999999;
  99.     }
  100.     avdist = 256;
  101.  
  102.     foe = find(world, classname, "grenade");
  103.     while(foe)
  104.     {
  105.         flen = vlen(foe.origin - self.origin);
  106.         if (flen < avdist)
  107.         {
  108.             avdist = flen;
  109.             self.avoid = foe;
  110.         }
  111.         foe = find(foe, classname, "grenade");
  112.     }
  113.     if (!self.avoid)
  114.     {
  115.         foe = find(world, classname, "missile");
  116.         while(foe)
  117.         {
  118.             if (foe.owner != self)
  119.             {
  120.                 flen = vlen(foe.origin - self.origin);
  121.                 if (flen < avdist)
  122.                 {
  123.                     avdist = flen;
  124.                     self.avoid = foe;
  125.                 }
  126.             }
  127.             foe = find(foe, classname, "missile");
  128.         }
  129.         if (!self.avoid)
  130.         {
  131.             foe = find(world, classname, "sddblossom");
  132.             while(foe)
  133.             {
  134.                 if (foe.owner != self)
  135.                 {
  136.                     flen = vlen(foe.origin - self.origin);
  137.                     if (flen < avdist)
  138.                     {
  139.                         avdist = flen;
  140.                         self.avoid = foe;
  141.                     }
  142.                 }
  143.                 foe = find(foe, classname, "sddblossom");
  144.             }
  145.             if (!self.avoid) //added
  146.             {
  147.                 foe = find(world, classname, "holo");
  148.                 while(foe)
  149.                 {
  150.                     flen = vlen(foe.origin - self.origin);
  151.                     if (flen < avdist)
  152.                     {
  153.                         avdist = flen;
  154.                         self.avoid = foe;
  155.                     }
  156.                     foe = find(foe, classname, "holo");
  157.                 }
  158.                 if (!self.avoid) //added for orbital bombardment
  159.                 {
  160.                     foe = find(world, classname, "vortex");
  161.                     while(foe)
  162.                     {
  163.                         flen = vlen(foe.origin - self.origin);
  164.                         if (flen < avdist)
  165.                         {
  166.                             avdist = flen;
  167.                             self.avoid = foe;
  168.                         }
  169.                         foe = find(foe, classname, "vortex");
  170.                     }
  171.                 }
  172.             }
  173.         }
  174.     if (coop)
  175.     {
  176.         if (!self.enemy)
  177.         {
  178.             foe = findradius(self.origin, foedist);
  179.             while(foe)
  180.             {
  181.                 if((foe.flags & FL_MONSTER) && (foe.classname != "robot_helper") && (foe.classname != "duke_helper")) //changed for robot helper
  182.                 {
  183.                     if(foe.health > 0)
  184.                     {
  185.                         flen = vlen(foe.origin - self.origin);
  186.                         if (flen < foedist)
  187.                         {
  188.                             tsz = bot_size_player(foe);
  189.                             if (tsz < foesz)
  190.                             {
  191.                                 if (fisible(foe))
  192.                                 {
  193.                                     self.enemy = foe;
  194.                                     foedist = flen;
  195.                                     foesz = tsz;
  196.                                 }
  197.                             }
  198.                         }
  199.                     }
  200.                 }
  201.                 foe = foe.chain;
  202.             }
  203.         }      
  204.     }
  205.     else
  206.     {
  207.         foe = player_head;
  208.         while(foe)
  209.         {
  210.             if(foe != self)
  211.             {
  212.                 if (foe.modelindex != 0)
  213.                 {
  214.                     if (foe.health > 0)
  215.                     {
  216.                         if (!(teamplay && self.team == foe.team))
  217.                         {
  218.                             flen = vlen(foe.origin - self.origin);
  219.                             if (flen < foedist)
  220.                             {
  221.                                 tsz = bot_size_player(foe);
  222.                                 if (tsz < foesz)
  223.                                 {
  224.                                     if (fov(foe) || foe.b_sound > time || self.b_skill == 3)
  225.                                     {
  226.                                         if (fisible(foe))
  227.                                         {
  228.                                             self.enemy = foe;
  229.                                             foedist = vlen(foe.origin - self.origin);
  230.                                         }
  231.                                     }
  232.                                 }
  233.                             }
  234.                         }
  235.                     }
  236.                 }
  237.             }
  238.             foe = foe._next;
  239.         }
  240.     }
  241. }
  242. };
  243.  
  244.  
  245.  
  246.  
  247. /*
  248. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  249.  
  250. weapon_range
  251.  
  252. _x "sweet spot range" - try to maintain this range if possible
  253. _y minimum range bot can be to be effective (rl/gl) (move away)
  254. _z maximum range bot can be to be effective (lg/axe) (move in)
  255. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  256. */
  257.  
  258. vector(float wep, float typ) weapon_range =
  259. {
  260.     if (wep == 4096) // IT_AXE
  261.     {
  262.         if (self.skin == 6)
  263.         {
  264.             if (typ == 0 || typ == 3)
  265.                 return '128 0 2048'; //hail/lightning
  266.             else if (typ == 2)
  267.                 return '128 0 512'; //plague
  268.             else
  269.                 return '512 256 2048'; //fire
  270.         }
  271.         else
  272.         {
  273.             if (typ == 4 || typ == 5)
  274.                 return '256 0 3000'; //magic buzzsaw/throwing axe
  275.             else //
  276.                 return '64 0 96';       //boot/sword/hammer
  277.         }
  278.     }
  279.     else if (wep == 1) // IT_SHOTGUN
  280.     {
  281.         if (typ == 2) return '256 128 1024';
  282.         return '128 0 2048'; //all weapons pretty much close quarters instant hit.
  283.     }
  284.     else if (wep == 2) // IT_SUPER_SHOTGUN
  285.     {  
  286.         //duke shot/superduper shot/e rifle/railgun/m60
  287.         return '128 0 512';
  288.     }
  289.     else if (wep == 4) // IT_NAILGUN
  290.     {
  291.         if (typ == 0) return '128 64 2048'; //slight splash dam from blazegun
  292.         else return '128 0 2048'; //shredder,
  293.     }
  294.     else if (wep == 8) // IT_SUPER_NAILGUN
  295.     {
  296.         if (typ == 0) return '128 0 512'; //heavy chaingun. was 180 0 3000
  297.         else if (typ == 1) return '256 128 1024'; //destructo gun
  298.         else if (typ == 2) return '128 64 512'; //flamethrower
  299.         else if (typ == 3) return '48 0 64'; //go kart
  300.         else return '128 0 512'; //go kart nailguns
  301.     }
  302.     else if (wep == 16) // IT_GRENADE_LAUNCHER
  303.     {
  304.         if (typ == 0) return '256 128 1024'; //dev
  305.         else if (typ == 1) return '256 0 1024'; //pds
  306.         else return '512 256 2048'; //sd dblossom, nuke grenade, deaths head, vortex
  307.     }
  308.     else if (wep == 32) // IT_ROCKET_LAUNCHER
  309.     {
  310.         if (typ < 3) return '512 256 2048'; //obliterator and freeze rockets
  311.         else return '1024 512 2048'; //world ender, doomsday
  312.     }
  313.     else if (wep == 64) // IT_LIGHTNING
  314.     {
  315.         if (typ == 0) return '192 64 2048'; //plasma
  316.         else if (typ == 1) return '512 256 2048'; //positron
  317.         else if (typ == 2) return '128 0 512'; //proton storm
  318.         else if (typ == 3) return '350 0 600'; //lg
  319.         else if (typ < 6) return '128 0 512'; //holo/grav well
  320.         else return '512 256 2048'; //orb bomb/napalm
  321.     }
  322.     else if (wep == IT_EXTRA_WEAPON) //
  323.     {
  324.         if (typ == 0) return '128 64 2048'; //double blazegun
  325.         else if (typ == 1) return '128 0 1024'; //nailgun
  326.         else if (typ == 2) return '128 0 512'; //twin chaingun
  327.         else return '512 128 1024'; //twin antimatter/FBOMBS/OBLITERATOR
  328.     }
  329. };
  330.  
  331. /*
  332. bondo's mod to frikbot to return weapon type and try to avoid close quarters nuking
  333. */
  334. float (entity boob) weapon_type = {
  335.  
  336.     local float nerd;
  337.    
  338.     nerd = boob.weapon;
  339.    
  340.     if (nerd == IT_AXE)
  341.         return boob.axetype;
  342.     else if (nerd == IT_SHOTGUN)
  343.         return boob.shotguntype;
  344.     else if (nerd == IT_SUPER_SHOTGUN)
  345.         return boob.supershotguntype;
  346.     else if (nerd == IT_NAILGUN)
  347.         return boob.nailguntype;
  348.     else if (nerd == IT_SUPER_NAILGUN)
  349.         return boob.supernailguntype;
  350.     else if (nerd == IT_GRENADE_LAUNCHER)
  351.         return boob.grenadetype;
  352.     else if (nerd == IT_ROCKET_LAUNCHER)
  353.         return boob.rockettype;
  354.     else if (nerd == IT_EXTRA_WEAPON)
  355.         return boob.extraweapontype;
  356.     else
  357.         return boob.cellguntype;
  358. };
  359.  
  360.  
  361.  
  362. /*
  363. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  364.  
  365. bot_weapon_switch
  366.  
  367. Pick a weapon based on range / ammo
  368.  
  369. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  370. */
  371.  
  372.  
  373. void(float brange) bot_weapon_switch =
  374. {
  375.  
  376.     if (coop & FBOMB_MODE || deathmatch & FBOMB_MODE ||
  377.          coop & LIGHTSABER_MODE || deathmatch & LIGHTSABER_MODE ||
  378.          deathmatch & PROTONSTORM_MODE || coop & PROTONSTORM_MODE)
  379.         return;
  380.    
  381.  
  382.     local   float   it, flag, pulse, nerd;
  383.     local vector v;
  384.  
  385.     it = self.items & 127;
  386.  
  387.     while(it)
  388.     {
  389.         if (coop & JESUS_MODE || deathmatch & JESUS_MODE)
  390.         {
  391.             flag = 4096;
  392.             pulse = 1;
  393.         }
  394.         else if (coop & GOKART_MODE || deathmatch & GOKART_MODE)
  395.         {
  396.             flag = 8;
  397.             pulse = 5;
  398.         }
  399.         else if ((self.ammo_rockets >= 1) && (it & 32))
  400.         {
  401.             flag = 32;
  402.             pulse = 7;
  403.         }
  404.         else if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & 64))
  405.         {
  406.             flag = 64;
  407.             pulse = 8;
  408.         }
  409.         //SUPER NAILGUN
  410.         else if(self.ammo_nails >= 2 && (it & 8))
  411.         {
  412.             flag = 8;
  413.             pulse = 5;
  414.         }
  415.         else if ((self.ammo_rockets >= 1) && (it & 16))
  416.         {
  417.             flag = 16;
  418.             pulse = 6;
  419.         }
  420.         else if(self.ammo_shells >= 2 && (it & 2))
  421.         {
  422.             flag = 2;
  423.             pulse = 3;
  424.         }
  425.         else if(self.ammo_nails >= 1 && (it & 4))
  426.         {
  427.             flag = 4;
  428.             pulse = 4;
  429.         }
  430.         else if(self.ammo_shells >= 1 && (it & 1))
  431.         {
  432.             flag = 1;
  433.             pulse = 2;
  434.         }
  435.         else
  436.         {
  437.             if (pulse)
  438.                 self.impulse = pulse;
  439.             return;
  440.         }
  441.  
  442.         if (brange == -1)
  443.         {
  444.             if (pulse)
  445.                 self.impulse = pulse;
  446.             return;
  447.         }
  448.  
  449.         nerd = weapon_type(self); //bondo
  450.        
  451.         v = weapon_range(flag, nerd);
  452.         if (brange < v_y || brange > v_z)
  453.             it = it - flag;
  454.         else
  455.         {
  456.             if (pulse)
  457.                 self.impulse = pulse;
  458.             return;
  459.         }
  460.     }
  461. };
  462.  
  463. void() bot_shoot =
  464. {
  465.     // quick little function to stop making him shoot the wrong way ! Argh
  466.     local float g;
  467.     g = angcomp(self.v_angle_x, self.b_angle_x);
  468.     if (fabs(g) > 30)
  469.         return; // argh, too far away
  470.     g = angcomp(self.v_angle_y, self.b_angle_y);
  471.     if (fabs(g) > 30)
  472.         return; // not again!
  473.     self.button0 = TRUE;
  474. };
  475.  
  476. /*
  477. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  478.  
  479. Bot_fight_style
  480.  
  481. This is the core of the bot's thinking when
  482. attacking an enemy.
  483.  
  484. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  485. */
  486.  
  487. void() bot_fight_style =
  488. {
  489.     local vector v, v1, v2, org;
  490.     local float foedist, mysz, foesz, nerd;
  491.  
  492.     //bondo
  493.     local entity boob;
  494.  
  495.     if (self.enemy.health <= 0)
  496.     {
  497.         self.enemy = world;
  498.         return;
  499.     }
  500.     else if (!self.enemy.takedamage)
  501.     {
  502.         self.enemy = world;
  503.         return;
  504.     }
  505.     else if (!fisible(self.enemy))
  506.     {
  507.         self.enemy = world;
  508.         return;
  509.     }
  510.  
  511.     org = realorigin(self.enemy);
  512.     makevectors(self.v_angle);
  513.  
  514.     // decide if I should shoot
  515.  
  516.     foedist = vlen(org - self.origin);
  517.     nerd = weapon_type(self);
  518.     v = weapon_range(self.weapon,nerd);
  519.  
  520.  
  521.     if (foedist > v_y && foedist < v_z)
  522.     {
  523.         traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * v_z, FALSE, self);
  524.         if (vlen(trace_endpos - (self.origin + self.view_ofs)) >= v_y)
  525.         {
  526.             boob = find(world,classname,"player"); //new
  527.             while (boob != world) //new
  528.             {
  529.                 // try to avoid shooting teammates
  530.                 if ((trace_ent.team == self.team && teamplay) || coop)
  531.                 {
  532.                     if (trace_ent.classname == "player") return;
  533.                     if (vlen(self.origin - boob.origin) < 512 && self.weapon == IT_ROCKET_LAUNCHER)  //new
  534.                         return; //new
  535.                     else  //new
  536.                         bot_shoot();
  537.                     boob = find(boob,classname,"player"); //new
  538.                 }
  539.             }
  540.         }
  541.     }
  542.     else
  543.         bot_weapon_switch(foedist);
  544.  
  545.     if (!(self.b_aiflags & (AI_PRECISION | AI_BLIND | AI_OBSTRUCTED)))
  546.     {
  547.  
  548.         //bot_size_player returns health for monsters
  549.         foesz = bot_size_player(self.enemy);
  550.         mysz = bot_size_player(self) + 5;
  551.  
  552.         if (foesz > mysz)
  553.         {
  554.             if (teamplay)
  555.             {
  556.                 if (random() < 0.02)
  557.                 {
  558.                     bot_start_topic(5);
  559.                     self.b_chattime = 1;
  560.                 }
  561.             }
  562.            
  563.             return;
  564.         }
  565.         else if (mysz < 140)
  566.             return;
  567.         else if (self.avoid) //if you have something to avoid
  568.         {
  569.             if (self.avoid.velocity) //it's moving
  570.                 v = self.avoid.velocity;
  571.             else
  572.                 v = normalize(self.avoid.origin - self.origin);
  573.             v1_x = v_y;
  574.             v1_y = v_y * -1;
  575.             v2_x = v_y;
  576.             v2_y = v_y * -1;
  577.             foedist = vlen(self.avoid.origin - (self.origin + v1));
  578.             if (foedist < vlen(self.avoid.origin - (self.origin + v2)))
  579.                 frik_walkmove(v2);
  580.             else
  581.                 frik_walkmove(v1);
  582.         }
  583.         else if (!self.enemy.flags & FL_MONSTER)
  584.         {
  585.             if (foedist + 32 <  v_x)
  586.                 frik_walkmove(self.origin - org);
  587.             else if (foedist - 32 >  v_x)
  588.                 frik_walkmove(org - self.origin);
  589.             else if (self.wallhug)
  590.                 frik_walkmove(v_right);
  591.             else
  592.                 frik_walkmove(v_right * -1);
  593.         }
  594.     }
  595.     else
  596.     {
  597.         foesz = bot_size_player(self.enemy);
  598.         mysz = bot_size_player(self) + 5;
  599.  
  600.         if (foesz > mysz)
  601.             return;
  602.         else if (mysz < 140)
  603.             return;
  604.         self.keys = self.keys & 960;
  605.     }
  606. };
Advertisement
Add Comment
Please, Sign In to add comment