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