Browse Source

Use FlipCoin for most uses of GenerateRnd with variable frequency

pull/4935/head
ephphatha 4 years ago committed by Anders Jenbo
parent
commit
420a248e0c
  1. 23
      Source/items.cpp
  2. 2
      Source/levels/drlg_l1.cpp
  3. 2
      Source/levels/drlg_l2.cpp
  4. 39
      Source/levels/drlg_l3.cpp
  5. 5
      Source/levels/drlg_l4.cpp
  6. 25
      Source/levels/gendung.cpp
  7. 100
      Source/levels/themes.cpp
  8. 16
      Source/monster.cpp
  9. 33
      Source/objects.cpp
  10. 26
      Source/player.cpp

23
Source/items.cpp

@ -1078,7 +1078,7 @@ void SaveItemAffix(Item &item, const PLStruct &affix)
void GetStaffPower(Item &item, int lvl, int bs, bool onlygood)
{
int preidx = -1;
if (GenerateRnd(10) == 0 || onlygood) {
if (FlipCoin(10) || onlygood) {
int nl = 0;
int l[256];
for (int j = 0; ItemPrefixes[j].power.type != IPL_INVALID; j++) {
@ -1150,20 +1150,21 @@ void GetItemPower(Item &item, int minlvl, int maxlvl, AffixItemType flgs, bool o
int l[256];
goodorevil goe;
int pre = GenerateRnd(4);
int post = GenerateRnd(3);
if (pre != 0 && post == 0) {
bool allocatePrefix = FlipCoin(4);
bool allocateSuffix = !FlipCoin(3);
if (!allocatePrefix && !allocateSuffix) {
// At least try and give each item a prefix or suffix
if (FlipCoin())
pre = 0;
allocatePrefix = true;
else
post = 1;
allocateSuffix = true;
}
int preidx = -1;
int sufidx = -1;
goe = GOE_ANY;
if (!onlygood && GenerateRnd(3) != 0)
if (!onlygood && !FlipCoin(3))
onlygood = true;
if (pre == 0) {
if (allocatePrefix) {
int nt = 0;
for (int j = 0; ItemPrefixes[j].power.type != IPL_INVALID; j++) {
if (!IsPrefixValidForItemType(j, flgs))
@ -1189,7 +1190,7 @@ void GetItemPower(Item &item, int minlvl, int maxlvl, AffixItemType flgs, bool o
goe = ItemPrefixes[preidx].PLGOE;
}
}
if (post != 0) {
if (allocateSuffix) {
int nl = 0;
for (int j = 0; ItemSuffixes[j].power.type != IPL_INVALID; j++) {
if (IsSuffixValidForItemType(j, flgs)
@ -1218,7 +1219,7 @@ void GetItemPower(Item &item, int minlvl, int maxlvl, AffixItemType flgs, bool o
void GetStaffSpell(Item &item, int lvl, bool onlygood)
{
if (!gbIsHellfire && GenerateRnd(4) == 0) {
if (!gbIsHellfire && FlipCoin(4)) {
GetItemPower(item, lvl / 2, lvl, AffixItemType::Staff, onlygood);
return;
}
@ -1591,7 +1592,7 @@ void SetupAllUseful(Item &item, int iseed, int lvl)
} else {
idx = PickRandomlyAmong({ IDI_MANA, IDI_HEAL });
if (lvl > 1 && GenerateRnd(3) == 0)
if (lvl > 1 && FlipCoin(3))
idx = IDI_PORTAL;
}

2
Source/levels/drlg_l1.cpp

@ -965,7 +965,7 @@ void Substitution()
{
for (int y = 0; y < DMAXY; y++) {
for (int x = 0; x < DMAXX; x++) {
if (GenerateRnd(4) == 0) {
if (FlipCoin(4)) {
uint8_t c = TileDecorations[dungeon[x][y]];
if (c != 0 && !Protected.test(x, y)) {
int rv = GenerateRnd(16);

2
Source/levels/drlg_l2.cpp

@ -2097,7 +2097,7 @@ void Substitution()
for (int x = 0; x < DMAXX; x++) {
if (SetPieceRoom.contains({ x, y }))
continue;
if (GenerateRnd(4) != 0)
if (!FlipCoin(4))
continue;
uint8_t c = BTYPESL2[dungeon[x][y]];

39
Source/levels/drlg_l3.cpp

@ -815,17 +815,19 @@ void CreateBlock(int x, int y, int obs, int dir)
}
if (FillRoom(x1, y1, x2, y2)) {
int contflag = GenerateRnd(4);
if (contflag != 0 && dir != 2) {
if (FlipCoin(4))
return;
if (dir != 2) {
CreateBlock(x1, y1, blksizey, 0);
}
if (contflag != 0 && dir != 3) {
if (dir != 3) {
CreateBlock(x2, y1, blksizex, 1);
}
if (contflag != 0 && dir != 0) {
if (dir != 0) {
CreateBlock(x1, y2, blksizey, 2);
}
if (contflag != 0 && dir != 1) {
if (dir != 1) {
CreateBlock(x1, y1, blksizex, 3);
}
}
@ -989,20 +991,10 @@ void MakeMegas()
for (int i = 0; i < DMAXX - 1; i++) {
int v = dungeon[i + 1][j + 1] + 2 * dungeon[i][j + 1] + 4 * dungeon[i + 1][j] + 8 * dungeon[i][j];
if (v == 6) {
int rv = GenerateRnd(2);
if (rv == 0) {
v = 12;
} else {
v = 5;
}
v = PickRandomlyAmong({ 12, 5 });
}
if (v == 9) {
int rv = GenerateRnd(2);
if (rv == 0) {
v = 13;
} else {
v = 14;
}
v = PickRandomlyAmong({ 13, 14 });
}
dungeon[i][j] = L3ConvTbl[v];
}
@ -1475,14 +1467,14 @@ bool PlaceLavaPool()
} else {
found = true;
}
int poolchance = GenerateRnd(100);
bool placePool = GenerateRnd(100) < 25;
for (int j = std::max(duny - totarea, 0); j < std::min(duny + totarea, DMAXY); j++) {
for (int i = std::max(dunx - totarea, 0); i < std::min(dunx + totarea, DMAXX); i++) {
// BUGFIX: In the following swap the order to first do the
// index checks and only then access dungeon[i][j] (fixed)
if ((dungeon[i][j] & 0x80) != 0) {
dungeon[i][j] &= ~0x80;
if (totarea > 4 && poolchance < 25 && !found) {
if (totarea > 4 && placePool && !found) {
uint8_t k = Poolsub[dungeon[i][j]];
if (k != 0 && k <= 37) {
dungeon[i][j] = k;
@ -1691,9 +1683,9 @@ void Fence()
for (int j = 1; j < DMAXY; j++) { // BUGFIX: Change '0' to '1' (fixed)
for (int i = 1; i < DMAXX; i++) { // BUGFIX: Change '0' to '1' (fixed)
if (dungeon[i][j] == 7 && GenerateRnd(1) == 0 && !IsNearThemeRoom({ i, j })) {
int rt = GenerateRnd(2);
if (rt == 0) {
// note the comma operator is used here to advance the RNG state
if (dungeon[i][j] == 7 && (AdvanceRndSeed(), !IsNearThemeRoom({ i, j }))) {
if (FlipCoin()) {
int y1 = j;
// BUGFIX: Check `y1 >= 0` first (fixed)
while (y1 >= 0 && FenceVerticalUp(i, y1)) {
@ -1742,8 +1734,7 @@ void Fence()
}
}
}
}
if (rt == 1) {
} else {
int x1 = i;
// BUGFIX: Check `x1 >= 0` first (fixed)
while (x1 >= 0 && FenceHorizontalLeft(x1, j)) {

5
Source/levels/drlg_l4.cpp

@ -811,7 +811,7 @@ void Substitution()
{
for (int y = 0; y < DMAXY; y++) {
for (int x = 0; x < DMAXX; x++) {
if (GenerateRnd(3) == 0) {
if (FlipCoin(3)) {
uint8_t c = L4BTYPES[dungeon[x][y]];
if (c != 0 && !Protected.test(x, y)) {
int rv = GenerateRnd(16);
@ -833,8 +833,7 @@ void Substitution()
}
for (int y = 0; y < DMAXY; y++) {
for (int x = 0; x < DMAXX; x++) {
int rv = GenerateRnd(10);
if (rv == 0) {
if (FlipCoin(10)) {
uint8_t c = dungeon[x][y];
if (L4BTYPES[c] == 6 && !Protected.test(x, y)) {
dungeon[x][y] = GenerateRnd(3) + 95;

25
Source/levels/gendung.cpp

@ -218,42 +218,31 @@ void CreateThemeRoom(int themeIndex)
}
if (leveltype == DTYPE_CATACOMBS) {
switch (GenerateRnd(2)) {
case 0:
if (FlipCoin())
dungeon[hx - 1][(ly + hy) / 2] = 4;
break;
case 1:
else
dungeon[(lx + hx) / 2][hy - 1] = 5;
break;
}
}
if (IsAnyOf(leveltype, DTYPE_CAVES, DTYPE_NEST)) {
switch (GenerateRnd(2)) {
case 0:
if (FlipCoin())
dungeon[hx - 1][(ly + hy) / 2] = 147;
break;
case 1:
else
dungeon[(lx + hx) / 2][hy - 1] = 146;
break;
}
}
if (leveltype == DTYPE_HELL) {
switch (GenerateRnd(2)) {
case 0: {
if (FlipCoin()) {
int yy = (ly + hy) / 2;
dungeon[hx - 1][yy - 1] = 53;
dungeon[hx - 1][yy] = 6;
dungeon[hx - 1][yy + 1] = 52;
dungeon[hx - 2][yy - 1] = 54;
} break;
case 1: {
} else {
int xx = (lx + hx) / 2;
dungeon[xx - 1][hy - 1] = 57;
dungeon[xx][hy - 1] = 6;
dungeon[xx + 1][hy - 1] = 56;
dungeon[xx][hy - 2] = 59;
dungeon[xx - 1][hy - 2] = 58;
} break;
}
}
}
@ -655,7 +644,7 @@ void DRLG_PlaceThemeRooms(int minSize, int maxSize, int floor, int freq, bool rn
for (int i = 0; i < DMAXX; i++) {
int themeW = 0;
int themeH = 0;
if (dungeon[i][j] == floor && GenerateRnd(freq) == 0 && WillThemeRoomFit(floor, i, j, minSize, maxSize, &themeW, &themeH)) {
if (dungeon[i][j] == floor && FlipCoin(freq) && WillThemeRoomFit(floor, i, j, minSize, maxSize, &themeW, &themeH)) {
if (rndSize) {
int min = minSize - 2;
int max = maxSize - 2;

100
Source/levels/themes.cpp

@ -169,7 +169,7 @@ bool TFit_GoatShrine(int t)
return false;
}
bool CheckThemeObj3(Point origin, int8_t regionId, int frequency)
bool CheckThemeObj3(Point origin, int8_t regionId, unsigned frequency)
{
const PointsInRectangleRange searchArea { Rectangle { origin, 1 } };
return std::all_of(searchArea.cbegin(), searchArea.cend(), [regionId, frequency](Point testPosition) {
@ -186,7 +186,7 @@ bool CheckThemeObj3(Point origin, int8_t regionId, int frequency)
if (IsObjectAtPosition(testPosition)) {
return false;
}
if (frequency != -1 && GenerateRnd(frequency) == 0) {
if (frequency != -1 && FlipCoin(frequency)) {
return false;
}
return true;
@ -195,7 +195,7 @@ bool CheckThemeObj3(Point origin, int8_t regionId, int frequency)
bool TFit_Obj3(int8_t regionId)
{
int objrnd[4] = { 4, 4, 3, 5 };
unsigned objrnd[4] = { 4, 4, 3, 5 };
for (int yp = 1; yp < MAXDUNY - 1; yp++) {
for (int xp = 1; xp < MAXDUNX - 1; xp++) {
@ -489,7 +489,7 @@ void PlaceThemeMonsts(int t, int f)
for (int yp = 0; yp < MAXDUNY; yp++) {
for (int xp = 0; xp < MAXDUNX; xp++) {
if (dTransVal[xp][yp] == themes[t].ttval && IsTileNotSolid({ xp, yp }) && dItem[xp][yp] == 0 && !IsObjectAtPosition({ xp, yp })) {
if (GenerateRnd(f) == 0) {
if (FlipCoin(f)) {
AddMonster({ xp, yp }, static_cast<Direction>(GenerateRnd(8)), mtype, true);
}
}
@ -510,11 +510,8 @@ void Theme_Barrel(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 (GenerateRnd(barrnd[leveltype - 1]) == 0) {
_object_id r = OBJ_BARREL;
if (GenerateRnd(barrnd[leveltype - 1]) != 0) {
r = OBJ_BARRELEX;
}
if (FlipCoin(barrnd[leveltype - 1])) {
_object_id r = FlipCoin(barrnd[leveltype - 1]) ? OBJ_BARREL : OBJ_BARRELEX;
AddObject(r, { xp, yp });
}
}
@ -577,6 +574,18 @@ void Theme_MonstPit(int t)
PlaceThemeMonsts(t, monstrnd[leveltype - 1]);
}
namespace {
void SpawnObjectOrSkeleton(unsigned frequency, _object_id objectType, Point tile)
{
if (FlipCoin(frequency)) {
AddObject(objectType, tile);
} else {
Monster *skeleton = PreSpawnSkeleton();
SpawnSkeleton(skeleton, tile);
}
}
} // namespace
/**
* Theme_SkelRoom initializes the skeleton room theme.
*
@ -584,7 +593,7 @@ void Theme_MonstPit(int t)
*/
void Theme_SkelRoom(int t)
{
int monstrnd[4] = { 6, 7, 3, 9 };
constexpr unsigned monstrnd[4] = { 6, 7, 3, 9 };
TFit_SkelRoom(t);
@ -593,54 +602,27 @@ void Theme_SkelRoom(int t)
AddObject(OBJ_SKFIRE, { xp, yp });
if (GenerateRnd(monstrnd[leveltype - 1]) != 0) {
Monster *skeleton = PreSpawnSkeleton();
SpawnSkeleton(skeleton, { xp - 1, yp - 1 });
} else {
AddObject(OBJ_BANNERL, { xp - 1, yp - 1 });
}
SpawnObjectOrSkeleton(monstrnd[leveltype - 1], OBJ_BANNERL, { xp - 1, yp - 1 });
{
Monster *skeleton = PreSpawnSkeleton();
SpawnSkeleton(skeleton, { xp, yp - 1 });
}
if (GenerateRnd(monstrnd[leveltype - 1]) != 0) {
Monster *skeleton = PreSpawnSkeleton();
SpawnSkeleton(skeleton, { xp + 1, yp - 1 });
} else {
AddObject(OBJ_BANNERR, { xp + 1, yp - 1 });
}
if (GenerateRnd(monstrnd[leveltype - 1]) != 0) {
Monster *skeleton = PreSpawnSkeleton();
SpawnSkeleton(skeleton, { xp - 1, yp });
} else {
AddObject(OBJ_BANNERM, { xp - 1, yp });
}
if (GenerateRnd(monstrnd[leveltype - 1]) != 0) {
Monster *skeleton = PreSpawnSkeleton();
SpawnSkeleton(skeleton, { xp + 1, yp });
} else {
AddObject(OBJ_BANNERM, { xp + 1, yp });
}
if (GenerateRnd(monstrnd[leveltype - 1]) != 0) {
Monster *skeleton = PreSpawnSkeleton();
SpawnSkeleton(skeleton, { xp - 1, yp + 1 });
} else {
AddObject(OBJ_BANNERR, { xp - 1, yp + 1 });
}
SpawnObjectOrSkeleton(monstrnd[leveltype - 1], OBJ_BANNERR, { xp + 1, yp - 1 });
SpawnObjectOrSkeleton(monstrnd[leveltype - 1], OBJ_BANNERM, { xp - 1, yp });
SpawnObjectOrSkeleton(monstrnd[leveltype - 1], OBJ_BANNERM, { xp + 1, yp });
SpawnObjectOrSkeleton(monstrnd[leveltype - 1], OBJ_BANNERR, { xp - 1, yp + 1 });
{
Monster *skeleton = PreSpawnSkeleton();
SpawnSkeleton(skeleton, { xp, yp + 1 });
}
if (GenerateRnd(monstrnd[leveltype - 1]) != 0) {
Monster *skeleton = PreSpawnSkeleton();
SpawnSkeleton(skeleton, { xp + 1, yp + 1 });
} else {
AddObject(OBJ_BANNERL, { xp + 1, yp + 1 });
}
SpawnObjectOrSkeleton(monstrnd[leveltype - 1], OBJ_BANNERL, { xp + 1, yp + 1 });
if (!IsObjectAtPosition({ xp, yp - 3 })) {
AddObject(OBJ_SKELBOOK, { xp, yp - 2 });
@ -694,7 +676,7 @@ void Theme_Treasure(int t)
*/
void Theme_Library(int t)
{
int librnd[4] = { 1, 2, 2, 5 };
constexpr unsigned librnd[4] = { 1, 2, 2, 5 };
int monstrnd[4] = { 5, 7, 3, 9 };
TFit_Shrine(t);
@ -711,9 +693,9 @@ 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 }, themes[t].ttval, -1) && dMonster[xp][yp] == 0 && GenerateRnd(librnd[leveltype - 1]) == 0) {
if (CheckThemeObj3({ xp, yp }, themes[t].ttval, -1) && dMonster[xp][yp] == 0 && FlipCoin(librnd[leveltype - 1])) {
AddObject(OBJ_BOOKSTAND, { xp, yp });
if (GenerateRnd(2 * librnd[leveltype - 1]) != 0) {
if (!FlipCoin(2 * librnd[leveltype - 1])) {
Object *bookstand = ObjectAtPosition({ xp, yp });
if (bookstand != nullptr) {
bookstand->_oSelFlag = 0;
@ -737,14 +719,14 @@ void Theme_Library(int t)
*/
void Theme_Torture(int t)
{
int tortrnd[4] = { 6, 8, 3, 8 };
constexpr unsigned tortrnd[4] = { 6, 8, 3, 8 };
int monstrnd[4] = { 6, 8, 3, 9 };
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 }, themes[t].ttval, -1)) {
if (GenerateRnd(tortrnd[leveltype - 1]) == 0) {
if (FlipCoin(tortrnd[leveltype - 1])) {
AddObject(OBJ_TNUDEM2, { xp, yp });
}
}
@ -774,14 +756,14 @@ void Theme_BloodFountain(int t)
*/
void Theme_Decap(int t)
{
int decaprnd[4] = { 6, 8, 3, 8 };
constexpr unsigned decaprnd[4] = { 6, 8, 3, 8 };
int monstrnd[4] = { 6, 8, 3, 9 };
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 }, themes[t].ttval, -1)) {
if (GenerateRnd(decaprnd[leveltype - 1]) == 0) {
if (FlipCoin(decaprnd[leveltype - 1])) {
AddObject(OBJ_DECAP, { xp, yp });
}
}
@ -812,7 +794,7 @@ void Theme_PurifyingFountain(int t)
*/
void Theme_ArmorStand(int t)
{
int armorrnd[4] = { 6, 8, 3, 8 };
constexpr unsigned armorrnd[4] = { 6, 8, 3, 8 };
int monstrnd[4] = { 6, 7, 3, 9 };
if (armorFlag) {
@ -823,7 +805,7 @@ void Theme_ArmorStand(int t)
for (int xp = 0; xp < MAXDUNX; xp++) {
if (dTransVal[xp][yp] == themes[t].ttval && IsTileNotSolid({ xp, yp })) {
if (CheckThemeObj3({ xp, yp }, themes[t].ttval, -1)) {
if (GenerateRnd(armorrnd[leveltype - 1]) == 0) {
if (FlipCoin(armorrnd[leveltype - 1])) {
AddObject(OBJ_ARMORSTANDN, { xp, yp });
}
}
@ -903,13 +885,13 @@ void Theme_BrnCross(int t)
{
int8_t regionId = themes[t].ttval;
int monstrnd[4] = { 6, 8, 3, 9 };
int bcrossrnd[4] = { 5, 7, 3, 8 };
constexpr unsigned bcrossrnd[4] = { 5, 7, 3, 8 };
for (int yp = 0; yp < MAXDUNY; yp++) {
for (int xp = 0; xp < MAXDUNX; xp++) {
if (dTransVal[xp][yp] == regionId && IsTileNotSolid({ xp, yp })) {
if (CheckThemeObj3({ xp, yp }, regionId, -1)) {
if (GenerateRnd(bcrossrnd[leveltype - 1]) == 0) {
if (FlipCoin(bcrossrnd[leveltype - 1])) {
AddObject(OBJ_TBCROSS, { xp, yp });
}
}
@ -927,7 +909,7 @@ void Theme_BrnCross(int t)
void Theme_WeaponRack(int t)
{
int8_t regionId = themes[t].ttval;
int weaponrnd[4] = { 6, 8, 5, 8 };
constexpr unsigned weaponrnd[4] = { 6, 8, 5, 8 };
int monstrnd[4] = { 6, 7, 3, 9 };
if (weaponFlag) {
@ -938,7 +920,7 @@ void Theme_WeaponRack(int t)
for (int xp = 0; xp < MAXDUNX; xp++) {
if (dTransVal[xp][yp] == regionId && IsTileNotSolid({ xp, yp })) {
if (CheckThemeObj3({ xp, yp }, regionId, -1)) {
if (GenerateRnd(weaponrnd[leveltype - 1]) == 0) {
if (FlipCoin(weaponrnd[leveltype - 1])) {
AddObject(OBJ_WEAPONRACKN, { xp, yp });
}
}

16
Source/monster.cpp

@ -1004,8 +1004,8 @@ std::optional<Point> GetTeleportTile(const Monster &monster)
{
int mx = monster.enemyPosition.x;
int my = monster.enemyPosition.y;
int rx = 2 * GenerateRnd(2) - 1;
int ry = 2 * GenerateRnd(2) - 1;
int rx = PickRandomlyAmong({ -1, 1 });
int ry = PickRandomlyAmong({ -1, 1 });
for (int j = -1; j <= 1; j++) {
for (int k = -1; k < 1; k++) {
@ -2005,7 +2005,7 @@ void AiAvoidance(int monsterId)
MonstCheckDoors(monster);
int v = GenerateRnd(100);
if ((abs(mx) >= 2 || abs(my) >= 2) && monster.activeForTicks == UINT8_MAX && dTransVal[monster.position.tile.x][monster.position.tile.y] == dTransVal[fx][fy]) {
if (monster.goal == MGOAL_MOVE || ((abs(mx) >= 4 || abs(my) >= 4) && GenerateRnd(4) == 0)) {
if (monster.goal == MGOAL_MOVE || ((abs(mx) >= 4 || abs(my) >= 4) && FlipCoin(4))) {
if (monster.goal != MGOAL_MOVE) {
monster.goalVar1 = 0;
monster.goalVar2 = GenerateRnd(2);
@ -2145,7 +2145,7 @@ void AiRangedAvoidance(int monsterId)
int v = GenerateRnd(10000);
int dist = std::max(abs(mx), abs(my));
if (dist >= 2 && monster.activeForTicks == UINT8_MAX && dTransVal[monster.position.tile.x][monster.position.tile.y] == dTransVal[fx][fy]) {
if (monster.goal == MGOAL_MOVE || (dist >= 3 && GenerateRnd(4 << lessmissiles) == 0)) {
if (monster.goal == MGOAL_MOVE || (dist >= 3 && FlipCoin(4 << lessmissiles))) {
if (monster.goal != MGOAL_MOVE) {
monster.goalVar1 = 0;
monster.goalVar2 = GenerateRnd(2);
@ -2417,7 +2417,7 @@ void RhinoAi(int monsterId)
int v = GenerateRnd(100);
int dist = std::max(abs(mx), abs(my));
if (dist >= 2) {
if (monster.goal == MGOAL_MOVE || (dist >= 5 && GenerateRnd(4) != 0)) {
if (monster.goal == MGOAL_MOVE || (dist >= 5 && !FlipCoin(4))) {
if (monster.goal != MGOAL_MOVE) {
monster.goalVar1 = 0;
monster.goalVar2 = GenerateRnd(2);
@ -2486,7 +2486,7 @@ void FallenAi(int monsterId)
}
if (monster.animInfo.currentFrame == monster.animInfo.numberOfFrames - 1) {
if (GenerateRnd(4) != 0) {
if (!FlipCoin(4)) {
return;
}
if ((monster.flags & MFLAG_NOHEAL) == 0) {
@ -2549,7 +2549,7 @@ void LeoricAi(int monsterId)
int v = GenerateRnd(100);
int dist = std::max(abs(mx), abs(my));
if (dist >= 2 && monster.activeForTicks == UINT8_MAX && dTransVal[monster.position.tile.x][monster.position.tile.y] == dTransVal[fx][fy]) {
if (monster.goal == MGOAL_MOVE || ((abs(mx) >= 3 || abs(my) >= 3) && GenerateRnd(4) == 0)) {
if (monster.goal == MGOAL_MOVE || ((abs(mx) >= 3 || abs(my) >= 3) && FlipCoin(4))) {
if (monster.goal != MGOAL_MOVE) {
monster.goalVar1 = 0;
monster.goalVar2 = GenerateRnd(2);
@ -3232,7 +3232,7 @@ void HorkDemonAi(int monsterId)
if (abs(mx) < 2 && abs(my) < 2) {
monster.goal = MGOAL_NORMAL;
} else if (monster.goal == 4 || ((abs(mx) >= 5 || abs(my) >= 5) && GenerateRnd(4) != 0)) {
} else if (monster.goal == 4 || ((abs(mx) >= 5 || abs(my) >= 5) && !FlipCoin(4))) {
if (monster.goal != 4) {
monster.goalVar1 = 0;
monster.goalVar2 = GenerateRnd(2);

33
Source/objects.cpp

@ -494,14 +494,14 @@ void InitRndBarrels()
xp = GenerateRnd(80) + 16;
yp = GenerateRnd(80) + 16;
} while (!RndLocOk(xp, yp));
_object_id o = (GenerateRnd(4) != 0) ? barrelId : explosiveBarrelId;
_object_id o = FlipCoin(4) ? explosiveBarrelId : barrelId;
AddObject(o, { xp, yp });
bool found = true;
/** regulates chance to stop placing barrels in current group */
int p = 0;
/** number of barrels in current group */
int c = 1;
while (GenerateRnd(p) == 0 && found) {
while (FlipCoin(p) && found) {
/** number of tries of placing next barrel in current group */
int t = 0;
found = false;
@ -517,7 +517,7 @@ void InitRndBarrels()
break;
}
if (found) {
o = (GenerateRnd(5) != 0) ? barrelId : explosiveBarrelId;
o = FlipCoin(5) ? explosiveBarrelId : barrelId;
AddObject(o, { xp, yp });
c++;
}
@ -535,19 +535,19 @@ void AddL2Torches()
continue;
int pn = dPiece[i][j];
if (pn == 0 && GenerateRnd(3) == 0) {
if (pn == 0 && FlipCoin(3)) {
AddObject(OBJ_TORCHL2, testPosition);
}
if (pn == 4 && GenerateRnd(3) == 0) {
if (pn == 4 && FlipCoin(3)) {
AddObject(OBJ_TORCHR2, testPosition);
}
if (pn == 36 && GenerateRnd(10) == 0 && !IsObjectAtPosition(testPosition + Direction::NorthWest)) {
if (pn == 36 && FlipCoin(10) && !IsObjectAtPosition(testPosition + Direction::NorthWest)) {
AddObject(OBJ_TORCHL, testPosition + Direction::NorthWest);
}
if (pn == 40 && GenerateRnd(10) == 0 && !IsObjectAtPosition(testPosition + Direction::NorthEast)) {
if (pn == 40 && FlipCoin(10) && !IsObjectAtPosition(testPosition + Direction::NorthEast)) {
AddObject(OBJ_TORCHR, testPosition + Direction::NorthEast);
}
}
@ -890,7 +890,7 @@ void AddHookedBodies(int freq)
int ii = 16 + i * 2;
if (dungeon[i][j] != 1 && dungeon[i][j] != 2)
continue;
if (GenerateRnd(freq) != 0)
if (!FlipCoin(freq))
continue;
if (IsNearThemeRoom({ i, j }))
continue;
@ -909,14 +909,7 @@ void AddHookedBodies(int freq)
continue;
}
if (dungeon[i][j] == 2 && dungeon[i][j + 1] == 6) {
switch (GenerateRnd(2)) {
case 0:
AddObject(OBJ_TORTURE3, { ii, jj });
break;
case 1:
AddObject(OBJ_TORTURE4, { ii, jj });
break;
}
AddObject(PickRandomlyAmong({ OBJ_TORTURE3, OBJ_TORTURE4 }), { ii, jj });
}
}
}
@ -3262,7 +3255,7 @@ void OperateShrineMurphys(Player &player)
bool broke = false;
for (auto &item : player.InvBody) {
if (!item.isEmpty() && GenerateRnd(3) == 0) {
if (!item.isEmpty() && FlipCoin(3)) {
if (item._iDurability != DUR_INDESTRUCTIBLE) {
if (item._iDurability > 0) {
item._iDurability /= 2;
@ -3418,10 +3411,10 @@ void OperateSkelBook(int i, bool sendmsg, bool sendLootMsg)
Objects[i]._oSelFlag = 0;
Objects[i]._oAnimFrame += 2;
SetRndSeed(Objects[i]._oRndSeed);
if (GenerateRnd(5) != 0)
CreateTypeItem(Objects[i].position, false, ItemType::Misc, IMISC_SCROLL, sendLootMsg, false);
else
if (FlipCoin(5))
CreateTypeItem(Objects[i].position, false, ItemType::Misc, IMISC_BOOK, sendLootMsg, false);
else
CreateTypeItem(Objects[i].position, false, ItemType::Misc, IMISC_SCROLL, sendLootMsg, false);
if (sendmsg)
NetSendCmdParam1(false, CMD_OPERATEOBJ, i);
}

26
Source/player.cpp

@ -726,7 +726,7 @@ bool WeaponDecay(Player &player, int ii)
return false;
}
bool DamageWeapon(Player &player, int durrnd)
bool DamageWeapon(Player &player, unsigned damageFrequency)
{
if (&player != MyPlayer) {
return false;
@ -737,7 +737,7 @@ bool DamageWeapon(Player &player, int durrnd)
if (WeaponDecay(player, INVLOC_HAND_RIGHT))
return true;
if (GenerateRnd(durrnd) != 0) {
if (!FlipCoin(damageFrequency)) {
return false;
}
@ -1281,7 +1281,7 @@ bool DoBlock(int pnum)
StartStand(pnum, player._pdir);
ClearStateVariables(player);
if (GenerateRnd(10) == 0) {
if (FlipCoin(10)) {
DamageParryItem(player);
}
return true;
@ -1300,19 +1300,19 @@ void DamageArmor(Player &player)
return;
}
int a = GenerateRnd(3);
bool targetHead = GenerateRnd(3);
if (!player.InvBody[INVLOC_CHEST].isEmpty() && player.InvBody[INVLOC_HEAD].isEmpty()) {
a = 1;
targetHead = false;
}
if (player.InvBody[INVLOC_CHEST].isEmpty() && !player.InvBody[INVLOC_HEAD].isEmpty()) {
a = 0;
targetHead = true;
}
Item *pi;
if (a != 0) {
pi = &player.InvBody[INVLOC_CHEST];
} else {
if (targetHead) {
pi = &player.InvBody[INVLOC_HEAD];
} else {
pi = &player.InvBody[INVLOC_CHEST];
}
if (pi->_iDurability == DUR_INDESTRUCTIBLE) {
return;
@ -1323,10 +1323,10 @@ void DamageArmor(Player &player)
return;
}
if (a != 0) {
RemoveEquipment(player, INVLOC_CHEST, true);
} else {
if (targetHead) {
RemoveEquipment(player, INVLOC_HEAD, true);
} else {
RemoveEquipment(player, INVLOC_CHEST, true);
}
CalcPlrInv(player, true);
}
@ -1372,7 +1372,7 @@ bool DoGotHit(int pnum)
if (player.AnimInfo.currentFrame >= player._pHFrames - 1) {
StartStand(pnum, player._pdir);
ClearStateVariables(player);
if (GenerateRnd(4) != 0) {
if (!FlipCoin(4)) {
DamageArmor(player);
}

Loading…
Cancel
Save