Bmodel objects don't interact with each other, but push all box objects.
(SubgameEntity ent, GameExportsImpl gameExports)
| 454 | * Bmodel objects don't interact with each other, but push all box objects. |
| 455 | */ |
| 456 | static void SV_Physics_Pusher(SubgameEntity ent, GameExportsImpl gameExports) { |
| 457 | float[] move = { 0, 0, 0 }; |
| 458 | float[] amove = { 0, 0, 0 }; |
| 459 | |
| 460 | // if not a team captain, so movement will be handled elsewhere |
| 461 | if ((ent.flags & GameDefines.FL_TEAMSLAVE) != 0) |
| 462 | return; |
| 463 | |
| 464 | // make sure all team slaves can move before commiting |
| 465 | // any moves or calling any think functions |
| 466 | // if the move is blocked, all moved objects will be backed out |
| 467 | // retry: |
| 468 | gameExports.pushed_p = 0; |
| 469 | SubgameEntity part; |
| 470 | for (part = ent; part != null; part = part.teamchain) { |
| 471 | if (part.velocity[0] != 0 || part.velocity[1] != 0 |
| 472 | || part.velocity[2] != 0 || part.avelocity[0] != 0 |
| 473 | || part.avelocity[1] != 0 || part.avelocity[2] != 0) { // object |
| 474 | // is |
| 475 | // moving |
| 476 | Math3D.VectorScale(part.velocity, Defines.FRAMETIME, move); |
| 477 | Math3D.VectorScale(part.avelocity, Defines.FRAMETIME, amove); |
| 478 | |
| 479 | if (!SV_Push(part, move, amove, gameExports)) |
| 480 | break; // move was blocked |
| 481 | } |
| 482 | } |
| 483 | if (gameExports.pushed_p > Defines.MAX_EDICTS) |
| 484 | gameExports.gameImports.error(Defines.ERR_FATAL, "pushed_p > &pushed[MAX_EDICTS], memory corrupted"); |
| 485 | |
| 486 | if (part != null) { |
| 487 | // the move failed, bump all nextthink times and back out moves |
| 488 | for (SubgameEntity mv = ent; mv != null; mv = mv.teamchain) { |
| 489 | if (mv.think.nextTime > 0) |
| 490 | mv.think.nextTime += Defines.FRAMETIME; |
| 491 | } |
| 492 | |
| 493 | // if the pusher has a "blocked" function, call it |
| 494 | // otherwise, just stay in place until the obstacle is gone |
| 495 | if (part.blocked != null) |
| 496 | part.blocked.blocked(part, gameExports.obstacle, gameExports); |
| 497 | } else { // the move succeeded, so call all think functions |
| 498 | for (part = ent; part != null; part = part.teamchain) { |
| 499 | SV_RunThink(part, gameExports); |
| 500 | } |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | |
| 505 | /** |
no test coverage detected