From bb3fb36ddc744d3e3265d752bfbc85d87a24184a Mon Sep 17 00:00:00 2001 From: Cesar Canassa Date: Thu, 7 Jul 2022 20:57:03 +0200 Subject: [PATCH] :sparkles: Introduces FlipCoin() (#4908) --- Source/engine/random.cpp | 5 +++++ Source/engine/random.hpp | 9 +++++++++ Source/items.cpp | 6 +++--- Source/levels/drlg_l1.cpp | 14 +++++++------- Source/levels/drlg_l3.cpp | 38 +++++++++++++++++++------------------- Source/missiles.cpp | 8 ++++---- Source/monster.cpp | 18 +++++++++--------- Source/objects.cpp | 8 ++++---- Source/quests.cpp | 2 +- 9 files changed, 61 insertions(+), 47 deletions(-) diff --git a/Source/engine/random.cpp b/Source/engine/random.cpp index fa11f74a5..bc83a14d8 100644 --- a/Source/engine/random.cpp +++ b/Source/engine/random.cpp @@ -51,4 +51,9 @@ int32_t GenerateRnd(int32_t v) return AdvanceRndSeed() % v; } +bool FlipCoin() +{ + return GenerateRnd(2) != 0; +} + } // namespace devilution diff --git a/Source/engine/random.hpp b/Source/engine/random.hpp index 59ae02e98..894f0ff47 100644 --- a/Source/engine/random.hpp +++ b/Source/engine/random.hpp @@ -59,6 +59,15 @@ int32_t AdvanceRndSeed(); */ int32_t GenerateRnd(int32_t v); +/** + * @brief Generates a random boolean value using the vanilla RNG + * + * This function returns true 50% of the time and false 50% of the time. + * + * @return A random boolean value + */ +bool FlipCoin(); + /** * @brief Picks one of the elements in the list randomly. * diff --git a/Source/items.cpp b/Source/items.cpp index 5f969c4e7..3b7f84844 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -438,7 +438,7 @@ void AddInitItems() item._iSeed = AdvanceRndSeed(); SetRndSeed(item._iSeed); - if (GenerateRnd(2) != 0) + if (FlipCoin()) GetItemAttrs(item, IDI_HEAL, curlv); else GetItemAttrs(item, IDI_MANA, curlv); @@ -1156,7 +1156,7 @@ void GetItemPower(Item &item, int minlvl, int maxlvl, AffixItemType flgs, bool o int pre = GenerateRnd(4); int post = GenerateRnd(3); if (pre != 0 && post == 0) { - if (GenerateRnd(2) != 0) + if (FlipCoin()) post = 1; else pre = 0; @@ -1592,7 +1592,7 @@ void SetupAllUseful(Item &item, int iseed, int lvl) break; } } else { - if (GenerateRnd(2) != 0) + if (FlipCoin()) idx = IDI_HEAL; else idx = IDI_MANA; diff --git a/Source/levels/drlg_l1.cpp b/Source/levels/drlg_l1.cpp index 217f822de..b7e04daae 100644 --- a/Source/levels/drlg_l1.cpp +++ b/Source/levels/drlg_l1.cpp @@ -954,10 +954,10 @@ void GenerateRoom(int x, int y, int w, int h, int dir) void FirstRoom() { - VerticalLayout = GenerateRnd(2) == 0; - HasChamber1 = (GenerateRnd(2) != 0); - HasChamber2 = (GenerateRnd(2) != 0); - HasChamber3 = (GenerateRnd(2) != 0); + VerticalLayout = !FlipCoin(); + HasChamber1 = FlipCoin(); + HasChamber2 = FlipCoin(); + HasChamber3 = FlipCoin(); if (!HasChamber1 || !HasChamber3) HasChamber2 = true; @@ -1497,11 +1497,11 @@ Point SelectChamber() { int chamber; if (!HasChamber1) - chamber = GenerateRnd(2) != 0 ? 3 : 2; + chamber = FlipCoin() ? 3 : 2; else if (!HasChamber2) - chamber = GenerateRnd(2) != 0 ? 1 : 3; + chamber = FlipCoin() ? 1 : 3; else if (!HasChamber3) - chamber = GenerateRnd(2) != 0 ? 1 : 2; + chamber = FlipCoin() ? 1 : 2; else chamber = GenerateRnd(3) + 1; diff --git a/Source/levels/drlg_l3.cpp b/Source/levels/drlg_l3.cpp index 645f72f89..53614c886 100644 --- a/Source/levels/drlg_l3.cpp +++ b/Source/levels/drlg_l3.cpp @@ -729,18 +729,18 @@ bool FillRoom(int x1, int y1, int x2, int y2) } } for (int j = y1; j <= y2; j++) { - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { dungeon[x1][j] = 1; } - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { dungeon[x2][j] = 1; } } for (int i = x1; i <= x2; i++) { - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { dungeon[i][y1] = 1; } - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { dungeon[i][y2] = 1; } } @@ -847,14 +847,14 @@ void FillDiagonals() 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) { - if (GenerateRnd(2) == 0) { + if (!FlipCoin()) { dungeon[i][j] = 1; } else { dungeon[i + 1][j + 1] = 1; } } if (v == 9) { - if (GenerateRnd(2) == 0) { + if (!FlipCoin()) { dungeon[i + 1][j] = 1; } else { dungeon[i][j + 1] = 1; @@ -892,7 +892,7 @@ void FillStraights() } xs++; } else { - if (xs > 3 && GenerateRnd(2) != 0) { + if (xs > 3 && FlipCoin()) { for (int k = xc; k < i; k++) { int rv = GenerateRnd(2); dungeon[k][j] = rv; @@ -911,7 +911,7 @@ void FillStraights() } xs++; } else { - if (xs > 3 && GenerateRnd(2) != 0) { + if (xs > 3 && FlipCoin()) { for (int k = xc; k < i; k++) { int rv = GenerateRnd(2); dungeon[k][j + 1] = rv; @@ -930,7 +930,7 @@ void FillStraights() } ys++; } else { - if (ys > 3 && GenerateRnd(2) != 0) { + if (ys > 3 && FlipCoin()) { for (int k = yc; k < j; k++) { int rv = GenerateRnd(2); dungeon[i][k] = rv; @@ -949,7 +949,7 @@ void FillStraights() } ys++; } else { - if (ys > 3 && GenerateRnd(2) != 0) { + if (ys > 3 && FlipCoin()) { for (int k = yc; k < j; k++) { int rv = GenerateRnd(2); dungeon[i + 1][k] = rv; @@ -1638,7 +1638,7 @@ void Fence() { for (int j = 1; j < DMAXY - 1; j++) { // BUGFIX: Change '0' to '1' (fixed) for (int i = 1; i < DMAXX - 1; i++) { // BUGFIX: Change '0' to '1' (fixed) - if (dungeon[i][j] == 10 && GenerateRnd(2) != 0) { + if (dungeon[i][j] == 10 && FlipCoin()) { int x = i; while (dungeon[x][j] == 10) { x++; @@ -1647,7 +1647,7 @@ void Fence() if (x - i > 0) { dungeon[i][j] = 127; for (int xx = i + 1; xx < x; xx++) { - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { dungeon[xx][j] = 126; } else { dungeon[xx][j] = 129; @@ -1656,7 +1656,7 @@ void Fence() dungeon[x][j] = 128; } } - if (dungeon[i][j] == 9 && GenerateRnd(2) != 0) { + if (dungeon[i][j] == 9 && FlipCoin()) { int y = j; while (dungeon[i][y] == 9) { y++; @@ -1665,7 +1665,7 @@ void Fence() if (y - j > 0) { dungeon[i][j] = 123; for (int yy = j + 1; yy < y; yy++) { - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { dungeon[i][yy] = 121; } else { dungeon[i][yy] = 124; @@ -1674,7 +1674,7 @@ void Fence() dungeon[i][y] = 122; } } - if (dungeon[i][j] == 11 && dungeon[i + 1][j] == 10 && dungeon[i][j + 1] == 9 && GenerateRnd(2) != 0) { + if (dungeon[i][j] == 11 && dungeon[i + 1][j] == 10 && dungeon[i][j + 1] == 9 && FlipCoin()) { dungeon[i][j] = 125; int x = i + 1; while (dungeon[x][j] == 10) { @@ -1682,7 +1682,7 @@ void Fence() } x--; for (int xx = i + 1; xx < x; xx++) { - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { dungeon[xx][j] = 126; } else { dungeon[xx][j] = 129; @@ -1695,7 +1695,7 @@ void Fence() } y--; for (int yy = j + 1; yy < y; yy++) { - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { dungeon[i][yy] = 121; } else { dungeon[i][yy] = 124; @@ -1737,7 +1737,7 @@ void Fence() continue; } if (dungeon[i][y] == 7) { - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { dungeon[i][y] = 135; } else { dungeon[i][y] = 137; @@ -1791,7 +1791,7 @@ void Fence() continue; } if (dungeon[x][j] == 7) { - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { dungeon[x][j] = 134; } else { dungeon[x][j] = 136; diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 4411b9a4c..db34138cd 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -361,7 +361,7 @@ bool Plr2PlrMHit(const Player &player, int p, int mindam, int maxdam, int dist, void RotateBlockedMissile(Missile &missile) { - int rotation = GenerateRnd(2) != 0 ? 1 : -1; + int rotation = FlipCoin() ? 1 : -1; if (missile._miAnimType == MFILE_ARROWS) { int dir = missile._miAnimFrame + rotation; @@ -1148,7 +1148,7 @@ void AddBerserk(Missile &missile, const AddMissileParameter ¶meter) return false; if ((monster.magicResistance & IMMUNE_MAGIC) != 0) return false; - if ((monster.magicResistance & RESIST_MAGIC) != 0 && ((monster.magicResistance & RESIST_MAGIC) != 1 || GenerateRnd(2) != 0)) + if ((monster.magicResistance & RESIST_MAGIC) != 0 && ((monster.magicResistance & RESIST_MAGIC) != 1 || FlipCoin())) return false; return true; @@ -1231,7 +1231,7 @@ void AddStealPotions(Missile &missile, const AddMissileParameter & /*parameter*/ for (int si = 0; si < MaxBeltItems; si++) { int ii = -1; if (player.SpdList[si]._itype == ItemType::Misc) { - if (GenerateRnd(2) == 0) + if (!FlipCoin()) continue; switch (player.SpdList[si]._iMiscId) { case IMISC_FULLHEAL: @@ -1245,7 +1245,7 @@ void AddStealPotions(Missile &missile, const AddMissileParameter & /*parameter*/ ii = ItemMiscIdIdx(IMISC_MANA); break; case IMISC_REJUV: - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { ii = ItemMiscIdIdx(IMISC_MANA); } else { ii = ItemMiscIdIdx(IMISC_HEAL); diff --git a/Source/monster.cpp b/Source/monster.cpp index 5d9ff4234..8420d0b76 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -1818,11 +1818,11 @@ bool RandomWalk(int monsterId, Direction md) Monster &monster = Monsters[monsterId]; bool ok = DirOK(monsterId, md); - if (GenerateRnd(2) != 0) + if (FlipCoin()) ok = ok || (md = Left(mdtemp), DirOK(monsterId, md)) || (md = Right(mdtemp), DirOK(monsterId, md)); else ok = ok || (md = Right(mdtemp), DirOK(monsterId, md)) || (md = Left(mdtemp), DirOK(monsterId, md)); - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { ok = ok || (md = Right(Right(mdtemp)), DirOK(monsterId, md)) || (md = Left(Left(mdtemp)), DirOK(monsterId, md)); @@ -1842,7 +1842,7 @@ bool RandomWalk2(int monsterId, Direction md) Direction mdtemp = md; bool ok = DirOK(monsterId, md); // Can we continue in the same direction - if (GenerateRnd(2) != 0) { // Randomly go left or right + if (FlipCoin()) { // Randomly go left or right ok = ok || (mdtemp = Left(md), DirOK(monsterId, Left(md))) || (mdtemp = Right(md), DirOK(monsterId, Right(md))); } else { ok = ok || (mdtemp = Right(md), DirOK(monsterId, Right(md))) || (mdtemp = Left(md), DirOK(monsterId, Left(md))); @@ -2052,7 +2052,7 @@ void AiAvoidance(int monsterId) } } else if (v < 2 * monster.intelligence + 23) { monster.direction = md; - if (IsAnyOf(monster.ai, AI_GOATMC, AI_GARBUD) && monster.hitPoints < (monster.maxHitPoints / 2) && GenerateRnd(2) != 0) + if (IsAnyOf(monster.ai, AI_GOATMC, AI_GARBUD) && monster.hitPoints < (monster.maxHitPoints / 2) && FlipCoin()) StartSpecialAttack(monster); else StartAttack(monster); @@ -2337,7 +2337,7 @@ void SkeletonBowAi(int monsterId) std::optional ScavengerFindCorpse(const Monster &scavenger) { - bool lowToHigh = GenerateRnd(2) != 0; + bool lowToHigh = FlipCoin(); int first = lowToHigh ? -4 : 4; int last = lowToHigh ? 4 : -4; int increment = lowToHigh ? 1 : -1; @@ -2632,7 +2632,7 @@ void BatAi(int monsterId) RandomWalk(monsterId, Opposite(md)); monster.goalVar1++; } else { - if (GenerateRnd(2) != 0) + if (FlipCoin()) RandomWalk(monsterId, Left(md)); else RandomWalk(monsterId, Right(md)); @@ -2763,7 +2763,7 @@ void SneakAi(int monsterId) md = GetDirection(monster.position.tile, Players[monster.enemy].position.last); md = Opposite(md); if (monster.type().type == MT_UNSEEN) { - if (GenerateRnd(2) != 0) + if (FlipCoin()) md = Left(md); else md = Right(md); @@ -3094,7 +3094,7 @@ void MegaAi(int monsterId) } else { if (GenerateRnd(100) < 10 * (monster.intelligence + 4)) { monster.direction = md; - if (GenerateRnd(2) != 0) + if (FlipCoin()) StartAttack(monster); else StartRangedSpecialAttack(monster, MIS_FLAMEC, 0); @@ -3776,7 +3776,7 @@ void InitMonsters() } while (ActiveMonsterCount < totalmonsters) { int mtype = scattertypes[GenerateRnd(numscattypes)]; - if (currlevel == 1 || GenerateRnd(2) == 0) + if (currlevel == 1 || !FlipCoin()) na = 1; else if (currlevel == 2 || leveltype == DTYPE_CRYPT) na = GenerateRnd(2) + 2; diff --git a/Source/objects.cpp b/Source/objects.cpp index 1c0061bc2..93c23f175 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -575,7 +575,7 @@ void AddObjTraps() continue; Object *trapObject = nullptr; - if (GenerateRnd(2) == 0) { + if (!FlipCoin()) { int xp = i - 1; while (IsTileNotSolid({ xp, j })) xp--; @@ -987,7 +987,7 @@ void DeleteObject(int oi, int i) void AddChest(int i, int t) { - if (GenerateRnd(2) == 0) + if (!FlipCoin()) Objects[i]._oAnimFrame += 3; Objects[i]._oRndSeed = AdvanceRndSeed(); switch (t) { @@ -1167,7 +1167,7 @@ void AddShrine(int i) } while (!slist[val]); Objects[i]._oVar1 = val; - if (GenerateRnd(2) != 0) { + if (FlipCoin()) { Objects[i]._oAnimFrame = 12; Objects[i]._oAnimLen = 22; } @@ -3474,7 +3474,7 @@ void OperateArmorStand(int i, bool sendmsg, bool sendLootMsg) Objects[i]._oSelFlag = 0; Objects[i]._oAnimFrame++; SetRndSeed(Objects[i]._oRndSeed); - bool uniqueRnd = (GenerateRnd(2) != 0); + bool uniqueRnd = FlipCoin(); if (currlevel <= 5) { CreateTypeItem(Objects[i].position, true, ItemType::LightArmor, IMISC_NONE, sendLootMsg, false); } else if (currlevel >= 6 && currlevel <= 9) { diff --git a/Source/quests.cpp b/Source/quests.cpp index 0026c6b5b..82c47f40c 100644 --- a/Source/quests.cpp +++ b/Source/quests.cpp @@ -282,7 +282,7 @@ void InitQuests() void InitialiseQuestPools(uint32_t seed, Quest quests[]) { SetRndSeed(seed); - if (GenerateRnd(2) != 0) + if (FlipCoin()) quests[Q_PWATER]._qactive = QUEST_NOTAVAIL; else quests[Q_SKELKING]._qactive = QUEST_NOTAVAIL;