Use Point/range iterator in CheckThemeObj3
This does introduce a slight behaviour difference for some callers. It was possible to read out of bounds due to the bounds check only guarding against negative indexes (e.g. Theme_Library uses 1, MAXDUN - 1 as the bounds, but Theme_ArmorStand includes boundary tiles so could read off the right/bottom edge). Given the way vanilla levels are generated with a border this has no impact in practice.
This commit is contained in:
parent
4eec1bd40c
commit
3e991fc9a8
1 changed files with 17 additions and 29 deletions
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
#include "themes.h"
|
||||
|
||||
#include "engine/points_in_rectangle_range.hpp"
|
||||
#include "engine/random.hpp"
|
||||
#include "items.h"
|
||||
#include "monster.h"
|
||||
|
|
@ -48,19 +49,6 @@ int trm5y[] = {
|
|||
1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 2
|
||||
};
|
||||
/** Specifies a 3x3 area to fit theme objects. */
|
||||
int trm3x[] = {
|
||||
-1, 0, 1,
|
||||
-1, 0, 1,
|
||||
-1, 0, 1
|
||||
};
|
||||
/** Specifies a 3x3 area to fit theme objects. */
|
||||
int trm3y[] = {
|
||||
-1, -1, -1,
|
||||
0, 0, 0,
|
||||
1, 1, 1
|
||||
};
|
||||
|
||||
bool TFit_Shrine(int i)
|
||||
{
|
||||
int xp = 0;
|
||||
|
|
@ -179,28 +167,28 @@ bool TFit_GoatShrine(int t)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CheckThemeObj3(int xp, int yp, int t, int f)
|
||||
bool CheckThemeObj3(Point origin, int8_t regionId, int frequency)
|
||||
{
|
||||
for (int i = 0; i < 9; i++) {
|
||||
Point testPosition = Point { xp, yp } + Displacement { trm3x[i], trm3y[i] };
|
||||
if (testPosition.x < 0 || testPosition.y < 0) {
|
||||
const PointsInRectangleRange searchArea { Rectangle { origin, 1 } };
|
||||
return std::all_of(searchArea.cbegin(), searchArea.cend(), [regionId, frequency](Point testPosition) {
|
||||
if (!InDungeonBounds(testPosition)) {
|
||||
return false;
|
||||
}
|
||||
if (IsTileSolid(testPosition)) {
|
||||
return false;
|
||||
}
|
||||
if (dTransVal[testPosition.x][testPosition.y] != themes[t].ttval) {
|
||||
// If the theme object would extend into a different region then it doesn't fit.
|
||||
if (dTransVal[testPosition.x][testPosition.y] != regionId) {
|
||||
return false;
|
||||
}
|
||||
if (IsObjectAtPosition(testPosition)) {
|
||||
return false;
|
||||
}
|
||||
if (f != -1 && GenerateRnd(f) == 0) {
|
||||
if (frequency != -1 && GenerateRnd(frequency) == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool TFit_Obj3(int t)
|
||||
|
|
@ -209,7 +197,7 @@ bool TFit_Obj3(int t)
|
|||
|
||||
for (int yp = 1; yp < MAXDUNY - 1; yp++) {
|
||||
for (int xp = 1; xp < MAXDUNX - 1; xp++) {
|
||||
if (CheckThemeObj3(xp, yp, t, objrnd[leveltype - 1])) {
|
||||
if (CheckThemeObj3({ xp, yp }, themes[t].ttval, objrnd[leveltype - 1])) {
|
||||
themex = xp;
|
||||
themey = yp;
|
||||
return true;
|
||||
|
|
@ -717,7 +705,7 @@ void Theme_Library(int t)
|
|||
|
||||
for (int yp = 1; yp < MAXDUNY - 1; yp++) {
|
||||
for (int xp = 1; xp < MAXDUNX - 1; xp++) {
|
||||
if (CheckThemeObj3(xp, yp, t, -1) && dMonster[xp][yp] == 0 && GenerateRnd(librnd[leveltype - 1]) == 0) {
|
||||
if (CheckThemeObj3({ xp, yp }, themes[t].ttval, -1) && dMonster[xp][yp] == 0 && GenerateRnd(librnd[leveltype - 1]) == 0) {
|
||||
AddObject(OBJ_BOOKSTAND, { xp, yp });
|
||||
if (GenerateRnd(2 * librnd[leveltype - 1]) != 0) {
|
||||
Object *bookstand = ObjectAtPosition({ xp, yp });
|
||||
|
|
@ -753,7 +741,7 @@ void Theme_Torture(int t)
|
|||
for (int yp = 1; yp < MAXDUNY - 1; yp++) {
|
||||
for (int xp = 1; xp < MAXDUNX - 1; xp++) {
|
||||
if (dTransVal[xp][yp] == themes[t].ttval && IsTileNotSolid({ xp, yp })) {
|
||||
if (CheckThemeObj3(xp, yp, t, -1)) {
|
||||
if (CheckThemeObj3({ xp, yp }, themes[t].ttval, -1)) {
|
||||
if (GenerateRnd(tortrnd[leveltype - 1]) == 0) {
|
||||
AddObject(OBJ_TNUDEM2, { xp, yp });
|
||||
}
|
||||
|
|
@ -790,7 +778,7 @@ void Theme_Decap(int t)
|
|||
for (int yp = 1; yp < MAXDUNY - 1; yp++) {
|
||||
for (int xp = 1; xp < MAXDUNX - 1; xp++) {
|
||||
if (dTransVal[xp][yp] == themes[t].ttval && IsTileNotSolid({ xp, yp })) {
|
||||
if (CheckThemeObj3(xp, yp, t, -1)) {
|
||||
if (CheckThemeObj3({ xp, yp }, themes[t].ttval, -1)) {
|
||||
if (GenerateRnd(decaprnd[leveltype - 1]) == 0) {
|
||||
AddObject(OBJ_DECAP, { xp, yp });
|
||||
}
|
||||
|
|
@ -832,7 +820,7 @@ void Theme_ArmorStand(int t)
|
|||
for (int yp = 0; yp < MAXDUNY; yp++) {
|
||||
for (int xp = 0; xp < MAXDUNX; xp++) {
|
||||
if (dTransVal[xp][yp] == themes[t].ttval && IsTileNotSolid({ xp, yp })) {
|
||||
if (CheckThemeObj3(xp, yp, t, -1)) {
|
||||
if (CheckThemeObj3({ xp, yp }, themes[t].ttval, -1)) {
|
||||
if (GenerateRnd(armorrnd[leveltype - 1]) == 0) {
|
||||
AddObject(OBJ_ARMORSTANDN, { xp, yp });
|
||||
}
|
||||
|
|
@ -917,7 +905,7 @@ void Theme_BrnCross(int t)
|
|||
for (int yp = 0; yp < MAXDUNY; yp++) {
|
||||
for (int xp = 0; xp < MAXDUNX; xp++) {
|
||||
if (dTransVal[xp][yp] == themes[t].ttval && IsTileNotSolid({ xp, yp })) {
|
||||
if (CheckThemeObj3(xp, yp, t, -1)) {
|
||||
if (CheckThemeObj3({ xp, yp }, themes[t].ttval, -1)) {
|
||||
if (GenerateRnd(bcrossrnd[leveltype - 1]) == 0) {
|
||||
AddObject(OBJ_TBCROSS, { xp, yp });
|
||||
}
|
||||
|
|
@ -945,7 +933,7 @@ void Theme_WeaponRack(int t)
|
|||
for (int yp = 0; yp < MAXDUNY; yp++) {
|
||||
for (int xp = 0; xp < MAXDUNX; xp++) {
|
||||
if (dTransVal[xp][yp] == themes[t].ttval && IsTileNotSolid({ xp, yp })) {
|
||||
if (CheckThemeObj3(xp, yp, t, -1)) {
|
||||
if (CheckThemeObj3({ xp, yp }, themes[t].ttval, -1)) {
|
||||
if (GenerateRnd(weaponrnd[leveltype - 1]) == 0) {
|
||||
AddObject(OBJ_WEAPONRACKN, { xp, yp });
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue