| 373 | bool sv_pos = true; |
| 374 | |
| 375 | void c2sinfo(playerent *d) // send update to the server |
| 376 | { |
| 377 | if(d->clientnum<0) return; // we haven't had a welcome message from the server yet |
| 378 | if(totalmillis-lastupdate<40) return; // don't update faster than 25fps |
| 379 | |
| 380 | if(d->state==CS_ALIVE || d->state==CS_EDITING) |
| 381 | { |
| 382 | ASSERT(!(d->crouching && d->onladder)); // onladder is never set while crouching - and we're going to rely on it ;) |
| 383 | ASSERT(!(d->move < -1 || d->move > 1 || d->strafe < -1 || d->strafe > 1)); |
| 384 | packetbuf q(100); |
| 385 | int cn = d->clientnum, |
| 386 | x = (int)(d->o.x*DMF + 0.5f), // quantize coordinates to 1/16th of a cube, between 1 and 3 bytes |
| 387 | y = (int)(d->o.y*DMF + 0.5f), |
| 388 | z = (int)floorf((d->o.z - d->eyeheight)*DMF + 0.5f), |
| 389 | zsign = z < 0 ? 1 : 0, |
| 390 | ya = encodeyaw(d->yaw), |
| 391 | pi = encodepitch(d->pitch), |
| 392 | dx = (int)floorf(d->vel.x*DVELF + 0.5f), |
| 393 | dy = (int)floorf(d->vel.y*DVELF + 0.5f), |
| 394 | dz = (int)floorf(d->vel.z*DVELF + 0.5f); |
| 395 | int f = (d->strafe + 4 + d->move * 3 + (d->onladder ? 9 : 0) + (d->crouching ? 18 : 0)) // pack 6 bit into 5 with ternary logic :) |
| 396 | | (((int)d->scoping)<<5) | ((d->lifesequence&1)<<6) | (((int)d->onfloor)<<7) | (((int)d->jumpd)<<8) | (((int)(dx||dy||dz))<<9) | (zsign << 10); // number of used bits: FLAGBITS |
| 397 | int usefactor = sfactor < 7 ? 7 : sfactor; |
| 398 | if(zsign) z = -z; |
| 399 | if(cn >= 0 && cn < 32 && |
| 400 | usefactor <= 7 + 3 && // map size 7..10 |
| 401 | !((x | y) & ~((1 << (usefactor + 4)) - 1)) && |
| 402 | z >= -2047 && z <= 2047 && |
| 403 | dx >= -8 && dx <= 7 && |
| 404 | dy >= -8 && dy <= 7 && |
| 405 | dz >= -8 && dz <= 7) |
| 406 | { // compact POS packet |
| 407 | bitbuf<packetbuf> b(q); |
| 408 | putint(q, SV_POSC + usefactor - 7); |
| 409 | b.putbits(5, cn); |
| 410 | b.putbits(usefactor + 4, x); |
| 411 | b.putbits(usefactor + 4, y); |
| 412 | b.putbits(YAWBITS, ya); |
| 413 | b.putbits(PITCHBITS, pi); |
| 414 | b.putbits(FLAGBITS, f); |
| 415 | if(f & (1 << 9)) // hasvel |
| 416 | { |
| 417 | b.putbits(4, dx + 8); |
| 418 | b.putbits(4, dy + 8); |
| 419 | b.putbits(4, dz + 8); |
| 420 | } |
| 421 | int s = (b.rembits() - 1 + 8) % 8; // z is encoded with 3..10 bits minimum (fitted to byte boundaries), or full 11 bits if necessary |
| 422 | if(s < 3) s += 8; |
| 423 | if(z >= (1 << s)) s = 11; |
| 424 | b.putbits(1, s == 11 ? 1 : 0); |
| 425 | b.putbits(s, z); |
| 426 | } |
| 427 | else |
| 428 | { // classic POS packet |
| 429 | putint(q, SV_POS); |
| 430 | putint(q, d->clientnum); |
| 431 | putuint(q, x); |
| 432 | putuint(q, y); |
no test coverage detected