Harden bm_read_player_ship against invalid model numbers
Eliminate an unnecessary internal copy. Terminate the search early if an invalid model number is used.
This commit is contained in:
parent
504e950b75
commit
0faa33d3df
|
@ -76,6 +76,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
||||||
#include "partial_range.h"
|
#include "partial_range.h"
|
||||||
#include "d_enumerate.h"
|
#include "d_enumerate.h"
|
||||||
#include "d_range.h"
|
#include "d_range.h"
|
||||||
|
#include "d_zip.h"
|
||||||
|
|
||||||
using std::min;
|
using std::min;
|
||||||
|
|
||||||
|
@ -2044,28 +2045,38 @@ void bm_read_player_ship(void)
|
||||||
//calc player gun positions
|
//calc player gun positions
|
||||||
|
|
||||||
{
|
{
|
||||||
polymodel *pm;
|
const auto &r = ri;
|
||||||
robot_info *r;
|
const auto &pm = Polygon_models[Player_ship->model_num];
|
||||||
|
|
||||||
|
/* Binding to the zip iterator produces references. For r.gun_points
|
||||||
|
* and r.gun_submodels, a mutable local is desired instead.
|
||||||
|
*
|
||||||
|
* If there are no submodels, copy directly from `r.gun_points` to
|
||||||
|
* `plr_gun_point` (bound to an element of `Player_ship->gun_points`).
|
||||||
|
*
|
||||||
|
* If there are submodels:
|
||||||
|
* - Copy the submodel index into a local `mn`
|
||||||
|
* - Copy the r.gun_points vector into a local `pnt`
|
||||||
|
* - Redirect `ppnt` to the local.
|
||||||
|
* - Update the local as needed from the polygon models.
|
||||||
|
* - Copy that local to `plr_gun_point`.
|
||||||
|
*
|
||||||
|
* This minimizes unnecessary copying.
|
||||||
|
*/
|
||||||
|
for (auto &&[rpnt, rmn, plr_gun_point] : zip(partial_range(r.gun_points, r.n_guns), r.gun_submodels, Player_ship->gun_points))
|
||||||
|
{
|
||||||
|
auto ppnt = &rpnt;
|
||||||
|
/* Create a local copy to be modified by the `while` loop. */
|
||||||
vms_vector pnt;
|
vms_vector pnt;
|
||||||
int mn; //submodel number
|
if (auto mn = rmn)
|
||||||
int gun_num;
|
{
|
||||||
|
|
||||||
r = &ri;
|
|
||||||
pm = &Polygon_models[Player_ship->model_num];
|
|
||||||
|
|
||||||
for (gun_num=0;gun_num<r->n_guns;gun_num++) {
|
|
||||||
|
|
||||||
pnt = r->gun_points[gun_num];
|
|
||||||
mn = r->gun_submodels[gun_num];
|
|
||||||
|
|
||||||
//instance up the tree for this gun
|
//instance up the tree for this gun
|
||||||
while (mn != 0) {
|
pnt = rpnt;
|
||||||
vm_vec_add2(pnt,pm->submodel_offsets[mn]);
|
ppnt = &pnt;
|
||||||
mn = pm->submodel_parents[mn];
|
for (; mn && mn < std::size(pm.submodel_offsets); mn = pm.submodel_parents[mn])
|
||||||
|
vm_vec_add2(pnt, pm.submodel_offsets[mn]);
|
||||||
}
|
}
|
||||||
|
plr_gun_point = *ppnt;
|
||||||
Player_ship->gun_points[gun_num] = pnt;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue