]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/bot/default/havocbot/role_keyhunt.qc
Bots: define the API boundaries
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / bot / default / havocbot / role_keyhunt.qc
1 #include "role_keyhunt.qh"
2
3 void() havocbot_role_kh_carrier;
4 void() havocbot_role_kh_defense;
5 void() havocbot_role_kh_offense;
6 void() havocbot_role_kh_freelancer;
7
8
9 void havocbot_goalrating_kh(float ratingscale_team, float ratingscale_dropped, float ratingscale_enemy)
10 {SELFPARAM();
11         entity head;
12         for (head = kh_worldkeylist; head; head = head.kh_worldkeynext)
13         {
14                 if(head.owner == self)
15                         continue;
16                 if(!kh_tracking_enabled)
17                 {
18                         // if it's carried by our team we know about it
19                         // otherwise we have to see it to know about it
20                         if(!head.owner || head.team != self.team)
21                         {
22                                 traceline(self.origin + self.view_ofs, head.origin, MOVE_NOMONSTERS, self);
23                                 if (trace_fraction < 1 && trace_ent != head)
24                                         continue; // skip what I can't see
25                         }
26                 }
27                 if(!head.owner)
28                         navigation_routerating(head, ratingscale_dropped * BOT_PICKUP_RATING_HIGH, 100000);
29                 else if(head.team == self.team)
30                         navigation_routerating(head.owner, ratingscale_team * BOT_PICKUP_RATING_HIGH, 100000);
31                 else
32                         navigation_routerating(head.owner, ratingscale_enemy * BOT_PICKUP_RATING_HIGH, 100000);
33         }
34
35         havocbot_goalrating_items(1, self.origin, 10000);
36 }
37
38 void havocbot_role_kh_carrier()
39 {SELFPARAM();
40         if(self.deadflag != DEAD_NO)
41                 return;
42
43         if (!(self.kh_next))
44         {
45                 LOG_TRACE("changing role to freelancer\n");
46                 self.havocbot_role = havocbot_role_kh_freelancer;
47                 self.havocbot_role_timeout = 0;
48                 return;
49         }
50
51         if (self.bot_strategytime < time)
52         {
53                 self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
54                 navigation_goalrating_start();
55
56                 if(kh_Key_AllOwnedByWhichTeam() == self.team)
57                         havocbot_goalrating_kh(10, 0.1, 0.1); // bring home
58                 else
59                         havocbot_goalrating_kh(4, 4, 1); // play defensively
60
61                 navigation_goalrating_end();
62         }
63 }
64
65 void havocbot_role_kh_defense()
66 {SELFPARAM();
67         if(self.deadflag != DEAD_NO)
68                 return;
69
70         if (self.kh_next)
71         {
72                 LOG_TRACE("changing role to carrier\n");
73                 self.havocbot_role = havocbot_role_kh_carrier;
74                 self.havocbot_role_timeout = 0;
75                 return;
76         }
77
78         if (!self.havocbot_role_timeout)
79                 self.havocbot_role_timeout = time + random() * 10 + 20;
80         if (time > self.havocbot_role_timeout)
81         {
82                 LOG_TRACE("changing role to freelancer\n");
83                 self.havocbot_role = havocbot_role_kh_freelancer;
84                 self.havocbot_role_timeout = 0;
85                 return;
86         }
87
88         if (self.bot_strategytime < time)
89         {
90                 float key_owner_team;
91                 self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
92                 navigation_goalrating_start();
93
94                 key_owner_team = kh_Key_AllOwnedByWhichTeam();
95                 if(key_owner_team == self.team)
96                         havocbot_goalrating_kh(10, 0.1, 0.1); // defend key carriers
97                 else if(key_owner_team == -1)
98                         havocbot_goalrating_kh(4, 1, 0.1); // play defensively
99                 else
100                         havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK ANYWAY
101
102                 navigation_goalrating_end();
103         }
104 }
105
106 void havocbot_role_kh_offense()
107 {SELFPARAM();
108         if(self.deadflag != DEAD_NO)
109                 return;
110
111         if (self.kh_next)
112         {
113                 LOG_TRACE("changing role to carrier\n");
114                 self.havocbot_role = havocbot_role_kh_carrier;
115                 self.havocbot_role_timeout = 0;
116                 return;
117         }
118
119         if (!self.havocbot_role_timeout)
120                 self.havocbot_role_timeout = time + random() * 10 + 20;
121         if (time > self.havocbot_role_timeout)
122         {
123                 LOG_TRACE("changing role to freelancer\n");
124                 self.havocbot_role = havocbot_role_kh_freelancer;
125                 self.havocbot_role_timeout = 0;
126                 return;
127         }
128
129         if (self.bot_strategytime < time)
130         {
131                 float key_owner_team;
132
133                 self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
134                 navigation_goalrating_start();
135
136                 key_owner_team = kh_Key_AllOwnedByWhichTeam();
137                 if(key_owner_team == self.team)
138                         havocbot_goalrating_kh(10, 0.1, 0.1); // defend anyway
139                 else if(key_owner_team == -1)
140                         havocbot_goalrating_kh(0.1, 1, 4); // play offensively
141                 else
142                         havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK! EMERGENCY!
143
144                 navigation_goalrating_end();
145         }
146 }
147
148 void havocbot_role_kh_freelancer()
149 {SELFPARAM();
150         if(self.deadflag != DEAD_NO)
151                 return;
152
153         if (self.kh_next)
154         {
155                 LOG_TRACE("changing role to carrier\n");
156                 self.havocbot_role = havocbot_role_kh_carrier;
157                 self.havocbot_role_timeout = 0;
158                 return;
159         }
160
161         if (!self.havocbot_role_timeout)
162                 self.havocbot_role_timeout = time + random() * 10 + 10;
163         if (time > self.havocbot_role_timeout)
164         {
165                 if (random() < 0.5)
166                 {
167                         LOG_TRACE("changing role to offense\n");
168                         self.havocbot_role = havocbot_role_kh_offense;
169                 }
170                 else
171                 {
172                         LOG_TRACE("changing role to defense\n");
173                         self.havocbot_role = havocbot_role_kh_defense;
174                 }
175                 self.havocbot_role_timeout = 0;
176                 return;
177         }
178
179         if (self.bot_strategytime < time)
180         {
181                 float key_owner_team;
182
183                 self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
184                 navigation_goalrating_start();
185
186                 key_owner_team = kh_Key_AllOwnedByWhichTeam();
187                 if(key_owner_team == self.team)
188                         havocbot_goalrating_kh(10, 0.1, 0.1); // defend anyway
189                 else if(key_owner_team == -1)
190                         havocbot_goalrating_kh(1, 10, 4); // prefer dropped keys
191                 else
192                         havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK ANYWAY
193
194                 navigation_goalrating_end();
195         }
196 }
197
198 void havocbot_chooserole_kh()
199 {SELFPARAM();
200         float r;
201
202         if(self.deadflag != DEAD_NO)
203                 return;
204
205         r = random() * 3;
206         if (r < 1)
207                 self.havocbot_role = havocbot_role_kh_offense;
208         else if (r < 2)
209                 self.havocbot_role = havocbot_role_kh_defense;
210         else
211                 self.havocbot_role = havocbot_role_kh_freelancer;
212 }