Comment: | Convert more files to pure Objective-C |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
b250dfa8d49dc6cf7dd86d6c78367334 |
User & Date: | js on 2025-03-20 21:18:29 |
Other Links: | manifest | tags |
2025-03-20
| ||
21:52 | Convert more files to pure Objective-C check-in: 46c5779570 user: js tags: trunk | |
21:18 | Convert more files to pure Objective-C check-in: b250dfa8d4 user: js tags: trunk | |
20:59 | Convert several files to pure Objective-C check-in: eac9e3d948 user: js tags: trunk | |
Name change from src/client.m to src/Client.m.
Name change from src/clientextras.mm to src/clientextras.m.
Renamed and modified src/clientgame.mm [6041eeb1a7] to src/clientgame.m [ca9306999a].
1 2 3 4 5 6 7 8 9 10 11 | // clientgame.cpp: core game related stuff #include "cube.h" #import "DynamicEntity.h" #import "Entity.h" #import "OFString+Cube.h" int nextmode = 0; // nextmode becomes gamemode after next map load VAR(gamemode, 1, 0, 0); | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // clientgame.cpp: core game related stuff #include "cube.h" #import "DynamicEntity.h" #import "Entity.h" #import "OFString+Cube.h" int nextmode = 0; // nextmode becomes gamemode after next map load VAR(gamemode, 1, 0, 0); static void mode(int n) { addmsg(1, 2, SV_GAMEMODE, nextmode = n); } COMMAND(mode, ARG_1INT) bool intermission = false; |
︙ | ︙ | |||
140 141 142 143 144 145 146 | void respawnself() { spawnplayer(player1); showscores(false); } | | | | | | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | void respawnself() { spawnplayer(player1); showscores(false); } static void arenacount( DynamicEntity *d, int *alive, int *dead, OFString **lastteam, bool *oneteam) { if (d.state != CS_DEAD) { (*alive)++; if (![*lastteam isEqual:d.team]) *oneteam = false; *lastteam = d.team; } else (*dead)++; } int arenarespawnwait = 0; int arenadetectwait = 0; void arenarespawn() |
︙ | ︙ | |||
173 174 175 176 177 178 179 | arenadetectwait = 0; int alive = 0, dead = 0; OFString *lastteam = nil; bool oneteam = true; for (id player in players) if (player != [OFNull null]) arenacount( | | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | arenadetectwait = 0; int alive = 0, dead = 0; OFString *lastteam = nil; bool oneteam = true; for (id player in players) if (player != [OFNull null]) arenacount( player, &alive, &dead, &lastteam, &oneteam); arenacount(player1, &alive, &dead, &lastteam, &oneteam); if (dead > 0 && (alive <= 1 || (m_teammode && oneteam))) { conoutf( @"arena round is over! next round in 5 seconds..."); if (alive) conoutf( @"team %s is last man standing", lastteam); else |
︙ | ︙ | |||
328 329 330 331 332 333 334 | spawnstate(d); d.state = CS_ALIVE; } // movement input code #define dir(name, v, d, s, os) \ | | | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | spawnstate(d); d.state = CS_ALIVE; } // movement input code #define dir(name, v, d, s, os) \ static void name(bool isdown) \ { \ player1.s = isdown; \ player1.v = isdown ? d : (player1.os ? -(d) : 0); \ player1.lastmove = lastmillis; \ } dir(backward, move, -1, k_down, k_up); |
︙ | ︙ |
Renamed and modified src/clients.mm [0b1a4d40d0] to src/clients.m [6783fe61cf].
︙ | ︙ | |||
193 194 195 196 197 198 199 | static OFMutableArray<OFData *> *messages; void addmsg(int rel, int num, int type, ...) { if (demoplayback) return; | | < | | < | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | static OFMutableArray<OFData *> *messages; void addmsg(int rel, int num, int type, ...) { if (demoplayback) return; if (num != msgsizelookup(type)) fatal(@"inconsistant msg size for %d (%d != %d)", type, num, msgsizelookup(type)); if (messages.count == 100) { conoutf(@"command flood protection (type %d)", type); return; } OFMutableData *msg = [OFMutableData dataWithItemSize:sizeof(int) capacity:num + 2]; |
︙ | ︙ |
Renamed and modified src/clients2c.mm [783cdb6446] to src/clients2c.m [e43832fc31].
︙ | ︙ | |||
304 305 306 307 308 309 310 | case SV_EDITD: case SV_EDITE: { int x = getint(&p); int y = getint(&p); int xs = getint(&p); int ys = getint(&p); int v = getint(&p); | | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | case SV_EDITD: case SV_EDITE: { int x = getint(&p); int y = getint(&p); int xs = getint(&p); int ys = getint(&p); int v = getint(&p); struct block b = { x, y, xs, ys }; switch (type) { case SV_EDITH: editheightxy(v != 0, getint(&p), &b); break; case SV_EDITT: edittexxy(v, getint(&p), &b); break; |
︙ | ︙ |
Name change from src/console.mm to src/console.m.
Renamed and modified src/editing.mm [93fef8399d] to src/editing.m [1b9f6190f4].
︙ | ︙ | |||
8 9 10 11 12 13 14 | bool editmode = false; // the current selection, used by almost all editing commands // invariant: all code assumes that these are kept inside MINBORD distance of // the edge of the map | | | | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | bool editmode = false; // the current selection, used by almost all editing commands // invariant: all code assumes that these are kept inside MINBORD distance of // the edge of the map struct block sel; OF_CONSTRUCTOR() { enqueueInit(^{ sel = (struct block) { variable(@"selx", 0, 0, 4096, &sel.x, NULL, false), variable(@"sely", 0, 0, 4096, &sel.y, NULL, false), variable(@"selxs", 0, 0, 4096, &sel.xs, NULL, false), variable(@"selys", 0, 0, 4096, &sel.ys, NULL, false), }; }); } int selh = 0; bool selset = false; #define loopselxy(b) \ { \ makeundo(); \ loop(x, sel->xs) loop(y, sel->ys) \ { \ struct sqr *s = S(sel->x + x, sel->y + y); \ b; \ } \ remip(sel, 0); \ } int cx, cy, ch; int curedittex[] = { -1, -1, -1 }; bool dragging = false; int lastx, lasty, lasth; int lasttype = 0, lasttex = 0; static struct sqr rtex; VAR(editing, 0, 0, 1); void toggleedit() { if (player1.state == CS_DEAD) |
︙ | ︙ | |||
117 118 119 120 121 122 123 | #define EDITMP \ if (noteditmode() || multiplayer()) \ return; void selectpos(int x, int y, int xs, int ys) { | | | > | < | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | #define EDITMP \ if (noteditmode() || multiplayer()) \ return; void selectpos(int x, int y, int xs, int ys) { struct block s = { x, y, xs, ys }; sel = s; selh = 0; correctsel(); } void makesel() { struct block s = { min(lastx, cx), min(lasty, cy), abs(lastx - cx) + 1, abs(lasty - cy) + 1 }; sel = s; selh = max(lasth, ch); correctsel(); if (selset) rtex = *S(sel.x, sel.y); } VAR(flrceil, 0, 0, 2); // finds out z height when cursor points at wall float sheight(struct sqr *s, struct sqr *t, float z) { return !flrceil // z-s->floor<s->ceil-z ? (s->type == FHF ? s->floor - t->vdelta / 4.0f : (float)s->floor) : (s->type == CHF ? s->ceil + t->vdelta / 4.0f : (float)s->ceil); } void |
︙ | ︙ | |||
161 162 163 164 165 166 167 | volatile float z = worldpos.z; cx = (int)x; cy = (int)y; if (OUTBORD(cx, cy)) return; | | | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | volatile float z = worldpos.z; cx = (int)x; cy = (int)y; if (OUTBORD(cx, cy)) return; struct sqr *s = S(cx, cy); // selected wall if (fabs(sheight(s, s, z) - z) > 1) { x += x > player1.o.x ? 0.5f : -0.5f; // find right wall cube y += y > player1.o.y ? 0.5f : -0.5f; cx = (int)x; |
︙ | ︙ | |||
190 191 192 193 194 195 196 | // render editing grid for (int ix = cx - GRIDSIZE; ix <= cx + GRIDSIZE; ix++) { for (int iy = cy - GRIDSIZE; iy <= cy + GRIDSIZE; iy++) { if (OUTBORD(ix, iy)) continue; | | | | | 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 | // render editing grid for (int ix = cx - GRIDSIZE; ix <= cx + GRIDSIZE; ix++) { for (int iy = cy - GRIDSIZE; iy <= cy + GRIDSIZE; iy++) { if (OUTBORD(ix, iy)) continue; struct sqr *s = S(ix, iy); if (SOLID(s)) continue; float h1 = sheight(s, s, z); float h2 = sheight(s, SWS(s, 1, 0, ssize), z); float h3 = sheight(s, SWS(s, 1, 1, ssize), z); float h4 = sheight(s, SWS(s, 0, 1, ssize), z); if (s->tag) linestyle(GRIDW, 0xFF, 0x40, 0x40); else if (s->type == FHF || s->type == CHF) linestyle(GRIDW, 0x80, 0xFF, 0x80); else linestyle(GRIDW, 0x80, 0x80, 0x80); struct block b = { ix, iy, 1, 1 }; box(&b, h1, h2, h3, h4); linestyle(GRID8, 0x40, 0x40, 0xFF); if (!(ix & GRIDM)) line(ix, iy, h1, ix, iy + 1, h4); if (!(ix + 1 & GRIDM)) line(ix + 1, iy, h2, ix + 1, iy + 1, h3); if (!(iy & GRIDM)) line(ix, iy, h1, ix + 1, iy, h2); if (!(iy + 1 & GRIDM)) line(ix, iy + 1, h4, ix + 1, iy + 1, h3); } } if (!SOLID(s)) { float ih = sheight(s, s, z); linestyle(GRIDS, 0xFF, 0xFF, 0xFF); struct block b = { cx, cy, 1, 1 }; box(&b, ih, sheight(s, SWS(s, 1, 0, ssize), z), sheight(s, SWS(s, 1, 1, ssize), z), sheight(s, SWS(s, 0, 1, ssize), z)); linestyle(GRIDS, 0xFF, 0x00, 0x00); dot(cx, cy, ih); ch = (int)ih; } |
︙ | ︙ | |||
243 244 245 246 247 248 249 | VARP(undomegs, 0, 1, 10); // bounded by n megs void pruneundos(int maxremain) // bound memory { int t = 0; for (ssize_t i = (ssize_t)undos.count - 1; i >= 0; i--) { | | | | | | | | 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 | VARP(undomegs, 0, 1, 10); // bounded by n megs void pruneundos(int maxremain) // bound memory { int t = 0; for (ssize_t i = (ssize_t)undos.count - 1; i >= 0; i--) { struct block *undo = [undos mutableItemAtIndex:i]; t += undo->xs * undo->ys * sizeof(struct sqr); if (t > maxremain) { OFFreeMemory(undo); [undos removeItemAtIndex:i]; } } } void makeundo() { if (undos == nil) undos = [[OFMutableData alloc] initWithItemSize:sizeof(struct block *)]; struct block *copy = blockcopy(&sel); [undos addItem:©]; pruneundos(undomegs << 20); } void editundo() { EDITMP; if (undos.count == 0) { conoutf(@"nothing more to undo"); return; } struct block *p = undos.mutableLastItem; [undos removeLastItem]; blockpaste(p); OFFreeMemory(p); } static struct block *copybuf = NULL; void copy() { EDITSELMP; if (copybuf) OFFreeMemory(copybuf); |
︙ | ︙ | |||
347 348 349 350 351 352 353 | } // the core editing function. all the *xy functions perform the core operations // and are also called directly from the network, the function below it is // strictly triggered locally. They all have very similar structure. void | | | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | } // the core editing function. all the *xy functions perform the core operations // and are also called directly from the network, the function below it is // strictly triggered locally. They all have very similar structure. void editheightxy(bool isfloor, int amount, const struct block *sel) { loopselxy( if (isfloor) { s->floor += amount; if (s->floor >= s->ceil) s->floor = s->ceil - 1; } else { |
︙ | ︙ | |||
372 373 374 375 376 377 378 | bool isfloor = flr == 0; editheightxy(isfloor, amount, &sel); addmsg(1, 7, SV_EDITH, sel.x, sel.y, sel.xs, sel.ys, isfloor, amount); } COMMAND(editheight, ARG_2INT) void | | | 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | bool isfloor = flr == 0; editheightxy(isfloor, amount, &sel); addmsg(1, 7, SV_EDITH, sel.x, sel.y, sel.xs, sel.ys, isfloor, amount); } COMMAND(editheight, ARG_2INT) void edittexxy(int type, int t, const struct block *sel) { loopselxy(switch (type) { case 0: s->ftex = t; break; case 1: s->wtex = t; |
︙ | ︙ | |||
415 416 417 418 419 420 421 | void replace() { EDITSELMP; loop(x, ssize) loop(y, ssize) { | | | | | 415 416 417 418 419 420 421 422 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 | void replace() { EDITSELMP; loop(x, ssize) loop(y, ssize) { struct sqr *s = S(x, y); switch (lasttype) { case 0: if (s->ftex == rtex.ftex) s->ftex = lasttex; break; case 1: if (s->wtex == rtex.wtex) s->wtex = lasttex; break; case 2: if (s->ctex == rtex.ctex) s->ctex = lasttex; break; case 3: if (s->utex == rtex.utex) s->utex = lasttex; break; } } struct block b = { 0, 0, ssize, ssize }; remip(&b, 0); } void edittypexy(int type, const struct block *sel) { loopselxy(s->type = type); } void edittype(int type) { |
︙ | ︙ | |||
481 482 483 484 485 486 487 | corner() { edittype(CORNER); } COMMAND(corner, ARG_NONE) void | | | 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 | corner() { edittype(CORNER); } COMMAND(corner, ARG_NONE) void editequalisexy(bool isfloor, const struct block *sel) { int low = 127, hi = -128; loopselxy({ if (s->floor < low) low = s->floor; if (s->ceil > hi) hi = s->ceil; |
︙ | ︙ | |||
511 512 513 514 515 516 517 | EDITSEL; editequalisexy(isfloor, &sel); addmsg(1, 6, SV_EDITE, sel.x, sel.y, sel.xs, sel.ys, isfloor); } COMMAND(equalize, ARG_1INT) void | | | 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | EDITSEL; editequalisexy(isfloor, &sel); addmsg(1, 6, SV_EDITE, sel.x, sel.y, sel.xs, sel.ys, isfloor); } COMMAND(equalize, ARG_1INT) void setvdeltaxy(int delta, const struct block *sel) { loopselxy(s->vdelta = max(s->vdelta + delta, 0)); remipmore(sel, 0); } void setvdelta(int delta) |
︙ | ︙ | |||
551 552 553 554 555 556 557 | EDITSELMP; sel.xs++; sel.ys++; if (sel.xs > MAXARCHVERT) sel.xs = MAXARCHVERT; if (sel.ys > MAXARCHVERT) sel.ys = MAXARCHVERT; | | | | | | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 | EDITSELMP; sel.xs++; sel.ys++; if (sel.xs > MAXARCHVERT) sel.xs = MAXARCHVERT; if (sel.ys > MAXARCHVERT) sel.ys = MAXARCHVERT; struct block *sel_ = &sel; // Ugly hack to make the macro work. struct block *sel = sel_; loopselxy(s->vdelta = sel->xs > sel->ys ? (archverts[sel->xs - 1][x] + (y == 0 || y == sel->ys - 1 ? sidedelta : 0)) : (archverts[sel->ys - 1][y] + (x == 0 || x == sel->xs - 1 ? sidedelta : 0))); remipmore(sel, 0); } void slope(int xd, int yd) { EDITSELMP; int off = 0; if (xd < 0) off -= xd * sel.xs; if (yd < 0) off -= yd * sel.ys; sel.xs++; sel.ys++; struct block *sel_ = &sel; // Ugly hack to make the macro work. struct block *sel = sel_; loopselxy(s->vdelta = xd * x + yd * y + off); remipmore(sel, 0); } void perlin(int scale, int seed, int psize) { |
︙ | ︙ | |||
608 609 610 611 612 613 614 | loopi(mipsize) world[i].r = world[i].g = world[i].b = 176; }); void edittag(int tag) { EDITSELMP; | | | | 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 | loopi(mipsize) world[i].r = world[i].g = world[i].b = 176; }); void edittag(int tag) { EDITSELMP; struct block *sel_ = &sel; // Ugly hack to make the macro work. struct block *sel = sel_; loopselxy(s->tag = tag); } void newent(OFString *what, OFString *a1, OFString *a2, OFString *a3, OFString *a4) { EDITSEL; |
︙ | ︙ |
Renamed and modified src/entities.mm [47ee9d00d9] to src/entities.m [2808b0e950].
︙ | ︙ | |||
25 26 27 28 29 30 31 | void initEntities() { ents = [[OFMutableArray alloc] init]; } | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | void initEntities() { ents = [[OFMutableArray alloc] init]; } static void renderent(Entity *e, OFString *mdlname, float z, float yaw, int frame/* = 0*/, int numf/* = 1*/, int basetime/* = 0*/, float speed/* = 10.0f*/) { rendermodel(mdlname, frame, numf, 0, 1.1f, OFMakeVector3D(e.x, z + S(e.x, e.y)->floor, e.y), yaw, 0, false, 1.0f, speed, 0, basetime); } void |
︙ | ︙ | |||
63 64 65 66 67 68 69 | continue; if (e.type < I_SHELLS || e.type > TELEPORT) continue; renderent(e, entmdlnames[e.type - I_SHELLS], (float)(1 + sin(lastmillis / 100.0 + e.x + e.y) / 20), | | | > | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | continue; if (e.type < I_SHELLS || e.type > TELEPORT) continue; renderent(e, entmdlnames[e.type - I_SHELLS], (float)(1 + sin(lastmillis / 100.0 + e.x + e.y) / 20), lastmillis / 10.0f, 0,1,0,10.0f); } else { switch (e.attr2) { case 1: case 3: continue; case 2: case 0: if (!e.spawned) continue; renderent(e, @"carrot", (float)(1 + sin(lastmillis / 100.0 + e.x + e.y) / 20), lastmillis / (e.attr2 ? 1.0f : 10.0f), 0, 1, 0, 10.0f); break; case 4: renderent(e, @"switch2", 3, (float)e.attr3 * 90, (!e.spawned && !triggertime) ? 1 : 0, |
︙ | ︙ | |||
132 133 134 135 136 137 138 | // these two functions are called when the server acknowledges that you really // picked up the item (in multiplayer someone may grab it before you). static int radditem(int i, int v) { | | | | | | | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | // these two functions are called when the server acknowledges that you really // picked up the item (in multiplayer someone may grab it before you). static int radditem(int i, int v) { struct itemstat *is = &itemstats[ents[i].type - I_SHELLS]; ents[i].spawned = false; v += is->add; if (v > is->max) v = is->max; playsoundc(is->sound); return v; } void realpickup(int n, DynamicEntity *d) { switch (ents[n].type) { |
︙ | ︙ |
Name change from src/menus.mm to src/menus.m.
Modified src/meson.build from [0f5a54e283] to [44296e0cb5].
︙ | ︙ | |||
17 18 19 20 21 22 23 | 'PersistentEntity.m', 'Projectile.m', 'ResolverResult.m', 'ResolverThread.m', 'ServerEntity.m', 'ServerInfo.m', 'Variable.m', | | | | | | | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 'PersistentEntity.m', 'Projectile.m', 'ResolverResult.m', 'ResolverThread.m', 'ServerEntity.m', 'ServerInfo.m', 'Variable.m', 'clients.m', 'clientextras.m', 'clientgame.m', 'clients2c.m', 'commands.mm', 'console.m', 'editing.m', 'entities.m', 'init.mm', 'menus.m', 'monster.m', 'physics.mm', 'rendercubes.mm', 'renderextras.mm', 'rendergl.mm', 'rendermd2.mm', 'renderparticles.mm', 'rendertext.mm', |
︙ | ︙ |
Renamed and modified src/monster.mm [f91ea743e3] to src/monster.m [c3b07dd60c].
︙ | ︙ | |||
59 60 61 62 63 64 65 | basicmonster(int type, int yaw, int state, int trigger, int move) { if (type >= NUMMONSTERTYPES) { conoutf(@"warning: unknown monster in spawn: %d", type); type = 0; } DynamicEntity *m = newdynent(); | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | basicmonster(int type, int yaw, int state, int trigger, int move) { if (type >= NUMMONSTERTYPES) { conoutf(@"warning: unknown monster in spawn: %d", type); type = 0; } DynamicEntity *m = newdynent(); struct monstertype *t = &monstertypes[(m.mtype = type)]; m.eyeheight = 2.0f; m.aboveeye = 1.9f; m.radius *= t->bscale / 10.0f; m.eyeheight *= t->bscale / 10.0f; m.aboveeye *= t->bscale / 10.0f; m.monsterstate = state; if (state != M_SLEEP) |
︙ | ︙ | |||
134 135 136 137 138 139 140 | monstertotal++; } } } // height-correct line of sight for monster shooting/seeing bool | | | | | | | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | monstertotal++; } } } // height-correct line of sight for monster shooting/seeing bool los(float lx, float ly, float lz, float bx, float by, float bz, OFVector3D *v) { if (OUTBORD((int)lx, (int)ly) || OUTBORD((int)bx, (int)by)) return false; float dx = bx - lx; float dy = by - ly; int steps = (int)(sqrt(dx * dx + dy * dy) / 0.9); if (!steps) return false; float x = lx; float y = ly; int i = 0; for (;;) { struct sqr *s = S(fast_f2nat(x), fast_f2nat(y)); if (SOLID(s)) break; float floor = s->floor; if (s->type == FHF) floor -= s->vdelta / 4.0f; float ceil = s->ceil; if (s->type == CHF) ceil += s->vdelta / 4.0f; float rz = lz - ((lz - bz) * (i / (float)steps)); if (rz < floor || rz > ceil) break; v->x = x; v->y = y; v->z = rz; x += dx / (float)steps; y += dy / (float)steps; i++; } return i >= steps; } bool enemylos(DynamicEntity *m, OFVector3D *v) { *v = m.o; return los( m.o.x, m.o.y, m.o.z, m.enemy.o.x, m.enemy.o.y, m.enemy.o.z, v); } // monster AI is sequenced using transitions: they are in a particular state // where they execute a particular behaviour until the trigger time is hit, and // then they reevaluate their situation based on the current state, the |
︙ | ︙ | |||
257 258 259 260 261 262 263 | transition(m, M_HOME, 1, 100, 200); break; case M_SLEEP: // state classic sp monster start in, wait for visual // contact { OFVector3D target; | | | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | transition(m, M_HOME, 1, 100, 200); break; case M_SLEEP: // state classic sp monster start in, wait for visual // contact { OFVector3D target; if (editmode || !enemylos(m, &target)) return; // skip running physics normalise(m, enemyyaw); float angle = (float)fabs(enemyyaw - m.yaw); if (disttoenemy < 8 // the better the angle to the player, the // further the monster can see/hear || (disttoenemy < 16 && angle < 135) || (disttoenemy < 32 && angle < 90) || |
︙ | ︙ | |||
291 292 293 294 295 296 297 | case M_HOME: // monster has visual contact, heads straight for player and // may want to shoot at any time m.targetyaw = enemyyaw; if (m.trigger < lastmillis) { OFVector3D target; | | | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | case M_HOME: // monster has visual contact, heads straight for player and // may want to shoot at any time m.targetyaw = enemyyaw; if (m.trigger < lastmillis) { OFVector3D target; if (!enemylos(m, &target)) { // no visual contact anymore, let monster get // as close as possible then search for player transition(m, M_HOME, 1, 800, 500); } else { // the closer the monster is the more likely he // wants to shoot if (!rnd((int)disttoenemy / 3 + 1) && |
︙ | ︙ |
Modified src/serverbrowser.mm from [3cbd2b77d6] to [7fbcf875ca].
︙ | ︙ | |||
198 199 200 201 202 203 204 | si.sdesc = @(text); break; } } } } | | | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | si.sdesc = @(text); break; } } } } extern "C" void refreshservers() { checkresolver(); checkpings(); if (lastmillis - lastinfo >= 5000) pingservers(); [servers sort]; |
︙ | ︙ |