1 ///////////////////////////////////////////////////////////////////////
2 //
3 // ACE - Quake II Bot Base Code
4 //
5 // Version 1.0
6 //
7 // This file is Copyright(c), Steve Yeager 1998, All Rights Reserved
8 //
9 //
10 // All other files are Copyright(c) Id Software, Inc.
11 //
12 // Please see liscense.txt in the source directory for the copyright
13 // information regarding those files belonging to Id Software, Inc.
14 //
15 // Should you decide to release a modified version of ACE, you MUST
16 // include the following text (minus the BEGIN and END lines) in the
17 // documentation for your modification.
18 //
19 // --- BEGIN ---
20 //
21 // The ACE Bot is a product of Steve Yeager, and is available from
22 // the ACE Bot homepage, at http://www.axionfx.com/ace.
23 //
24 // This program is a modification of the ACE Bot, and is therefore
25 // in NO WAY supported by Steve Yeager.
26
27 // This program MUST NOT be sold in ANY form. If you have paid for
28 // this product, you should contact Steve Yeager immediately, via
29 // the ACE Bot homepage.
30 //
31 // --- END ---
32 //
33 // I, Steve Yeager, hold no responsibility for any harm caused by the
34 // use of this source code, especially to small children and animals.
35 // It is provided as-is with no implied warranty or support.
36 //
37 // I also wish to thank and acknowledge the great work of others
38 // that has helped me to develop this code.
39 //
40 // John Cricket - For ideas and swapping code.
41 // Ryan Feltrin - For ideas and swapping code.
42 // SABIN - For showing how to do true client based movement.
43 // BotEpidemic - For keeping us up to date.
44 // Telefragged.com - For giving ACE a home.
45 // Microsoft - For giving us such a wonderful crash free OS.
46 // id - Need I say more.
47 //
48 // And to all the other testers, pathers, and players and people
49 // who I can't remember who the heck they were, but helped out.
50 //
51 ///////////////////////////////////////////////////////////////////////
52
53 ///////////////////////////////////////////////////////////////////////
54 //
55 // acebot_cmds.c - Main internal command processor
56 //
57 ///////////////////////////////////////////////////////////////////////
58
59 #include "../g_local.h"
60 #include "acebot.h"
61
62 qboolean debug_mode=false;
63
64 ///////////////////////////////////////////////////////////////////////
65 // Special command processor
66 ///////////////////////////////////////////////////////////////////////
ACECM_Commands(edict_t * ent)67 qboolean ACECM_Commands(edict_t *ent)
68 {
69 char *cmd;
70 int node;
71
72 cmd = gi.argv(0);
73
74 if(Q_stricmp (cmd, "addnode") == 0 && debug_mode)
75 ent->last_node = ACEND_AddNode(ent,atoi(gi.argv(1)));
76
77 else if(Q_stricmp (cmd, "removelink") == 0 && debug_mode)
78 ACEND_RemoveNodeEdge(ent,atoi(gi.argv(1)), atoi(gi.argv(2)));
79
80 else if(Q_stricmp (cmd, "addlink") == 0 && debug_mode)
81 ACEND_UpdateNodeEdge(atoi(gi.argv(1)), atoi(gi.argv(2)));
82
83 else if(Q_stricmp (cmd, "showpath") == 0 && debug_mode)
84 ACEND_ShowPath(ent,atoi(gi.argv(1)));
85
86 else if(Q_stricmp (cmd, "findnode") == 0 && debug_mode)
87 {
88 node = ACEND_FindClosestReachableNode(ent,NODE_DENSITY, NODE_ALL);
89 safe_bprintf(PRINT_MEDIUM,"node: %d type: %d x: %f y: %f z %f\n",node,nodes[node].type,nodes[node].origin[0],nodes[node].origin[1],nodes[node].origin[2]);
90 }
91
92 else if(Q_stricmp (cmd, "movenode") == 0 && debug_mode)
93 {
94 node = atoi(gi.argv(1));
95 nodes[node].origin[0] = atof(gi.argv(2));
96 nodes[node].origin[1] = atof(gi.argv(3));
97 nodes[node].origin[2] = atof(gi.argv(4));
98 safe_bprintf(PRINT_MEDIUM,"node: %d moved to x: %f y: %f z %f\n",node, nodes[node].origin[0],nodes[node].origin[1],nodes[node].origin[2]);
99 }
100
101 else
102 return false;
103
104 return true;
105 }
106
107
108 ///////////////////////////////////////////////////////////////////////
109 // Called when the level changes, store maps and bots (disconnected)
110 ///////////////////////////////////////////////////////////////////////
ACECM_Store()111 void ACECM_Store()
112 {
113 ACEND_SaveNodes();
114 }
115
116 ///////////////////////////////////////////////////////////////////////
117 // These routines are bot safe print routines, all id code needs to be
118 // changed to these so the bots do not blow up on messages sent to them.
119 // Do a find and replace on all code that matches the below criteria.
120 //
121 // (Got the basic idea from Ridah)
122 //
123 // change: gi.cprintf to safe_cprintf
124 // change: gi.bprintf to safe_bprintf
125 // change: gi.centerprintf to safe_centerprintf
126 //
127 ///////////////////////////////////////////////////////////////////////
128
129 ///////////////////////////////////////////////////////////////////////
130 // Debug print, could add a "logging" feature to print to a file
131 ///////////////////////////////////////////////////////////////////////
debug_printf(char * fmt,...)132 void debug_printf(char *fmt, ...)
133 {
134 int i;
135 char bigbuffer[0x10000];
136 int len;
137 va_list argptr;
138 edict_t *cl_ent;
139
140 va_start (argptr,fmt);
141 len = vsprintf (bigbuffer,fmt,argptr);
142 va_end (argptr);
143
144 if (dedicated->value)
145 gi.cprintf(NULL, PRINT_MEDIUM, bigbuffer);
146
147 for (i=0 ; i<maxclients->value ; i++)
148 {
149 cl_ent = g_edicts + 1 + i;
150 if (!cl_ent->inuse || cl_ent->is_bot)
151 continue;
152
153 gi.cprintf(cl_ent, PRINT_MEDIUM, bigbuffer);
154 }
155
156 }
157
158 ///////////////////////////////////////////////////////////////////////
159 // botsafe cprintf
160 ///////////////////////////////////////////////////////////////////////
safe_cprintf(edict_t * ent,int printlevel,char * fmt,...)161 void safe_cprintf (edict_t *ent, int printlevel, char *fmt, ...)
162 {
163 char bigbuffer[0x10000];
164 va_list argptr;
165 int len;
166
167 if (ent && (!ent->inuse || ent->is_bot))
168 return;
169
170 va_start (argptr,fmt);
171 len = vsprintf (bigbuffer,fmt,argptr);
172 va_end (argptr);
173
174 gi.cprintf(ent, printlevel, bigbuffer);
175
176 }
177
178 ///////////////////////////////////////////////////////////////////////
179 // botsafe centerprintf
180 ///////////////////////////////////////////////////////////////////////
safe_centerprintf(edict_t * ent,char * fmt,...)181 void safe_centerprintf (edict_t *ent, char *fmt, ...)
182 {
183 char bigbuffer[0x10000];
184 va_list argptr;
185 int len;
186
187 if (!ent->inuse || ent->is_bot)
188 return;
189
190 va_start (argptr,fmt);
191 len = vsprintf (bigbuffer,fmt,argptr);
192 va_end (argptr);
193
194 gi.centerprintf(ent, bigbuffer);
195
196 }
197
198 ///////////////////////////////////////////////////////////////////////
199 // botsafe bprintf
200 ///////////////////////////////////////////////////////////////////////
safe_bprintf(int printlevel,char * fmt,...)201 void safe_bprintf (int printlevel, char *fmt, ...)
202 {
203 int i;
204 char bigbuffer[0x10000];
205 int len;
206 va_list argptr;
207 edict_t *cl_ent;
208
209 va_start (argptr,fmt);
210 len = vsprintf (bigbuffer,fmt,argptr);
211 va_end (argptr);
212
213 if (dedicated->value)
214 gi.cprintf(NULL, printlevel, bigbuffer);
215
216 for (i=0 ; i<maxclients->value ; i++)
217 {
218 cl_ent = g_edicts + 1 + i;
219 if (!cl_ent->inuse || cl_ent->is_bot)
220 continue;
221
222 gi.cprintf(cl_ent, printlevel, bigbuffer);
223 }
224 }
225
226
227