1
2
3
4
5
6
7
8
9
10
11
12
13
|
1
2
3
4
5
6
7
8
9
10
11
|
-
-
|
// clientgame.cpp: core game related stuff
#include "cube.h"
#include <memory>
int nextmode = 0; // nextmode becomes gamemode after next map load
VAR(gamemode, 1, 0, 0);
void
mode(int n)
{
addmsg(1, 2, SV_GAMEMODE, nextmode = n);
|
︙ | | |
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
|
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
|
-
-
-
-
+
-
-
+
-
-
+
+
-
+
|
void
updateworld(int millis) // main game update loop
{
if (lastmillis) {
curtime = millis - lastmillis;
if (sleepwait && lastmillis > sleepwait) {
sleepwait = 0;
@autoreleasepool {
std::unique_ptr<char> cmd(
strdup(sleepcmd.UTF8String));
execute(cmd.get());
execute(sleepcmd);
}
}
physicsframe();
checkquad(curtime);
if (m_arena)
arenarespawn();
moveprojectiles((float)curtime);
demoplaybackstep();
if (!demoplayback) {
if (getclientnum() >= 0)
shoot(player1, worldpos); // only shoot when
// connected to server
gets2c(); // do this first, so we have most accurate
// information when our player moves
};
}
otherplayers();
if (!demoplayback) {
monsterthink();
if (player1->state == CS_DEAD) {
if (lastmillis - player1->lastaction < 2000) {
player1->move = player1->strafe = 0;
moveplayer(player1, 10, false);
} else if (!m_arena && !m_sp &&
lastmillis - player1->lastaction >
10000)
respawn();
} else if (!intermission) {
moveplayer(player1, 20, true);
checkitems();
};
c2sinfo(player1); // do this last, to reduce the
// effective frame lag
};
};
}
}
lastmillis = millis;
};
}
void
entinmap(dynent *
d) // brute force but effective way to find a free spawn spot in the map
{
loopi(100) // try max 100 times
{
|
︙ | | |
︙ | | |
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
-
-
-
+
+
+
+
|
conoutf(@"missing \"%c\"", right);
return NULL;
}
}
char *s = newstring(word, p - word - 1);
if (left == '(') {
string t;
itoa(t,
execute(
s)); // evaluate () exps directly, and substitute result
// evaluate () exps directly, and substitute result
@autoreleasepool {
itoa(t, execute(@(s)));
}
s = exchangestr(s, t);
}
return s;
}
char *
parseword(char *&p) // parse single argument, including expressions
|
︙ | | |
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
+
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
|
}
conoutf(@"unknown alias lookup: %s", n + 1);
return n;
}
int
execute(
execute(char *p, bool isdown) // all evaluation happens here, recursively
OFString *string, bool isdown) // all evaluation happens here, recursively
{
@autoreleasepool {
std::unique_ptr<char> copy(strdup(string.UTF8String));
char *p = copy.get();
const int MAXWORDS = 25; // limit, remove
char *w[MAXWORDS];
int val = 0;
for (bool cont = true; cont;) // for each ; seperated statement
const int MAXWORDS = 25; // limit, remove
char *w[MAXWORDS];
int val = 0;
for (bool cont = true; cont;) {
{
int numargs = MAXWORDS;
loopi(MAXWORDS) // collect all argument values
{
w[i] = "";
if (i > numargs)
continue;
char *s = parseword(p); // parse and evaluate exps
if (!s) {
numargs = i;
s = "";
}
if (*s == '$')
s = lookup(s); // substitute variables
w[i] = s;
}
// for each ; seperated statement
int numargs = MAXWORDS;
loopi(MAXWORDS)
{
// collect all argument values
w[i] = "";
if (i > numargs)
continue;
// parse and evaluate exps
char *s = parseword(p);
if (!s) {
numargs = i;
s = "";
}
if (*s == '$')
s = lookup(s); // substitute variables
w[i] = s;
}
p += strcspn(p, ";\n\0");
p += strcspn(p, ";\n\0");
cont = *p++ !=
0; // more statements if this isn't the end of the string
char *c = w[0];
if (*c == '/')
c++; // strip irc-style command prefix
if (!*c)
continue; // empty statement
// more statements if this isn't the end of the string
cont = *p++ != 0;
char *c = w[0];
// strip irc-style command prefix
if (*c == '/')
c++;
// empty statement
if (!*c)
continue;
@autoreleasepool {
__kindof Identifier *identifier = identifiers[@(c)];
if (identifier == nil) {
val = ATOI(c);
if (!val && *c != '0')
conoutf(@"unknown command: %s", c);
} else {
if ([identifier
isKindOfClass:[Command class]]) {
// game defined commands
// use very ad-hoc function signature,
// and just call it
// game defined commands use very
// ad-hoc function signature, and just
// call it
val = [identifier
callWithArguments:w
numArguments:numargs
isDown:isdown];
} else if ([identifier
isKindOfClass:[Variable
class]]) {
|
︙ | | |
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
-
-
-
-
+
+
-
-
-
+
+
-
+
+
|
stringWithFormat:
@"arg%d", i];
alias(t, @(w[i]));
}
}
// create new string here because alias
// could rebind itself
char *action = newstring(
[identifier action].UTF8String);
val = execute(action, isdown);
gp()->deallocstr(action);
val = execute(
[[identifier action] copy], isdown);
break;
}
}
}
loopj(numargs) gp()->deallocstr(w[j]);
}
loopj(numargs) gp()->deallocstr(w[j]);
}
return val;
return val;
}
}
// tab-completion of all identifiers
int completesize = 0, completeidx = 0;
void
|
︙ | | |
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
|
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
|
-
+
|
} @catch (id e) {
return false;
}
// Ensure \0 termination.
[data addItem:""];
execute((char *)data.mutableItems);
execute(@((char *)data.mutableItems));
return true;
}
}
void
exec(OFString *cfgfile)
{
|
︙ | | |
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
|
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
|
-
-
-
-
+
-
-
-
+
+
-
-
+
-
-
+
-
+
-
-
-
-
-
-
+
+
-
-
+
-
-
-
-
+
+
+
-
-
-
+
-
|
alias(name, [OFString stringWithFormat:@"%d", v]);
}
}
void
ifthen(OFString *cond, OFString *thenp, OFString *elsep)
{
@autoreleasepool {
std::unique_ptr<char> cmd(strdup(
(cond.UTF8String[0] != '0' ? thenp : elsep).UTF8String));
execute((![cond hasPrefix:@"0"] ? thenp : elsep));
execute(cmd.get());
}
}
}
void
loopa(OFString *times, OFString *body_)
loopa(OFString *times, OFString *body)
{
@autoreleasepool {
int t = (int)times.longLongValue;
std::unique_ptr<char> body(strdup(body_.UTF8String));
loopi(t)
{
intset(@"i", i);
execute(body.get());
execute(body);
}
}
}
void
whilea(OFString *cond_, OFString *body_)
whilea(OFString *cond, OFString *body)
{
@autoreleasepool {
std::unique_ptr<char> cond(strdup(cond_.UTF8String));
std::unique_ptr<char> body(strdup(body_.UTF8String));
while (execute(cond.get()))
execute(body.get());
while (execute(cond))
execute(body);
}
}
void
onrelease(bool on, OFString *body)
{
if (!on) {
if (!on)
std::unique_ptr<char> copy(strdup(body.UTF8String));
execute(copy.get());
}
}
execute(body);
}
void
concat(OFString *s)
{
@autoreleasepool {
alias(@"s", s);
alias(@"s", s);
}
}
void
concatword(OFString *s)
{
// The original used this code which does nothing:
// for (char *a = s, *b = s; *a = *b; b++)
|
︙ | | |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-
|
// console.cpp: the console buffer, its display, and command line control
#include "cube.h"
#include <ctype.h>
#include <memory>
#import "KeyMapping.h"
struct cline {
char *cref;
int outtime;
};
|
︙ | | |
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
-
+
-
-
|
void
history(int n)
{
static bool rec = false;
if (!rec && n >= 0 && n < vhistory.count) {
rec = true;
OFString *cmd = vhistory[vhistory.count - n - 1];
execute(vhistory[vhistory.count - n - 1]);
std::unique_ptr<char> copy(strdup(cmd.UTF8String));
execute(copy.get());
rec = false;
}
}
COMMAND(history, ARG_1INT)
void
keypress(int code, bool isdown, int cooked)
|
︙ | | |
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
|
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
-
+
-
-
-
+
-
-
+
-
-
+
-
|
[vhistory
addObject:
[commandbuf
copy]];
}
}
histpos = vhistory.count;
if ([commandbuf hasPrefix:@"/"]) {
if ([commandbuf hasPrefix:@"/"])
std::unique_ptr<char> copy(
strdup(
commandbuf.UTF8String));
execute(commandbuf, true);
execute(copy.get(), true);
} else
else
toserver(commandbuf);
}
saycommand(NULL);
} else if (code == SDLK_ESCAPE) {
saycommand(NULL);
}
}
} else if (!menukey(code, isdown)) {
// keystrokes go to menu
for (KeyMapping *mapping in keyMappings) {
if (mapping.code == code) {
// keystrokes go to game, lookup in keymap and
// execute
string temp;
strcpy_s(temp, mapping.action.UTF8String);
execute(mapping.action, isdown);
execute(temp, isdown);
return;
}
}
}
}
OFString *
|
︙ | | |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
-
+
|
// protos for ALL external functions in cube...
// command
extern int variable(OFString *name, int min, int cur, int max, int *storage,
void (*fun)(), bool persist);
extern void setvar(OFString *name, int i);
extern int getvar(OFString *name);
extern bool identexists(OFString *name);
extern bool addcommand(OFString *name, void (*fun)(), int narg);
extern int execute(char *p, bool down = true);
extern int execute(OFString *p, bool down = true);
extern void exec(OFString *cfgfile);
extern bool execfile(OFString *cfgfile);
extern void resetcomplete();
extern void complete(OFString *s);
extern void alias(OFString *name, OFString *action);
extern OFString *getalias(OFString *name);
extern void writecfg();
|
︙ | | |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
1
2
3
4
5
6
7
8
9
10
11
|
-
-
|
// world.cpp: core map management stuff
#include "cube.h"
#include <memory>
extern OFString *entnames[]; // lookup from map entities above to strings
sqr *world = NULL;
int sfactor, ssize, cubicsize, mipsize;
header hdr;
|
︙ | | |
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
-
+
-
-
+
-
|
if (!savegame && type != 3)
playsound(S_RUMBLE);
@autoreleasepool {
OFString *aliasname =
[OFString stringWithFormat:@"level_trigger_%d", tag];
if (identexists(aliasname)) {
if (identexists(aliasname))
std::unique_ptr<char> cmd(strdup(aliasname.UTF8String));
execute(cmd.get());
execute(aliasname);
}
}
if (type == 2)
endsp(false);
}
COMMAND(trigger, ARG_2INT)
|
︙ | | |
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
|
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
|
-
+
|
}
calclight();
startmap(@"base/unnamed");
if (oldworld) {
free(oldworld);
toggleedit();
execute("fullbright 1");
execute(@"fullbright 1");
}
}
void
mapenlarge()
{
empty_world(-1, false);
|
︙ | | |