Refactoring random.cc. Convert to class Random.

This commit is contained in:
Евгений 2022-05-24 00:11:03 +04:00
parent 55c28b451e
commit a9ea199f53
24 changed files with 206 additions and 210 deletions

View File

@ -293,8 +293,8 @@ void _show_damage_to_object(Object* a1, int damage, int flags, Object* weapon, b
reg_anim_animate(a1, anim, 0); reg_anim_animate(a1, anim, 0);
int randomDistance = randomBetween(2, 5); int randomDistance = Random::between(2, 5);
int randomRotation = randomBetween(0, 5); int randomRotation = Random::between(0, 5);
while (randomDistance > 0) { while (randomDistance > 0) {
int tile = tileGetTileInDirection(a1->tile, randomRotation, randomDistance); int tile = tileGetTileInDirection(a1->tile, randomRotation, randomDistance);
@ -1714,7 +1714,7 @@ int _finished_explosion(Object* a1, Object* a2)
// 0x4132CC // 0x4132CC
int _compute_explosion_damage(int min, int max, Object* a3, int* a4) int _compute_explosion_damage(int min, int max, Object* a3, int* a4)
{ {
int v5 = randomBetween(min, max); int v5 = Random::between(min, max);
int v7 = v5 - critterGetStat(a3, STAT_DAMAGE_THRESHOLD_EXPLOSION); int v7 = v5 - critterGetStat(a3, STAT_DAMAGE_THRESHOLD_EXPLOSION);
if (v7 > 0) { if (v7 > 0) {
v7 -= critterGetStat(a3, STAT_DAMAGE_RESISTANCE_EXPLOSION) * v7 / 100; v7 -= critterGetStat(a3, STAT_DAMAGE_RESISTANCE_EXPLOSION) * v7 / 100;
@ -1881,7 +1881,7 @@ int _compute_dmg_damage(int min, int max, Object* obj, int* a4, int damageType)
a4 = NULL; a4 = NULL;
} }
int v8 = randomBetween(min, max); int v8 = Random::between(min, max);
int v10 = v8 - critterGetStat(obj, STAT_DAMAGE_THRESHOLD + damageType); int v10 = v8 - critterGetStat(obj, STAT_DAMAGE_THRESHOLD + damageType);
if (v10 > 0) { if (v10 > 0) {
v10 -= critterGetStat(obj, STAT_DAMAGE_RESISTANCE + damageType) * v10 / 100; v10 -= critterGetStat(obj, STAT_DAMAGE_RESISTANCE + damageType) * v10 / 100;

View File

@ -2625,7 +2625,7 @@ void _dude_fidget()
int v13; int v13;
if (v5 != 0) { if (v5 != 0) {
int r = randomBetween(0, v5 - 1); int r = Random::between(0, v5 - 1);
Object* object = dword_56C7E0[r]; Object* object = dword_56C7E0[r];
reg_anim_begin(0x201); reg_anim_begin(0x201);
@ -2663,7 +2663,7 @@ void _dude_fidget()
v13 = 7; v13 = 7;
} }
_next_time = randomBetween(0, 3000) + 1000 * v13; _next_time = Random::between(0, 3000) + 1000 * v13;
} }
// 0x418378 // 0x418378

View File

@ -2701,11 +2701,11 @@ void _combat_give_exps(int exp_points)
return; return;
} }
v9.num = randomBetween(0, 3) + 622; // generate prefix for message v9.num = Random::between(0, 3) + 622; // generate prefix for message
current_hp = critterGetStat(gDude, STAT_CURRENT_HIT_POINTS); current_hp = critterGetStat(gDude, STAT_CURRENT_HIT_POINTS);
max_hp = critterGetStat(gDude, STAT_MAXIMUM_HIT_POINTS); max_hp = critterGetStat(gDude, STAT_MAXIMUM_HIT_POINTS);
if (current_hp == max_hp && randomBetween(0, 100) > 65) { if (current_hp == max_hp && Random::between(0, 100) > 65) {
v9.num = 626; // Best possible prefix: For destroying your enemies without taking a scratch, v9.num = 626; // Best possible prefix: For destroying your enemies without taking a scratch,
} }
@ -3288,7 +3288,7 @@ void attackInit(Attack* attack, Object* attacker, Object* defender, int hitMode,
// 0x422F3C // 0x422F3C
int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation) int _combat_attack(Object* a1, Object* a2, int hitMode, int hitLocation)
{ {
if (a1 != gDude && hitMode == HIT_MODE_PUNCH && randomBetween(1, 4) == 1) { if (a1 != gDude && hitMode == HIT_MODE_PUNCH && Random::between(1, 4) == 1) {
int fid = buildFid(1, a1->fid & 0xFFF, ANIM_KICK_LEG, (a1->fid & 0xF000) >> 12, (a1->fid & 0x70000000) >> 28); int fid = buildFid(1, a1->fid & 0xFFF, ANIM_KICK_LEG, (a1->fid & 0xF000) >> 12, (a1->fid & 0x70000000) >> 28);
if (artExists(fid)) { if (artExists(fid)) {
hitMode = HIT_MODE_KICK; hitMode = HIT_MODE_KICK;
@ -3373,7 +3373,7 @@ bool _check_ranged_miss(Attack* attack)
int range = _item_w_range(attack->attacker, attack->hitMode); int range = _item_w_range(attack->attacker, attack->hitMode);
int to = _tile_num_beyond(attack->attacker->tile, attack->defender->tile, range); int to = _tile_num_beyond(attack->attacker->tile, attack->defender->tile, range);
int roll = ROLL_FAILURE; int roll = Random::Roll::FAILURE;
Object* critter = attack->attacker; Object* critter = attack->attacker;
if (critter != NULL) { if (critter != NULL) {
int curr = attack->attacker->tile; int curr = attack->attacker->tile;
@ -3382,7 +3382,7 @@ bool _check_ranged_miss(Attack* attack)
if (critter != NULL) { if (critter != NULL) {
if ((critter->flags & OBJECT_FLAG_0x80000000) == 0) { if ((critter->flags & OBJECT_FLAG_0x80000000) == 0) {
if ((critter->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) { if ((critter->fid & 0xF000000) >> 24 != OBJ_TYPE_CRITTER) {
roll = ROLL_SUCCESS; roll = Random::Roll::SUCCESS;
break; break;
} }
@ -3392,8 +3392,8 @@ bool _check_ranged_miss(Attack* attack)
v6 = 5; v6 = 5;
} }
if (randomBetween(1, 100) <= v6) { if (Random::between(1, 100) <= v6) {
roll = ROLL_SUCCESS; roll = Random::Roll::SUCCESS;
break; break;
} }
} }
@ -3410,7 +3410,7 @@ bool _check_ranged_miss(Attack* attack)
attack->defenderHitLocation = HIT_LOCATION_TORSO; attack->defenderHitLocation = HIT_LOCATION_TORSO;
if (roll < ROLL_SUCCESS || critter == NULL || (critter->flags & OBJECT_FLAG_0x80000000) == 0) { if (roll < Random::Roll::SUCCESS || critter == NULL || (critter->flags & OBJECT_FLAG_0x80000000) == 0) {
return false; return false;
} }
@ -3448,7 +3448,7 @@ int _shoot_along_path(Attack* attack, int a2, int a3, int anim)
} }
int a2a = 0; int a2a = 0;
while (randomBetween(1, 100) <= v8 && v5 > 0) { while (Random::between(1, 100) <= v8 && v5 > 0) {
v5 -= 1; v5 -= 1;
a2a += 1; a2a += 1;
} }
@ -3510,13 +3510,13 @@ int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int anim)
*a4 = ammoQuantity; *a4 = ammoQuantity;
int criticalChance = critterGetStat(attack->attacker, STAT_CRITICAL_CHANCE); int criticalChance = critterGetStat(attack->attacker, STAT_CRITICAL_CHANCE);
int roll = randomRoll(accuracy, criticalChance, NULL); int roll = Random::roll(accuracy, criticalChance, NULL);
if (roll == ROLL_CRITICAL_FAILURE) { if (roll == Random::Roll::CRITICAL_FAILURE) {
return roll; return roll;
} }
if (roll == ROLL_CRITICAL_SUCCESS) { if (roll == Random::Roll::CRITICAL_SUCCESS) {
accuracy += 20; accuracy += 20;
} }
@ -3545,7 +3545,7 @@ int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int anim)
} }
for (int index = 0; index < v14; index += 1) { for (int index = 0; index < v14; index += 1) {
if (randomRoll(accuracy, 0, NULL) >= ROLL_SUCCESS) { if (Random::roll(accuracy, 0, NULL) >= Random::Roll::SUCCESS) {
*a3 += 1; *a3 += 1;
} }
} }
@ -3578,12 +3578,12 @@ int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int anim)
int v28 = _tile_num_beyond(attack->attacker->tile, v26, range); int v28 = _tile_num_beyond(attack->attacker->tile, v26, range);
*a3 += _shoot_along_path(attack, v28, v30, anim); *a3 += _shoot_along_path(attack, v28, v30, anim);
if (roll != ROLL_FAILURE || *a3 <= 0 && attack->extrasLength <= 0) { if (roll != Random::Roll::FAILURE || *a3 <= 0 && attack->extrasLength <= 0) {
if (roll >= ROLL_SUCCESS && *a3 == 0 && attack->extrasLength == 0) { if (roll >= Random::Roll::SUCCESS && *a3 == 0 && attack->extrasLength == 0) {
roll = ROLL_FAILURE; roll = Random::Roll::FAILURE;
} }
} else { } else {
roll = ROLL_SUCCESS; roll = Random::Roll::SUCCESS;
} }
return roll; return roll;
@ -3594,7 +3594,7 @@ int attackComputeEnhancedKnockout(Attack* attack)
{ {
if (weaponGetPerk(attack->weapon) == PERK_WEAPON_ENHANCED_KNOCKOUT) { if (weaponGetPerk(attack->weapon) == PERK_WEAPON_ENHANCED_KNOCKOUT) {
int difficulty = critterGetStat(attack->attacker, STAT_STRENGTH) - 8; int difficulty = critterGetStat(attack->attacker, STAT_STRENGTH) - 8;
int chance = randomBetween(1, 100); int chance = Random::between(1, 100);
if (chance <= difficulty) { if (chance <= difficulty) {
Object* weapon = NULL; Object* weapon = NULL;
if (attack->defender != gDude) { if (attack->defender != gDude) {
@ -3644,21 +3644,21 @@ int attackCompute(Attack* attack)
roll = _compute_spray(attack, accuracy, &ammoQuantity, &v26, anim); roll = _compute_spray(attack, accuracy, &ammoQuantity, &v26, anim);
} else { } else {
int chance = critterGetStat(attack->attacker, STAT_CRITICAL_CHANCE); int chance = critterGetStat(attack->attacker, STAT_CRITICAL_CHANCE);
roll = randomRoll(accuracy, chance - _hit_location_penalty[attack->defenderHitLocation], NULL); roll = Random::roll(accuracy, chance - _hit_location_penalty[attack->defenderHitLocation], NULL);
} }
if (roll == ROLL_FAILURE) { if (roll == Random::Roll::FAILURE) {
if (traitIsSelected(TRAIT_JINXED) || perkHasRank(gDude, PERK_JINXED)) { if (traitIsSelected(TRAIT_JINXED) || perkHasRank(gDude, PERK_JINXED)) {
if (randomBetween(0, 1) == 1) { if (Random::between(0, 1) == 1) {
roll = ROLL_CRITICAL_FAILURE; roll = Random::Roll::CRITICAL_FAILURE;
} }
} }
} }
if (roll == ROLL_SUCCESS) { if (roll == Random::Roll::SUCCESS) {
if ((attackType == ATTACK_TYPE_MELEE || attackType == ATTACK_TYPE_UNARMED) && attack->attacker == gDude) { if ((attackType == ATTACK_TYPE_MELEE || attackType == ATTACK_TYPE_UNARMED) && attack->attacker == gDude) {
if (perkHasRank(attack->attacker, PERK_SLAYER)) { if (perkHasRank(attack->attacker, PERK_SLAYER)) {
roll = ROLL_CRITICAL_SUCCESS; roll = Random::Roll::CRITICAL_SUCCESS;
} }
if (perkHasRank(gDude, PERK_SILENT_DEATH) if (perkHasRank(gDude, PERK_SILENT_DEATH)
@ -3668,13 +3668,13 @@ int attackCompute(Attack* attack)
damageMultiplier = 4; damageMultiplier = 4;
} }
if (((attack->hitMode == HIT_MODE_HAMMER_PUNCH || attack->hitMode == HIT_MODE_POWER_KICK) && randomBetween(1, 100) <= 5) if (((attack->hitMode == HIT_MODE_HAMMER_PUNCH || attack->hitMode == HIT_MODE_POWER_KICK) && Random::between(1, 100) <= 5)
|| ((attack->hitMode == HIT_MODE_JAB || attack->hitMode == HIT_MODE_HOOK_KICK) && randomBetween(1, 100) <= 10) || ((attack->hitMode == HIT_MODE_JAB || attack->hitMode == HIT_MODE_HOOK_KICK) && Random::between(1, 100) <= 10)
|| (attack->hitMode == HIT_MODE_HAYMAKER && randomBetween(1, 100) <= 15) || (attack->hitMode == HIT_MODE_HAYMAKER && Random::between(1, 100) <= 15)
|| (attack->hitMode == HIT_MODE_PALM_STRIKE && randomBetween(1, 100) <= 20) || (attack->hitMode == HIT_MODE_PALM_STRIKE && Random::between(1, 100) <= 20)
|| (attack->hitMode == HIT_MODE_PIERCING_STRIKE && randomBetween(1, 100) <= 40) || (attack->hitMode == HIT_MODE_PIERCING_STRIKE && Random::between(1, 100) <= 40)
|| (attack->hitMode == HIT_MODE_PIERCING_KICK && randomBetween(1, 100) <= 50)) { || (attack->hitMode == HIT_MODE_PIERCING_KICK && Random::between(1, 100) <= 50)) {
roll = ROLL_CRITICAL_SUCCESS; roll = Random::Roll::CRITICAL_SUCCESS;
} }
} }
} }
@ -3682,12 +3682,12 @@ int attackCompute(Attack* attack)
if (attackType == ATTACK_TYPE_RANGED) { if (attackType == ATTACK_TYPE_RANGED) {
attack->ammoQuantity = v26; attack->ammoQuantity = v26;
if (roll == ROLL_SUCCESS && attack->attacker == gDude) { if (roll == Random::Roll::SUCCESS && attack->attacker == gDude) {
if (perkGetRank(gDude, PERK_SNIPER) != 0) { if (perkGetRank(gDude, PERK_SNIPER) != 0) {
int d10 = randomBetween(1, 10); int d10 = Random::between(1, 10);
int luck = critterGetStat(gDude, STAT_LUCK); int luck = critterGetStat(gDude, STAT_LUCK);
if (d10 <= luck) { if (d10 <= luck) {
roll = ROLL_CRITICAL_SUCCESS; roll = Random::Roll::CRITICAL_SUCCESS;
} }
} }
} }
@ -3702,20 +3702,20 @@ int attackCompute(Attack* attack)
} }
switch (roll) { switch (roll) {
case ROLL_CRITICAL_SUCCESS: case Random::Roll::CRITICAL_SUCCESS:
damageMultiplier = attackComputeCriticalHit(attack); damageMultiplier = attackComputeCriticalHit(attack);
// FALLTHROUGH // FALLTHROUGH
case ROLL_SUCCESS: case Random::Roll::SUCCESS:
attack->attackerFlags |= DAM_HIT; attack->attackerFlags |= DAM_HIT;
attackComputeEnhancedKnockout(attack); attackComputeEnhancedKnockout(attack);
attackComputeDamage(attack, ammoQuantity, damageMultiplier); attackComputeDamage(attack, ammoQuantity, damageMultiplier);
break; break;
case ROLL_FAILURE: case Random::Roll::FAILURE:
if (attackType == ATTACK_TYPE_RANGED || attackType == ATTACK_TYPE_THROW) { if (attackType == ATTACK_TYPE_RANGED || attackType == ATTACK_TYPE_THROW) {
_check_ranged_miss(attack); _check_ranged_miss(attack);
} }
break; break;
case ROLL_CRITICAL_FAILURE: case Random::Roll::CRITICAL_FAILURE:
attackComputeCriticalFailure(attack); attackComputeCriticalFailure(attack);
break; break;
} }
@ -3724,12 +3724,12 @@ int attackCompute(Attack* attack)
if ((attack->attackerFlags & (DAM_HIT | DAM_CRITICAL)) == 0) { if ((attack->attackerFlags & (DAM_HIT | DAM_CRITICAL)) == 0) {
int tile; int tile;
if (isGrenade) { if (isGrenade) {
int throwDistance = randomBetween(1, distance / 2); int throwDistance = Random::between(1, distance / 2);
if (throwDistance == 0) { if (throwDistance == 0) {
throwDistance = 1; throwDistance = 1;
} }
int rotation = randomBetween(0, 5); int rotation = Random::between(0, 5);
tile = tileGetTileInDirection(attack->defender->tile, rotation, throwDistance); tile = tileGetTileInDirection(attack->defender->tile, rotation, throwDistance);
} else { } else {
tile = _tile_num_beyond(attack->attacker->tile, attack->defender->tile, range); tile = _tile_num_beyond(attack->attacker->tile, attack->defender->tile, range);
@ -3880,7 +3880,7 @@ int attackComputeCriticalHit(Attack* attack)
attack->attackerFlags |= DAM_CRITICAL; attack->attackerFlags |= DAM_CRITICAL;
int chance = randomBetween(1, 100); int chance = Random::between(1, 100);
chance += critterGetStat(attack->attacker, STAT_BETTER_CRITICALS); chance += critterGetStat(attack->attacker, STAT_BETTER_CRITICALS);
@ -3913,7 +3913,7 @@ int attackComputeCriticalHit(Attack* attack)
attack->criticalMessageId = criticalHitDescription->messageId; attack->criticalMessageId = criticalHitDescription->messageId;
if (criticalHitDescription->massiveCriticalStat != -1) { if (criticalHitDescription->massiveCriticalStat != -1) {
if (statRoll(defender, criticalHitDescription->massiveCriticalStat, criticalHitDescription->massiveCriticalStatModifier, NULL) <= ROLL_FAILURE) { if (statRoll(defender, criticalHitDescription->massiveCriticalStat, criticalHitDescription->massiveCriticalStatModifier, NULL) <= Random::Roll::FAILURE) {
attack->defenderFlags |= criticalHitDescription->massiveCriticalFlags; attack->defenderFlags |= criticalHitDescription->massiveCriticalFlags;
attack->criticalMessageId = criticalHitDescription->massiveCriticalMessageId; attack->criticalMessageId = criticalHitDescription->massiveCriticalMessageId;
} }
@ -3922,7 +3922,7 @@ int attackComputeCriticalHit(Attack* attack)
if ((attack->defenderFlags & DAM_CRIP_RANDOM) != 0) { if ((attack->defenderFlags & DAM_CRIP_RANDOM) != 0) {
attack->defenderFlags &= ~DAM_CRIP_RANDOM; attack->defenderFlags &= ~DAM_CRIP_RANDOM;
switch (randomBetween(0, 3)) { switch (Random::between(0, 3)) {
case 0: case 0:
attack->defenderFlags |= DAM_CRIP_LEG_LEFT; attack->defenderFlags |= DAM_CRIP_LEG_LEFT;
break; break;
@ -3991,7 +3991,7 @@ int attackComputeCriticalFailure(Attack* attack)
criticalFailureTableIndex = 0; criticalFailureTableIndex = 0;
} }
int chance = randomBetween(1, 100) - 5 * (critterGetStat(attack->attacker, STAT_LUCK) - 5); int chance = Random::between(1, 100) - 5 * (critterGetStat(attack->attacker, STAT_LUCK) - 5);
int effect; int effect;
if (chance <= 20) if (chance <= 20)
@ -4038,7 +4038,7 @@ int attackComputeCriticalFailure(Attack* attack)
if ((attack->attackerFlags & DAM_CRIP_RANDOM) != 0) { if ((attack->attackerFlags & DAM_CRIP_RANDOM) != 0) {
attack->attackerFlags &= ~DAM_CRIP_RANDOM; attack->attackerFlags &= ~DAM_CRIP_RANDOM;
switch (randomBetween(0, 3)) { switch (Random::between(0, 3)) {
case 0: case 0:
attack->attackerFlags |= DAM_CRIP_LEG_LEFT; attack->attackerFlags |= DAM_CRIP_LEG_LEFT;
break; break;
@ -4412,7 +4412,7 @@ void attackComputeDamage(Attack* attack, int ammoQuantity, int a3)
bool hasStonewall = false; bool hasStonewall = false;
if (critter == gDude) { if (critter == gDude) {
if (perkGetRank(critter, PERK_STONEWALL) != 0) { if (perkGetRank(critter, PERK_STONEWALL) != 0) {
int chance = randomBetween(0, 100); int chance = Random::between(0, 100);
hasStonewall = true; hasStonewall = true;
if (chance < 50) { if (chance < 50) {
shouldKnockback = false; shouldKnockback = false;

View File

@ -911,7 +911,7 @@ int _ai_check_drugs(Object* critter)
} }
} }
if (!v28 && v26 > 0 && randomBetween(0, 100) < v26) { if (!v28 && v26 > 0 && Random::between(0, 100) < v26) {
while (critter->data.critter.combat.ap >= 2) { while (critter->data.critter.combat.ap >= 2) {
Object* drug = _inven_find_type(critter, ITEM_TYPE_DRUG, &token); Object* drug = _inven_find_type(critter, ITEM_TYPE_DRUG, &token);
if (drug == NULL) { if (drug == NULL) {
@ -1587,7 +1587,7 @@ Object* _ai_best_weapon(Object* attacker, Object* weapon1, Object* weapon2, Obje
AiPacket* ai = aiGetPacket(attacker); AiPacket* ai = aiGetPacket(attacker);
if (ai->best_weapon == BEST_WEAPON_RANDOM) { if (ai->best_weapon == BEST_WEAPON_RANDOM) {
return randomBetween(1, 100) <= 50 ? weapon1 : weapon2; return Random::between(1, 100) <= 50 ? weapon1 : weapon2;
} }
int minDamage; int minDamage;
int maxDamage; int maxDamage;
@ -2024,7 +2024,7 @@ int _ai_pick_hit_mode(Object* a1, Object* a2, Object* a3)
useSecondaryMode = true; useSecondaryMode = true;
break; break;
case AREA_ATTACK_MODE_SOMETIMES: case AREA_ATTACK_MODE_SOMETIMES:
if (randomBetween(1, ai->secondary_freq) == 1) { if (Random::between(1, ai->secondary_freq) == 1) {
useSecondaryMode = true; useSecondaryMode = true;
} }
break; break;
@ -2049,7 +2049,7 @@ int _ai_pick_hit_mode(Object* a1, Object* a2, Object* a3)
} }
} else { } else {
if (intelligence < 6 || objectGetDistanceBetween(a1, a3) < 10) { if (intelligence < 6 || objectGetDistanceBetween(a1, a3) < 10) {
if (randomBetween(1, ai->secondary_freq) == 1) { if (Random::between(1, ai->secondary_freq) == 1) {
useSecondaryMode = true; useSecondaryMode = true;
} }
} }
@ -2357,7 +2357,7 @@ int _ai_called_shot(Object* a1, Object* a2, int a3)
if (_item_w_mp_cost(a1, a3, 1) <= a1->data.critter.combat.ap) { if (_item_w_mp_cost(a1, a3, 1) <= a1->data.critter.combat.ap) {
if (_item_w_called_shot(a1, a3)) { if (_item_w_called_shot(a1, a3)) {
ai = aiGetPacket(a1); ai = aiGetPacket(a1);
if (randomBetween(1, ai->called_freq) == 1) { if (Random::between(1, ai->called_freq) == 1) {
combat_difficulty = 1; combat_difficulty = 1;
configGetInt(&gGameConfig, GAME_CONFIG_PREFERENCES_KEY, GAME_CONFIG_COMBAT_DIFFICULTY_KEY, &combat_difficulty); configGetInt(&gGameConfig, GAME_CONFIG_PREFERENCES_KEY, GAME_CONFIG_COMBAT_DIFFICULTY_KEY, &combat_difficulty);
if (combat_difficulty) { if (combat_difficulty) {
@ -2371,7 +2371,7 @@ int _ai_called_shot(Object* a1, Object* a2, int a3)
} }
if (critterGetStat(a1, STAT_INTELLIGENCE) >= v6) { if (critterGetStat(a1, STAT_INTELLIGENCE) >= v6) {
v5 = randomBetween(0, 8); v5 = Random::between(0, 8);
v7 = _determine_to_hit(a1, a2, a3, v5); v7 = _determine_to_hit(a1, a2, a3, v5);
if (v7 < ai->min_to_hit) { if (v7 < ai->min_to_hit) {
v5 = 3; v5 = 3;
@ -3012,7 +3012,7 @@ int _combatai_msg(Object* a1, Attack* attack, int type, int delay)
debugPrint("%s is using %s packet with a %d%% chance to taunt\n", objectGetName(a1), ai->name, ai->chance); debugPrint("%s is using %s packet with a %d%% chance to taunt\n", objectGetName(a1), ai->name, ai->chance);
if (randomBetween(1, 100) > ai->chance) { if (Random::between(1, 100) > ai->chance) {
return -1; return -1;
} }
@ -3055,7 +3055,7 @@ int _combatai_msg(Object* a1, Attack* attack, int type, int delay)
} }
MessageListItem messageListItem; MessageListItem messageListItem;
messageListItem.num = randomBetween(start, end); messageListItem.num = Random::between(start, end);
if (!messageListGetItem(&gCombatAiMessageList, &messageListItem)) { if (!messageListGetItem(&gCombatAiMessageList, &messageListItem)) {
debugPrint("\nERROR: combatai_msg: Couldn't find message # %d for %s", messageListItem.num, critterGetName(a1)); debugPrint("\nERROR: combatai_msg: Couldn't find message # %d for %s", messageListItem.num, critterGetName(a1));
return -1; return -1;
@ -3110,7 +3110,7 @@ Object* _combat_ai_random_target(Attack* attack)
if (_curr_crit_num != 0) { if (_curr_crit_num != 0) {
// Randomize starting critter. // Randomize starting critter.
int start = randomBetween(0, _curr_crit_num - 1); int start = Random::between(0, _curr_crit_num - 1);
int index = start; int index = start;
while (true) { while (true) {
Object* obj = _curr_crit_list[index]; Object* obj = _curr_crit_list[index];

View File

@ -466,7 +466,7 @@ int _critter_check_rads(Object* obj)
else else
radiationLevel = RADIATION_LEVEL_NONE; radiationLevel = RADIATION_LEVEL_NONE;
if (statRoll(obj, STAT_ENDURANCE, gRadiationEnduranceModifiers[radiationLevel], NULL) <= ROLL_FAILURE) { if (statRoll(obj, STAT_ENDURANCE, gRadiationEnduranceModifiers[radiationLevel], NULL) <= Random::Roll::FAILURE) {
radiationLevel++; radiationLevel++;
} }
@ -479,7 +479,7 @@ int _critter_check_rads(Object* obj)
radiationEvent->radiationLevel = radiationLevel; radiationEvent->radiationLevel = radiationLevel;
radiationEvent->isHealing = 0; radiationEvent->isHealing = 0;
queueAddEvent(36000 * randomBetween(4, 18), obj, radiationEvent, EVENT_TYPE_RADIATION); queueAddEvent(36000 * Random::between(4, 18), obj, radiationEvent, EVENT_TYPE_RADIATION);
} }
proto->critter.data.flags &= ~(0x02); proto->critter.data.flags &= ~(0x02);
@ -1126,7 +1126,7 @@ int sneakEventProcess(Object* obj, void* data)
int time; int time;
int sneak = skillGetValue(gDude, SKILL_SNEAK); int sneak = skillGetValue(gDude, SKILL_SNEAK);
if (skillRoll(gDude, SKILL_SNEAK, 0, NULL) < ROLL_SUCCESS) { if (skillRoll(gDude, SKILL_SNEAK, 0, NULL) < Random::Roll::SUCCESS) {
time = 600; time = 600;
_sneak_working = false; _sneak_working = false;

View File

@ -1067,7 +1067,7 @@ void endgameSetupDeathEnding(int reason)
} }
if (!specialEndingSelected) { if (!specialEndingSelected) {
int chance = randomBetween(0, percentage); int chance = Random::between(0, percentage);
int accum = 0; int accum = 0;
for (int index = 0; index < gEndgameDeathEndingsLength; index++) { for (int index = 0; index < gEndgameDeathEndingsLength; index++) {

View File

@ -157,7 +157,7 @@ int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4
tileDisable(); tileDisable();
randomInit(); Random::init();
badwordsInit(); badwordsInit();
skillsInit(); skillsInit();
statsInit(); statsInit();
@ -326,7 +326,7 @@ void gameReset()
{ {
tileDisable(); tileDisable();
paletteReset(); paletteReset();
randomReset(); Random::reset();
skillsReset(); skillsReset();
statsReset(); statsReset();
perksReset(); perksReset();
@ -390,7 +390,7 @@ void gameExit()
statsExit(); statsExit();
skillsExit(); skillsExit();
traitsExit(); traitsExit();
randomExit(); Random::exit();
badwordsExit(); badwordsExit();
automapExit(); automapExit();
paletteExit(); paletteExit();

View File

@ -2287,7 +2287,7 @@ void _gdSetupFidget(int headFrmId, int reaction)
return; return;
} }
int chance = randomBetween(1, 100) + _dialogue_seconds_since_last_input / 2; int chance = Random::between(1, 100) + _dialogue_seconds_since_last_input / 2;
int fidget = fidgetCount; int fidget = fidgetCount;
switch (fidgetCount) { switch (fidgetCount) {
@ -2632,7 +2632,7 @@ void gameDialogTicker()
if (getTicksSince(gGameDialogFidgetLastUpdateTimestamp) >= _tocksWaiting) { if (getTicksSince(gGameDialogFidgetLastUpdateTimestamp) >= _tocksWaiting) {
_can_start_new_fidget = false; _can_start_new_fidget = false;
_dialogue_seconds_since_last_input += _tocksWaiting / 1000; _dialogue_seconds_since_last_input += _tocksWaiting / 1000;
_tocksWaiting = 1000 * (randomBetween(0, 3) + 4); _tocksWaiting = 1000 * (Random::between(0, 3) + 4);
_gdSetupFidget(gGameDialogFidgetFid & 0xFFF, (gGameDialogFidgetFid & 0xFF0000) >> 16); _gdSetupFidget(gGameDialogFidgetFid & 0xFFF, (gGameDialogFidgetFid & 0xFF0000) >> 16);
} }
return; return;
@ -3415,11 +3415,11 @@ int _gdPickAIUpdateMsg(Object* critter)
for (int index = 0; index < 3; index++) { for (int index = 0; index < 3; index++) {
if (critter->pid == pids[index]) { if (critter->pid == pids[index]) {
return 677 + randomBetween(0, 1); return 677 + Random::between(0, 1);
} }
} }
return 670 + randomBetween(0, 4); return 670 + Random::between(0, 4);
} }
// 0x449330 // 0x449330

View File

@ -2076,7 +2076,7 @@ int ambientSoundEffectEventProcess(Object* a1, void* data)
return 0; return 0;
} }
int delay = 10 * randomBetween(15, 20); int delay = 10 * Random::between(15, 20);
if (ambientSoundEffectGetLength() > 0) { if (ambientSoundEffectGetLength() > 0) {
nextSoundEffectEvent->ambientSoundEffectIndex = ambientSoundEffectGetRandom(); nextSoundEffectEvent->ambientSoundEffectIndex = ambientSoundEffectGetRandom();
if (queueAddEvent(delay, NULL, nextSoundEffectEvent, EVENT_TYPE_GSOUND_SFX_EVENT) == -1) { if (queueAddEvent(delay, NULL, nextSoundEffectEvent, EVENT_TYPE_GSOUND_SFX_EVENT) == -1) {

View File

@ -469,7 +469,7 @@ void opRollVsSkill(Program* program)
int skill = data[1]; int skill = data[1];
int modifier = data[0]; int modifier = data[0];
int roll = ROLL_CRITICAL_FAILURE; int roll = Random::Roll::CRITICAL_FAILURE;
if (object != NULL) { if (object != NULL) {
if ((object->pid >> 24) == OBJ_TYPE_CRITTER) { if ((object->pid >> 24) == OBJ_TYPE_CRITTER) {
int sid = scriptGetSid(program); int sid = scriptGetSid(program);
@ -583,12 +583,12 @@ void opSuccess(Program* program)
int result = -1; int result = -1;
switch (data) { switch (data) {
case ROLL_CRITICAL_FAILURE: case Random::Roll::CRITICAL_FAILURE:
case ROLL_FAILURE: case Random::Roll::FAILURE:
result = 0; result = 0;
break; break;
case ROLL_SUCCESS: case Random::Roll::SUCCESS:
case ROLL_CRITICAL_SUCCESS: case Random::Roll::CRITICAL_SUCCESS:
result = 1; result = 1;
break; break;
} }
@ -615,12 +615,12 @@ void opCritical(Program* program)
int result = -1; int result = -1;
switch (data) { switch (data) {
case ROLL_CRITICAL_FAILURE: case Random::Roll::CRITICAL_FAILURE:
case ROLL_CRITICAL_SUCCESS: case Random::Roll::CRITICAL_SUCCESS:
result = 1; result = 1;
break; break;
case ROLL_FAILURE: case Random::Roll::FAILURE:
case ROLL_SUCCESS: case Random::Roll::SUCCESS:
result = 0; result = 0;
break; break;
} }
@ -739,7 +739,7 @@ void opRandom(Program* program)
int result; int result;
if (_vcr_status() == 2) { if (_vcr_status() == 2) {
result = randomBetween(data[1], data[0]); result = Random::between(data[1], data[0]);
} else { } else {
result = (data[0] - data[1]) / 2; result = (data[0] - data[1]) / 2;
} }

View File

@ -1025,7 +1025,7 @@ void _exit_inventory(bool shouldEnableIso)
Object* critter = v1.extras[index]; Object* critter = v1.extras[index];
if (critter != gDude if (critter != gDude
&& critter->data.critter.combat.team != gDude->data.critter.combat.team && critter->data.critter.combat.team != gDude->data.critter.combat.team
&& statRoll(critter, STAT_PERCEPTION, 0, NULL) >= ROLL_SUCCESS) { && statRoll(critter, STAT_PERCEPTION, 0, NULL) >= Random::Roll::SUCCESS) {
_critter_set_who_hit_me(critter, gDude); _critter_set_who_hit_me(critter, gDude);
if (v2 == NULL) { if (v2 == NULL) {

View File

@ -1224,7 +1224,7 @@ int weaponGetMeleeDamage(Object* critter, int hitMode)
} }
} }
return randomBetween(unarmedDamage + minDamage, unarmedDamage + meleeDamage + maxDamage); return Random::between(unarmedDamage + minDamage, unarmedDamage + meleeDamage + maxDamage);
} }
// 0x478570 // 0x478570
@ -2614,7 +2614,7 @@ void _perform_drug_effect(Object* critter, int* stats, int* mods, bool isImmedia
} }
if (v32) { if (v32) {
v11 = randomBetween(mods[index - 1], mods[index]) + v10; v11 = Random::between(mods[index - 1], mods[index]) + v10;
v32 = false; v32 = false;
} else { } else {
v11 = mods[index] + v10; v11 = mods[index] + v10;
@ -2777,7 +2777,7 @@ int _item_d_take_drug(Object* critter, Object* item)
} }
} }
if (randomBetween(1, 100) <= addictionChance) { if (Random::between(1, 100) <= addictionChance) {
_insert_withdrawal(critter, 1, proto->item.data.drug.withdrawalOnset, proto->item.data.drug.withdrawalEffect, item->pid); _insert_withdrawal(critter, 1, proto->item.data.drug.withdrawalOnset, proto->item.data.drug.withdrawalEffect, item->pid);
if (critter == gDude) { if (critter == gDude) {

View File

@ -100,7 +100,7 @@ SaveGameHandler* _master_save_list[LOAD_SAVE_HANDLER_COUNT] = {
critterSave, critterSave,
killsSave, killsSave,
skillsSave, skillsSave,
randomSave, Random::save,
perksSave, perksSave,
combatSave, combatSave,
aiSave, aiSave,
@ -131,7 +131,7 @@ LoadGameHandler* _master_load_list[LOAD_SAVE_HANDLER_COUNT] = {
critterLoad, critterLoad,
killsLoad, killsLoad,
skillsLoad, skillsLoad,
randomLoad, Random::load,
perksLoad, perksLoad,
combatLoad, combatLoad,
aiLoad, aiLoad,

View File

@ -154,7 +154,7 @@ int falloutMain(int argc, char** argv)
mainMenuWindowFree(); mainMenuWindowFree();
if (characterSelectorOpen() == 2) { if (characterSelectorOpen() == 2) {
gameMoviePlay(MOVIE_ELDER, GAME_MOVIE_STOP_MUSIC); gameMoviePlay(MOVIE_ELDER, GAME_MOVIE_STOP_MUSIC);
randomSeedPrerandom(-1); Random::seedPrerandom(-1);
_main_load_new(_mainMap); _main_load_new(_mainMap);
mainLoop(fpsLimiter); mainLoop(fpsLimiter);
paletteFadeTo(gPaletteWhite); paletteFadeTo(gPaletteWhite);

View File

@ -1129,7 +1129,7 @@ int _map_age_dead_critters()
Proto* proto; Proto* proto;
protoGetProto(obj->pid, &proto); protoGetProto(obj->pid, &proto);
int frame = randomBetween(0, 3); int frame = Random::between(0, 3);
if ((proto->critter.flags & 0x800)) { if ((proto->critter.flags & 0x800)) {
frame += 6; frame += 6;
} else { } else {

View File

@ -518,7 +518,7 @@ bool messageListFilterBadwords(MessageList* messageList)
} }
int replacementsCount = strlen(gBadwordsReplacements); int replacementsCount = strlen(gBadwordsReplacements);
int replacementsIndex = randomBetween(1, replacementsCount) - 1; int replacementsIndex = Random::between(1, replacementsCount) - 1;
for (int index = 0; index < messageList->entries_num; index++) { for (int index = 0; index < messageList->entries_num; index++) {
MessageListItem* item = &(messageList->entries[index]); MessageListItem* item = &(messageList->entries[index]);

View File

@ -1471,7 +1471,7 @@ int _partyMemberIncLevels()
if (v24 != 0 || ptr_519DBC->field_8 == 0) { if (v24 != 0 || ptr_519DBC->field_8 == 0) {
if (ptr_519DBC->field_8 == 0) { if (ptr_519DBC->field_8 == 0) {
if (v24 == 0 || randomBetween(0, 100) <= 100 * v24 / party_member->level_up_every) { if (v24 == 0 || Random::between(0, 100) <= 100 * v24 / party_member->level_up_every) {
ptr_519DBC->field_0++; ptr_519DBC->field_0++;
if (v24 != 0) { if (v24 != 0) {
ptr_519DBC->field_8 = 1; ptr_519DBC->field_8 = 1;

View File

@ -2039,7 +2039,7 @@ int pipboyRenderScreensaver()
break; break;
} }
double random = randomBetween(0, RAND_MAX); double random = Random::between(0, RAND_MAX);
// TODO: Figure out what this constant means. Probably somehow related // TODO: Figure out what this constant means. Probably somehow related
// to RAND_MAX. // to RAND_MAX.
@ -2054,7 +2054,7 @@ int pipboyRenderScreensaver()
if (index < PIPBOY_BOMB_COUNT) { if (index < PIPBOY_BOMB_COUNT) {
PipboyBomb* bomb = &(bombs[index]); PipboyBomb* bomb = &(bombs[index]);
int v27 = (350 - gPipboyFrmSizes[PIPBOY_FRM_BOMB].width / 4) + (406 - gPipboyFrmSizes[PIPBOY_FRM_BOMB].height / 4); int v27 = (350 - gPipboyFrmSizes[PIPBOY_FRM_BOMB].width / 4) + (406 - gPipboyFrmSizes[PIPBOY_FRM_BOMB].height / 4);
int v5 = (int)((double)randomBetween(0, RAND_MAX) / (double)RAND_MAX * (double)v27); int v5 = (int)((double)Random::between(0, RAND_MAX) / (double)RAND_MAX * (double)v27);
int v6 = gPipboyFrmSizes[PIPBOY_FRM_BOMB].height / 4; int v6 = gPipboyFrmSizes[PIPBOY_FRM_BOMB].height / 4;
if (PIPBOY_WINDOW_CONTENT_VIEW_HEIGHT - v6 >= v5) { if (PIPBOY_WINDOW_CONTENT_VIEW_HEIGHT - v6 >= v5) {
bomb->x = 602; bomb->x = 602;
@ -2065,7 +2065,7 @@ int pipboyRenderScreensaver()
} }
bomb->field_10 = 1; bomb->field_10 = 1;
bomb->field_8 = (float)((double)randomBetween(0, RAND_MAX) * (2.75 / RAND_MAX) + 0.15); bomb->field_8 = (float)((double)Random::between(0, RAND_MAX) * (2.75 / RAND_MAX) + 0.15);
bomb->field_C = 0; bomb->field_C = 0;
} }
} }

View File

@ -180,7 +180,7 @@ int _obj_look_at_func(Object* a1, Object* a2, void (*a3)(char* string))
MessageListItem messageListItem; MessageListItem messageListItem;
if ((a2->pid >> 24) == OBJ_TYPE_CRITTER && critterIsDead(a2)) { if ((a2->pid >> 24) == OBJ_TYPE_CRITTER && critterIsDead(a2)) {
messageListItem.num = 491 + randomBetween(0, 1); messageListItem.num = 491 + Random::between(0, 1);
} else { } else {
messageListItem.num = 490; messageListItem.num = 490;
} }
@ -879,18 +879,18 @@ int _obj_use_explosive(Object* explosive)
int roll; int roll;
if (perkHasRank(gDude, PERK_DEMOLITION_EXPERT)) { if (perkHasRank(gDude, PERK_DEMOLITION_EXPERT)) {
roll = ROLL_SUCCESS; roll = Random::Roll::SUCCESS;
} else { } else {
roll = skillRoll(gDude, SKILL_TRAPS, 0, NULL); roll = skillRoll(gDude, SKILL_TRAPS, 0, NULL);
} }
int eventType; int eventType;
switch (roll) { switch (roll) {
case ROLL_CRITICAL_FAILURE: case Random::Roll::CRITICAL_FAILURE:
delay = 0; delay = 0;
eventType = EVENT_TYPE_EXPLOSION_FAILURE; eventType = EVENT_TYPE_EXPLOSION_FAILURE;
break; break;
case ROLL_FAILURE: case Random::Roll::FAILURE:
eventType = EVENT_TYPE_EXPLOSION_FAILURE; eventType = EVENT_TYPE_EXPLOSION_FAILURE;
delay /= 2; delay /= 2;
break; break;
@ -1159,7 +1159,7 @@ int _protinst_default_use_item(Object* a1, Object* a2, Object* item)
// 584: As you reach down, you realize that it is already dead. // 584: As you reach down, you realize that it is already dead.
// 585: Alas, you are too late. // 585: Alas, you are too late.
// 586: That won't work on the dead. // 586: That won't work on the dead.
messageListItem.num = 583 + randomBetween(0, 3); messageListItem.num = 583 + Random::between(0, 3);
if (messageListGetItem(&gProtoMessageList, &messageListItem)) { if (messageListGetItem(&gProtoMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text); displayMonitorAddMessage(messageListItem.text);
} }
@ -1309,7 +1309,7 @@ int _protinst_use_item_on(Object* a1, Object* a2, Object* item)
return 0; return 0;
} }
if (randomBetween(1, 10) != 1) { if (Random::between(1, 10) != 1) {
return 0; return 0;
} }

View File

@ -28,56 +28,56 @@ int _iv[32];
int _idum; int _idum;
// 0x4A2FE0 // 0x4A2FE0
void randomInit() void Random::init()
{ {
unsigned int randomSeed = randomGetSeed(); unsigned int randomSeed = getSeed();
srand(randomSeed); srand(randomSeed);
int pseudorandomSeed = randomInt32(); int pseudorandomSeed = Int32();
randomSeedPrerandomInternal(pseudorandomSeed); seedPrerandomInternal(pseudorandomSeed);
randomValidatePrerandom(); validatePrerandom();
} }
// Note: Collapsed. // Note: Collapsed.
// //
// 0x4A2FFC // 0x4A2FFC
int _roll_reset_() int Random::rollReset()
{ {
return 0; return 0;
} }
// NOTE: Uncollapsed 0x4A2FFC. // NOTE: Uncollapsed 0x4A2FFC.
void randomReset() void Random::reset()
{ {
_roll_reset_(); rollReset();
} }
// NOTE: Uncollapsed 0x4A2FFC. // NOTE: Uncollapsed 0x4A2FFC.
void randomExit() void Random::exit()
{ {
_roll_reset_(); rollReset();
} }
// NOTE: Uncollapsed 0x4A2FFC. // NOTE: Uncollapsed 0x4A2FFC.
int randomSave(File* stream) int Random::save(File* stream)
{ {
return _roll_reset_(); return rollReset();
} }
// NOTE: Uncollapsed 0x4A2FFC. // NOTE: Uncollapsed 0x4A2FFC.
int randomLoad(File* stream) int Random::load(File* stream)
{ {
return _roll_reset_(); return rollReset();
} }
// Rolls d% against [difficulty]. // Rolls d% against [difficulty].
// //
// 0x4A3000 // 0x4A3000
int randomRoll(int difficulty, int criticalSuccessModifier, int* howMuchPtr) int Random::roll(int difficulty, int criticalSuccessModifier, int* howMuchPtr)
{ {
int delta = difficulty - randomBetween(1, 100); int delta = difficulty - Random::between(1, 100);
int result = randomTranslateRoll(delta, criticalSuccessModifier); int result = translateRoll(delta, criticalSuccessModifier);
if (howMuchPtr != NULL) { if (howMuchPtr != NULL) {
*howMuchPtr = delta; *howMuchPtr = delta;
@ -90,27 +90,27 @@ int randomRoll(int difficulty, int criticalSuccessModifier, int* howMuchPtr)
// criticals (starting from day 2). // criticals (starting from day 2).
// //
// 0x4A3030 // 0x4A3030
int randomTranslateRoll(int delta, int criticalSuccessModifier) int Random::translateRoll(int delta, int criticalSuccessModifier)
{ {
int gameTime = gameTimeGetTime(); int gameTime = gameTimeGetTime();
int roll; int roll;
if (delta < 0) { if (delta < 0) {
roll = ROLL_FAILURE; roll = Random::Roll::FAILURE;
if ((gameTime / GAME_TIME_TICKS_PER_DAY) >= 1) { if ((gameTime / GAME_TIME_TICKS_PER_DAY) >= 1) {
// 10% to become critical failure. // 10% to become critical failure.
if (randomBetween(1, 100) <= -delta / 10) { if (Random::between(1, 100) <= -delta / 10) {
roll = ROLL_CRITICAL_FAILURE; roll = Random::Roll::CRITICAL_FAILURE;
} }
} }
} else { } else {
roll = ROLL_SUCCESS; roll = Random::Roll::SUCCESS;
if ((gameTime / GAME_TIME_TICKS_PER_DAY) >= 1) { if ((gameTime / GAME_TIME_TICKS_PER_DAY) >= 1) {
// 10% + modifier to become critical success. // 10% + modifier to become critical success.
if (randomBetween(1, 100) <= delta / 10 + criticalSuccessModifier) { if (Random::between(1, 100) <= delta / 10 + criticalSuccessModifier) {
roll = ROLL_CRITICAL_SUCCESS; roll = Random::Roll::CRITICAL_SUCCESS;
} }
} }
} }
@ -119,7 +119,7 @@ int randomTranslateRoll(int delta, int criticalSuccessModifier)
} }
// 0x4A30C0 // 0x4A30C0
int randomBetween(int min, int max) int Random::between(int min, int max)
{ {
int result; int result;
@ -138,7 +138,7 @@ int randomBetween(int min, int max)
} }
// 0x4A30FC // 0x4A30FC
int getRandom(int max) int Random::getRandom(int max)
{ {
int v1 = 16807 * (_idum % 127773) - 2836 * (_idum / 127773); int v1 = 16807 * (_idum % 127773) - 2836 * (_idum / 127773);
@ -160,18 +160,18 @@ int getRandom(int max)
} }
// 0x4A31A0 // 0x4A31A0
void randomSeedPrerandom(int seed) void Random::seedPrerandom(int seed)
{ {
if (seed == -1) { if (seed == -1) {
// NOTE: Uninline. // NOTE: Uninline.
seed = randomInt32(); seed = Int32();
} }
randomSeedPrerandomInternal(seed); seedPrerandomInternal(seed);
} }
// 0x4A31C4 // 0x4A31C4
int randomInt32() int Random::Int32()
{ {
int high = rand() << 16; int high = rand() << 16;
int low = rand(); int low = rand();
@ -180,7 +180,7 @@ int randomInt32()
} }
// 0x4A31E0 // 0x4A31E0
void randomSeedPrerandomInternal(int seed) void Random::seedPrerandomInternal(int seed)
{ {
int num = seed; int num = seed;
if (num < 1) { if (num < 1) {
@ -206,13 +206,13 @@ void randomSeedPrerandomInternal(int seed)
// Provides seed for random number generator. // Provides seed for random number generator.
// //
// 0x4A3258 // 0x4A3258
unsigned int randomGetSeed() unsigned int Random::getSeed()
{ {
return timeGetTime(); return timeGetTime();
} }
// 0x4A3264 // 0x4A3264
void randomValidatePrerandom() void Random::validatePrerandom()
{ {
int results[25]; int results[25];
@ -221,7 +221,7 @@ void randomValidatePrerandom()
} }
for (int attempt = 0; attempt < 100000; attempt++) { for (int attempt = 0; attempt < 100000; attempt++) {
int value = randomBetween(1, 25); int value = Random::between(1, 25);
if (value - 1 < 0) { if (value - 1 < 0) {
debugPrint("I made a negative number %d\n", value - 1); debugPrint("I made a negative number %d\n", value - 1);
} }

View File

@ -3,35 +3,31 @@
#include "db.h" #include "db.h"
typedef enum Roll { class Random {
ROLL_CRITICAL_FAILURE, public:
ROLL_FAILURE, enum Roll {
ROLL_SUCCESS, CRITICAL_FAILURE,
ROLL_CRITICAL_SUCCESS, FAILURE,
} Roll; SUCCESS,
CRITICAL_SUCCESS,
};
static void init();
static void reset();
static void exit();
static int save(File* stream);
static int load(File* stream);
static int roll(int difficulty, int criticalSuccessModifier, int* howMuchPtr);
static int between(int min, int max);
static void seedPrerandom(int seed);
extern const double dbl_50D4BA; private:
extern const double dbl_50D4C2; static int rollReset();
static int translateRoll(int delta, int criticalSuccessModifier);
extern int _iy; static int getRandom(int max);
static int Int32();
extern int _iv[32]; static void seedPrerandomInternal(int seed);
extern int _idum; static unsigned int getSeed();
static void validatePrerandom();
void randomInit(); };
int _roll_reset_();
void randomReset();
void randomExit();
int randomSave(File* stream);
int randomLoad(File* stream);
int randomRoll(int difficulty, int criticalSuccessModifier, int* howMuchPtr);
int randomTranslateRoll(int delta, int criticalSuccessModifier);
int randomBetween(int min, int max);
int getRandom(int max);
void randomSeedPrerandom(int seed);
int randomInt32();
void randomSeedPrerandomInternal(int seed);
unsigned int randomGetSeed();
void randomValidatePrerandom();
#endif /* RANDOM_H */ #endif /* RANDOM_H */

View File

@ -418,7 +418,7 @@ int skillSubForce(Object* obj, int skill)
int skillRoll(Object* critter, int skill, int modifier, int* howMuch) int skillRoll(Object* critter, int skill, int modifier, int* howMuch)
{ {
if (!skillIsValid(skill)) { if (!skillIsValid(skill)) {
return ROLL_FAILURE; return Random::Roll::FAILURE;
} }
if (critter == gDude && skill != SKILL_STEAL) { if (critter == gDude && skill != SKILL_STEAL) {
@ -441,7 +441,7 @@ int skillRoll(Object* critter, int skill, int modifier, int* howMuch)
} }
int criticalChance = critterGetStat(critter, STAT_CRITICAL_CHANCE); int criticalChance = critterGetStat(critter, STAT_CRITICAL_CHANCE);
return randomRoll(skillValue + modifier, criticalChance, howMuch); return Random::roll(skillValue + modifier, criticalChance, howMuch);
} }
// 0x4AAB9C // 0x4AAB9C
@ -542,7 +542,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
// 590: You've taxed your ability with that skill. Wait a while. // 590: You've taxed your ability with that skill. Wait a while.
// 591: You're too tired. // 591: You're too tired.
// 592: The strain might kill you. // 592: The strain might kill you.
messageListItem.num = 590 + randomBetween(0, 2); messageListItem.num = 590 + Random::between(0, 2);
if (messageListGetItem(&gSkillsMessageList, &messageListItem)) { if (messageListGetItem(&gSkillsMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text); displayMonitorAddMessage(messageListItem.text);
} }
@ -554,7 +554,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
// 512: You can't heal the dead. // 512: You can't heal the dead.
// 513: Let the dead rest in peace. // 513: Let the dead rest in peace.
// 514: It's dead, get over it. // 514: It's dead, get over it.
messageListItem.num = 512 + randomBetween(0, 2); messageListItem.num = 512 + Random::between(0, 2);
if (messageListGetItem(&gSkillsMessageList, &messageListItem)) { if (messageListGetItem(&gSkillsMessageList, &messageListItem)) {
debugPrint(messageListItem.text); debugPrint(messageListItem.text);
} }
@ -567,13 +567,13 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
int roll; int roll;
if (critterGetBodyType(a2) == BODY_TYPE_ROBOTIC) { if (critterGetBodyType(a2) == BODY_TYPE_ROBOTIC) {
roll = ROLL_FAILURE; roll = Random::Roll::FAILURE;
} else { } else {
roll = skillRoll(obj, skill, criticalChance, &hpToHeal); roll = skillRoll(obj, skill, criticalChance, &hpToHeal);
} }
if (roll == ROLL_SUCCESS || roll == ROLL_CRITICAL_SUCCESS) { if (roll == Random::Roll::SUCCESS || roll == Random::Roll::CRITICAL_SUCCESS) {
hpToHeal = randomBetween(minimumHpToHeal + 1, maximumHpToHeal + 5); hpToHeal = Random::between(minimumHpToHeal + 1, maximumHpToHeal + 5);
critterAdjustHitPoints(a2, hpToHeal); critterAdjustHitPoints(a2, hpToHeal);
if (obj == gDude) { if (obj == gDude) {
@ -643,7 +643,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
// 590: You've taxed your ability with that skill. Wait a while. // 590: You've taxed your ability with that skill. Wait a while.
// 591: You're too tired. // 591: You're too tired.
// 592: The strain might kill you. // 592: The strain might kill you.
messageListItem.num = 590 + randomBetween(0, 2); messageListItem.num = 590 + Random::between(0, 2);
if (messageListGetItem(&gSkillsMessageList, &messageListItem)) { if (messageListGetItem(&gSkillsMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text); displayMonitorAddMessage(messageListItem.text);
} }
@ -655,7 +655,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
// 512: You can't heal the dead. // 512: You can't heal the dead.
// 513: Let the dead rest in peace. // 513: Let the dead rest in peace.
// 514: It's dead, get over it. // 514: It's dead, get over it.
messageListItem.num = 512 + randomBetween(0, 2); messageListItem.num = 512 + Random::between(0, 2);
if (messageListGetItem(&gSkillsMessageList, &messageListItem)) { if (messageListGetItem(&gSkillsMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text); displayMonitorAddMessage(messageListItem.text);
} }
@ -688,7 +688,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
MessageListItem prefix; MessageListItem prefix;
if (roll == ROLL_SUCCESS || roll == ROLL_CRITICAL_SUCCESS) { if (roll == Random::Roll::SUCCESS || roll == Random::Roll::CRITICAL_SUCCESS) {
a2->data.critter.combat.results &= ~flags[index]; a2->data.critter.combat.results &= ~flags[index];
a2->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING; a2->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
@ -721,14 +721,14 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
int roll; int roll;
if (critterGetBodyType(a2) == BODY_TYPE_ROBOTIC) { if (critterGetBodyType(a2) == BODY_TYPE_ROBOTIC) {
roll = ROLL_FAILURE; roll = Random::Roll::FAILURE;
} else { } else {
int skillValue = skillGetValue(obj, skill); int skillValue = skillGetValue(obj, skill);
roll = randomRoll(skillValue, criticalChance, &hpToHeal); roll = Random::roll(skillValue, criticalChance, &hpToHeal);
} }
if (roll == ROLL_SUCCESS || roll == ROLL_CRITICAL_SUCCESS) { if (roll == Random::Roll::SUCCESS || roll == Random::Roll::CRITICAL_SUCCESS) {
hpToHeal = randomBetween(minimumHpToHeal + 4, maximumHpToHeal + 10); hpToHeal = Random::between(minimumHpToHeal + 4, maximumHpToHeal + 10);
critterAdjustHitPoints(a2, hpToHeal); critterAdjustHitPoints(a2, hpToHeal);
if (obj == gDude) { if (obj == gDude) {
@ -834,7 +834,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
// 590: You've taxed your ability with that skill. Wait a while. // 590: You've taxed your ability with that skill. Wait a while.
// 591: You're too tired. // 591: You're too tired.
// 592: The strain might kill you. // 592: The strain might kill you.
messageListItem.num = 590 + randomBetween(0, 2); messageListItem.num = 590 + Random::between(0, 2);
if (messageListGetItem(&gSkillsMessageList, &messageListItem)) { if (messageListGetItem(&gSkillsMessageList, &messageListItem)) {
displayMonitorAddMessage(messageListItem.text); displayMonitorAddMessage(messageListItem.text);
} }
@ -875,7 +875,7 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
MessageListItem prefix; MessageListItem prefix;
if (roll == ROLL_SUCCESS || roll == ROLL_CRITICAL_SUCCESS) { if (roll == Random::Roll::SUCCESS || roll == Random::Roll::CRITICAL_SUCCESS) {
a2->data.critter.combat.results &= ~flags[index]; a2->data.critter.combat.results &= ~flags[index];
a2->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING; a2->data.critter.combat.maneuver &= ~CRITTER_MANUEVER_FLEEING;
@ -905,10 +905,10 @@ int skillUse(Object* obj, Object* a2, int skill, int criticalChanceModifier)
} }
int skillValue = skillGetValue(obj, skill); int skillValue = skillGetValue(obj, skill);
int roll = randomRoll(skillValue, criticalChance, &hpToHeal); int roll = Random::roll(skillValue, criticalChance, &hpToHeal);
if (roll == ROLL_SUCCESS || roll == ROLL_CRITICAL_SUCCESS) { if (roll == Random::Roll::SUCCESS || roll == Random::Roll::CRITICAL_SUCCESS) {
hpToHeal = randomBetween(minimumHpToHeal + 4, maximumHpToHeal + 10); hpToHeal = Random::between(minimumHpToHeal + 4, maximumHpToHeal + 10);
critterAdjustHitPoints(a2, hpToHeal); critterAdjustHitPoints(a2, hpToHeal);
if (obj == gDude) { if (obj == gDude) {
@ -1027,17 +1027,17 @@ int skillsPerformStealing(Object* a1, Object* a2, Object* item, bool isPlanting)
int stealRoll; int stealRoll;
if (a1 == gDude && objectIsPartyMember(a2)) { if (a1 == gDude && objectIsPartyMember(a2)) {
stealRoll = ROLL_CRITICAL_SUCCESS; stealRoll = Random::Roll::CRITICAL_SUCCESS;
} else { } else {
int criticalChance = critterGetStat(a1, STAT_CRITICAL_CHANCE); int criticalChance = critterGetStat(a1, STAT_CRITICAL_CHANCE);
stealRoll = randomRoll(stealChance, criticalChance, &howMuch); stealRoll = Random::roll(stealChance, criticalChance, &howMuch);
} }
int catchRoll; int catchRoll;
if (stealRoll == ROLL_CRITICAL_SUCCESS) { if (stealRoll == Random::Roll::CRITICAL_SUCCESS) {
catchRoll = ROLL_CRITICAL_FAILURE; catchRoll = Random::Roll::CRITICAL_FAILURE;
} else if (stealRoll == ROLL_CRITICAL_FAILURE) { } else if (stealRoll == Random::Roll::CRITICAL_FAILURE) {
catchRoll = ROLL_SUCCESS; catchRoll = Random::Roll::SUCCESS;
} else { } else {
int catchChance; int catchChance;
if ((a2->pid >> 24) == OBJ_TYPE_CRITTER) { if ((a2->pid >> 24) == OBJ_TYPE_CRITTER) {
@ -1046,13 +1046,13 @@ int skillsPerformStealing(Object* a1, Object* a2, Object* item, bool isPlanting)
catchChance = 30 - stealModifier; catchChance = 30 - stealModifier;
} }
catchRoll = randomRoll(catchChance, 0, &howMuch); catchRoll = Random::roll(catchChance, 0, &howMuch);
} }
MessageListItem messageListItem; MessageListItem messageListItem;
char text[60]; char text[60];
if (catchRoll != ROLL_SUCCESS && catchRoll != ROLL_CRITICAL_SUCCESS) { if (catchRoll != Random::Roll::SUCCESS && catchRoll != Random::Roll::CRITICAL_SUCCESS) {
// 571: You steal the %s. // 571: You steal the %s.
// 573: You plant the %s. // 573: You plant the %s.
messageListItem.num = isPlanting ? 573 : 571; messageListItem.num = isPlanting ? 573 : 571;
@ -1174,7 +1174,7 @@ char* skillsGetGenericResponse(Object* critter, bool isDude)
count = 5; count = 5;
} }
int messageId = randomBetween(0, count); int messageId = Random::between(0, count);
MessageListItem messageListItem; MessageListItem messageListItem;
char* msg = getmsg(&gSkillsMessageList, &messageListItem, baseMessageId + messageId); char* msg = getmsg(&gSkillsMessageList, &messageListItem, baseMessageId + messageId);

View File

@ -686,17 +686,17 @@ int statGetFrmId(int stat)
int statRoll(Object* critter, int stat, int modifier, int* howMuch) int statRoll(Object* critter, int stat, int modifier, int* howMuch)
{ {
int value = critterGetStat(critter, stat) + modifier; int value = critterGetStat(critter, stat) + modifier;
int chance = randomBetween(PRIMARY_STAT_MIN, PRIMARY_STAT_MAX); int chance = Random::between(PRIMARY_STAT_MIN, PRIMARY_STAT_MAX);
if (howMuch != NULL) { if (howMuch != NULL) {
*howMuch = value - chance; *howMuch = value - chance;
} }
if (chance <= value) { if (chance <= value) {
return ROLL_SUCCESS; return Random::Roll::SUCCESS;
} }
return ROLL_FAILURE; return Random::Roll::FAILURE;
} }
// 0x4AFAA8 // 0x4AFAA8

View File

@ -3203,7 +3203,7 @@ int _wmRndEncounterOccurred()
} }
} }
int chance = randomBetween(0, 100); int chance = Random::between(0, 100);
if (chance >= frequency) { if (chance >= frequency) {
return 0; return 0;
} }
@ -3277,7 +3277,7 @@ int _wmRndEncounterOccurred()
outdoorsman += tile->encounterDifficultyModifier; outdoorsman += tile->encounterDifficultyModifier;
if (randomBetween(1, 100) < outdoorsman) { if (Random::between(1, 100) < outdoorsman) {
randomEncounterIsDetected = true; randomEncounterIsDetected = true;
int xp = 100 - outdoorsman; int xp = 100 - outdoorsman;
@ -3392,7 +3392,7 @@ int _wmRndEncounterPick()
} }
int v1 = critterGetStat(gDude, STAT_LUCK) - 5; int v1 = critterGetStat(gDude, STAT_LUCK) - 5;
int v2 = randomBetween(0, totalChance) + v1; int v2 = Random::between(0, totalChance) + v1;
if (perkHasRank(gDude, PERK_EXPLORER)) { if (perkHasRank(gDude, PERK_EXPLORER)) {
v2 += 2; v2 += 2;
@ -3448,10 +3448,10 @@ int _wmRndEncounterPick()
if (encounterTableEntry->map == -1) { if (encounterTableEntry->map == -1) {
if (encounterTable->mapsLength <= 0) { if (encounterTable->mapsLength <= 0) {
Terrain* terrain = &(gTerrains[_world_subtile->terrain]); Terrain* terrain = &(gTerrains[_world_subtile->terrain]);
int randomMapIndex = randomBetween(0, terrain->mapsLength - 1); int randomMapIndex = Random::between(0, terrain->mapsLength - 1);
_EncounterMapID = terrain->maps[randomMapIndex]; _EncounterMapID = terrain->maps[randomMapIndex];
} else { } else {
int randomMapIndex = randomBetween(0, encounterTable->mapsLength - 1); int randomMapIndex = Random::between(0, encounterTable->mapsLength - 1);
_EncounterMapID = encounterTable->maps[randomMapIndex]; _EncounterMapID = encounterTable->maps[randomMapIndex];
} }
} else { } else {
@ -3500,7 +3500,7 @@ int worldmapSetupRandomEncounter()
for (int i = 0; i < encounterTableEntry->field_50; i++) { for (int i = 0; i < encounterTableEntry->field_50; i++) {
ENCOUNTER_ENTRY_ENC* v3 = &(encounterTableEntry->field_54[i]); ENCOUNTER_ENTRY_ENC* v3 = &(encounterTableEntry->field_54[i]);
int v9 = randomBetween(v3->minQuantity, v3->maxQuantity); int v9 = Random::between(v3->minQuantity, v3->maxQuantity);
switch (gameDifficulty) { switch (gameDifficulty) {
case GAME_DIFFICULTY_EASY: case GAME_DIFFICULTY_EASY:
@ -3674,7 +3674,7 @@ int worldmapSetupCritters(int type_idx, Object** critterPtr, int critterCount)
if (v10->maximumQuantity == v10->minimumQuantity) { if (v10->maximumQuantity == v10->minimumQuantity) {
quantity = v10->maximumQuantity; quantity = v10->maximumQuantity;
} else { } else {
quantity = randomBetween(v10->minimumQuantity, v10->maximumQuantity); quantity = Random::between(v10->minimumQuantity, v10->maximumQuantity);
} }
if (quantity == 0) { if (quantity == 0) {
@ -3730,7 +3730,7 @@ int _wmSetupRndNextTileNumInit(ENC_BASE_TYPE* a1)
switch (a1->position) { switch (a1->position) {
case ENCOUNTER_FORMATION_TYPE_SURROUNDING: case ENCOUNTER_FORMATION_TYPE_SURROUNDING:
_wmRndCenterTiles[0] = gDude->tile; _wmRndCenterTiles[0] = gDude->tile;
_wmRndTileDirs[0] = randomBetween(0, ROTATION_COUNT - 1); _wmRndTileDirs[0] = Random::between(0, ROTATION_COUNT - 1);
_wmRndOriginalCenterTile = _wmRndCenterTiles[0]; _wmRndOriginalCenterTile = _wmRndCenterTiles[0];
@ -3743,7 +3743,7 @@ int _wmSetupRndNextTileNumInit(ENC_BASE_TYPE* a1)
if (1) { if (1) {
MapInfo* map = &(gMaps[gMapHeader.field_34]); MapInfo* map = &(gMaps[gMapHeader.field_34]);
if (map->startPointsLength != 0) { if (map->startPointsLength != 0) {
int rspIndex = randomBetween(0, map->startPointsLength - 1); int rspIndex = Random::between(0, map->startPointsLength - 1);
MapStartPointInfo* rsp = &(map->startPoints[rspIndex]); MapStartPointInfo* rsp = &(map->startPoints[rspIndex]);
_wmRndCenterTiles[0] = rsp->tile; _wmRndCenterTiles[0] = rsp->tile;
@ -3788,7 +3788,7 @@ int _wmSetupRndNextTileNum(ENC_BASE_TYPE* a1, ENC_BASE_TYPE_38* a2, int* out_til
if (a2->distance != 0) { if (a2->distance != 0) {
distance = a2->distance; distance = a2->distance;
} else { } else {
distance = randomBetween(-2, 2); distance = Random::between(-2, 2);
distance += critterGetStat(gDude, STAT_PERCEPTION); distance += critterGetStat(gDude, STAT_PERCEPTION);
@ -3810,8 +3810,8 @@ int _wmSetupRndNextTileNum(ENC_BASE_TYPE* a1, ENC_BASE_TYPE_38* a2, int* out_til
_wmRndTileDirs[0] = 0; _wmRndTileDirs[0] = 0;
} }
int randomizedDistance = randomBetween(0, distance / 2); int randomizedDistance = Random::between(0, distance / 2);
int randomizedRotation = randomBetween(0, ROTATION_COUNT - 1); int randomizedRotation = Random::between(0, ROTATION_COUNT - 1);
tile_num = tileGetTileInDirection(origin, (randomizedRotation + _wmRndTileDirs[0]) % ROTATION_COUNT, randomizedDistance); tile_num = tileGetTileInDirection(origin, (randomizedRotation + _wmRndTileDirs[0]) % ROTATION_COUNT, randomizedDistance);
} }
break; break;
@ -3927,7 +3927,7 @@ bool _wmEvalConditional(EncounterCondition* a1, int* a2)
} }
break; break;
case ENCOUNTER_CONDITION_TYPE_RANDOM: case ENCOUNTER_CONDITION_TYPE_RANDOM:
value = randomBetween(0, 100); value = Random::between(0, 100);
if (value > ptr->param) { if (value > ptr->param) {
matches = false; matches = false;
} }
@ -6011,7 +6011,7 @@ int ambientSoundEffectGetRandom()
totalChances += sfx->chance; totalChances += sfx->chance;
} }
int chance = randomBetween(0, totalChances); int chance = Random::between(0, totalChances);
for (int index = 0; index < map->ambientSoundEffectsLength; index++) { for (int index = 0; index < map->ambientSoundEffectsLength; index++) {
MapAmbientSoundEffectInfo* sfx = &(map->ambientSoundEffects[index]); MapAmbientSoundEffectInfo* sfx = &(map->ambientSoundEffects[index]);
if (chance >= sfx->chance) { if (chance >= sfx->chance) {