]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/bot/havocbot/role_assault.qc
Merge branch 'mand1nga/bot-fix-aiming-origins' into mand1nga/bot-assault
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / bot / havocbot / role_assault.qc
1 #define HAVOCBOT_AST_ROLE_NONE          0
2 #define HAVOCBOT_AST_ROLE_DEFENSE       2
3 #define HAVOCBOT_AST_ROLE_OFFENSE       8
4
5 .float havocbot_role_flags;
6 .float havocbot_attack_time;
7
8 .void() havocbot_role;
9 .void() havocbot_previous_role;
10
11 void() havocbot_role_ast_defense;
12 void() havocbot_role_ast_offense;
13 .entity havocbot_ast_target;
14
15 void(entity bot) havocbot_ast_reset_role;
16
17 void(float ratingscale, vector org, float sradius) havocbot_goalrating_items;
18 void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers;
19 .entity assault_decreaser;
20
21 void havocbot_goalrating_ast_targets(float ratingscale)
22 {
23         entity ad, best, pl, wp, tod;
24         float radius, found, bestvalue, c;
25         vector p;
26
27         ad = findchain(classname, "func_assault_destructible");
28
29         for (; ad; ad = ad.chain)
30         {
31                 if (ad.target == "")
32                         continue;
33
34                 found = FALSE;
35                 for(tod = world; (tod = find(tod, targetname, ad.target)); )
36                 {
37                         if(tod.classname == "target_objective_decrease")
38                         {
39                                 if(tod.enemy.health < ASSAULT_VALUE_INACTIVE)
40                                 {
41                                         found = TRUE;
42                                         break;
43                                 }
44                         }
45                 }
46
47                 if(!found)
48                         continue;
49
50                 p = 0.5 * (ad.absmin + ad.absmax);
51         //      dprint(vtos(ad.origin), " ", vtos(ad.absmin), " ", vtos(ad.absmax),"\n");
52                 te_knightspike(p);
53                 te_lightning2(world, '0 0 0', p);
54
55                 // Find and rate waypoints around it
56                 found = FALSE;
57                 best = world;
58                 bestvalue = 99999999999;
59                 for(radius=0; radius<1000 && !found; radius+=500)
60                 {
61                         for(wp=findradius(p, radius); wp; wp=wp.chain)
62                         {
63                                 if(!(wp.wpflags & WAYPOINTFLAG_GENERATED))
64                                 if(wp.classname=="waypoint")
65                                 if(checkpvs(wp.origin, ad))
66                                 {
67                                         found = TRUE;
68                                         if(wp.cnt<bestvalue)
69                                         {
70                                                 best = wp;
71                                                 bestvalue = wp.cnt;
72                                         }
73                                 }
74                         }
75                 }
76
77                 if(best)
78                 {
79                         dprint("waypoints around target were found\n");
80                 //      te_lightning2(world, '0 0 0', best.origin);
81                 //      te_knightspike(best.origin);
82
83                         navigation_routerating(best, ratingscale, 10000);
84                         best.cnt += 1;
85
86                         self.havocbot_attack_time = 0;
87
88                         if(checkpvs(self.view_ofs,ad))
89                         if(checkpvs(self.view_ofs,best))
90                                 self.havocbot_attack_time = time + 2;
91                 }
92         }
93 }
94
95 void havocbot_role_ast_offense()
96 {
97         if(self.deadflag != DEAD_NO)
98         {
99                 self.havocbot_attack_time = 0;
100                 havocbot_ast_reset_role(self);
101                 return;
102         }
103
104         // Set the role timeout if necessary
105         if (!self.havocbot_role_timeout)
106                 self.havocbot_role_timeout = time + 120;
107
108         if (time > self.havocbot_role_timeout)
109         {
110                 havocbot_ast_reset_role(self);
111                 return;
112         }
113
114         if(self.havocbot_attack_time>time)
115                 return;
116
117         if (self.bot_strategytime < time)
118         {
119                 navigation_goalrating_start();
120         ///     havocbot_goalrating_enemyplayers(20000, self.origin, 650);
121
122         //      if(!havocbot_goalrating_ast_generator_attack(20000))
123         //              havocbot_goalrating_ast_controlpoints_attack(20000);
124         //      havocbot_goalrating_ast_offenseitems(10000, self.origin, 10000);
125
126                 havocbot_goalrating_ast_targets(20000);
127         ///     havocbot_goalrating_items(10000, self.origin, 10000);
128                 navigation_goalrating_end();
129
130                 self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
131         }
132 };
133
134 void havocbot_role_ast_defense()
135 {
136         if(self.deadflag != DEAD_NO)
137         {
138                 self.havocbot_attack_time = 0;
139                 havocbot_ast_reset_role(self);
140                 return;
141         }
142
143         // Set the role timeout if necessary
144         if (!self.havocbot_role_timeout)
145                 self.havocbot_role_timeout = time + 120;
146
147         if (time > self.havocbot_role_timeout)
148         {
149                 havocbot_ast_reset_role(self);
150                 return;
151         }
152
153         if(self.havocbot_attack_time>time)
154                 return;
155
156         if (self.bot_strategytime < time)
157         {
158                 navigation_goalrating_start();
159                 havocbot_goalrating_enemyplayers(20000, self.origin, 650);
160         //      if(!havocbot_goalrating_ast_generator_attack(20000))
161         //              havocbot_goalrating_ast_controlpoints_attack(20000);
162         //      havocbot_goalrating_ast_offenseitems(10000, self.origin, 10000);
163                 havocbot_goalrating_items(10000, self.origin, 10000);
164                 navigation_goalrating_end();
165
166                 self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
167         }
168 };
169
170 void havocbot_role_ast_setrole(entity bot, float role)
171 {
172         switch(role)
173         {
174                 case HAVOCBOT_AST_ROLE_DEFENSE:
175                         bot.havocbot_role = havocbot_role_ast_defense;
176                         bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_DEFENSE;
177                         bot.havocbot_role_timeout = 0;
178                         break;
179                 case HAVOCBOT_AST_ROLE_OFFENSE:
180                         bot.havocbot_role = havocbot_role_ast_offense;
181                         bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_OFFENSE;
182                         bot.havocbot_role_timeout = 0;
183                         break;
184         }
185 };
186
187 void havocbot_ast_reset_role(entity bot)
188 {
189         local entity head;
190         local float c;
191
192         if(self.deadflag != DEAD_NO)
193                 return;
194
195         bot.havocbot_ast_target = world;
196
197         if(bot.team==assault_attacker_team)
198                 havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_OFFENSE);
199         else
200                 havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_DEFENSE);
201 };
202
203 void havocbot_chooserole_ast()
204 {
205         havocbot_ast_reset_role(self);
206 };