Called by monster program code. The move will be adjusted for slopes and stairs, but if the move isn't possible, no move is done, false is returned, and pr_global_struct.trace_normal is set to the normal of the blocking wall. FIXME: since we need to test end position contents here, can we avoid
(SubgameEntity ent, float[] move, boolean relink, GameExportsImpl gameExports)
| 776 | * FIXME: since we need to test end position contents here, can we avoid doing it again later in catagorize position? |
| 777 | */ |
| 778 | static boolean SV_movestep(SubgameEntity ent, float[] move, boolean relink, GameExportsImpl gameExports) { |
| 779 | float dz; |
| 780 | float[] oldorg = { 0, 0, 0 }; |
| 781 | float[] neworg = { 0, 0, 0 }; |
| 782 | float[] end = { 0, 0, 0 }; |
| 783 | |
| 784 | trace_t trace = null; // = new trace_t(); |
| 785 | int i; |
| 786 | float stepsize; |
| 787 | float[] test = { 0, 0, 0 }; |
| 788 | int contents; |
| 789 | |
| 790 | // try the move |
| 791 | Math3D.VectorCopy(ent.s.origin, oldorg); |
| 792 | Math3D.VectorAdd(ent.s.origin, move, neworg); |
| 793 | |
| 794 | // flying monsters don't step up |
| 795 | if ((ent.flags & (GameDefines.FL_SWIM | GameDefines.FL_FLY)) != 0) { |
| 796 | // try one move with vertical motion, then one without |
| 797 | for (i = 0; i < 2; i++) { |
| 798 | Math3D.VectorAdd(ent.s.origin, move, neworg); |
| 799 | if (i == 0 && ent.enemy != null) { |
| 800 | if (ent.goalentity == null) |
| 801 | ent.goalentity = ent.enemy; |
| 802 | dz = ent.s.origin[2] - ent.goalentity.s.origin[2]; |
| 803 | if (ent.goalentity.getClient() != null) { |
| 804 | if (dz > 40) |
| 805 | neworg[2] -= 8; |
| 806 | if (!((ent.flags & GameDefines.FL_SWIM) != 0 && (ent.waterlevel < 2))) |
| 807 | if (dz < 30) |
| 808 | neworg[2] += 8; |
| 809 | } else { |
| 810 | if (dz > 8) |
| 811 | neworg[2] -= 8; |
| 812 | else if (dz > 0) |
| 813 | neworg[2] -= dz; |
| 814 | else if (dz < -8) |
| 815 | neworg[2] += 8; |
| 816 | else |
| 817 | neworg[2] += dz; |
| 818 | } |
| 819 | } |
| 820 | trace = gameExports.gameImports.trace(ent.s.origin, ent.mins, ent.maxs, |
| 821 | neworg, ent, Defines.MASK_MONSTERSOLID); |
| 822 | |
| 823 | // fly monsters don't enter water voluntarily |
| 824 | if ((ent.flags & GameDefines.FL_FLY) != 0) { |
| 825 | if (ent.waterlevel == 0) { |
| 826 | test[0] = trace.endpos[0]; |
| 827 | test[1] = trace.endpos[1]; |
| 828 | test[2] = trace.endpos[2] + ent.mins[2] + 1; |
| 829 | contents = gameExports.gameImports.getPointContents(test); |
| 830 | if ((contents & Defines.MASK_WATER) != 0) |
| 831 | return false; |
| 832 | } |
| 833 | } |
| 834 | |
| 835 | // swim monsters don't exit water voluntarily |
no test coverage detected