mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
Multiple changes to RNG usage to both client and server
Server should never use RNG from CGameState directly. Instead server get's own RNG that's state is secret for client.
This commit is contained in:
parent
960d93ff5f
commit
2ba3b20928
@ -119,14 +119,14 @@ void CPrivilagedInfoCallback::getAllTiles (std::unordered_set<int3, ShashInt3> &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPrivilagedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact*> &out)
|
void CPrivilagedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact*> &out, CRandomGenerator & rand)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 3 ; j++)
|
for (int j = 0; j < 3 ; j++)
|
||||||
out.push_back(VLC->arth->artifacts[VLC->arth->pickRandomArtifact(gameState()->getRandomGenerator(), CArtifact::ART_TREASURE)]);
|
out.push_back(VLC->arth->artifacts[VLC->arth->pickRandomArtifact(rand, CArtifact::ART_TREASURE)]);
|
||||||
for (int j = 0; j < 3 ; j++)
|
for (int j = 0; j < 3 ; j++)
|
||||||
out.push_back(VLC->arth->artifacts[VLC->arth->pickRandomArtifact(gameState()->getRandomGenerator(), CArtifact::ART_MINOR)]);
|
out.push_back(VLC->arth->artifacts[VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MINOR)]);
|
||||||
|
|
||||||
out.push_back(VLC->arth->artifacts[VLC->arth->pickRandomArtifact(gameState()->getRandomGenerator(), CArtifact::ART_MAJOR)]);
|
out.push_back(VLC->arth->artifacts[VLC->arth->pickRandomArtifact(rand, CArtifact::ART_MAJOR)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPrivilagedInfoCallback::getAllowedSpells(std::vector<SpellID> &out, ui16 level)
|
void CPrivilagedInfoCallback::getAllowedSpells(std::vector<SpellID> &out, ui16 level)
|
||||||
@ -249,6 +249,11 @@ const CGCreature * IGameCallback::putNewMonster(CreatureID creID, int count, int
|
|||||||
return dynamic_cast<const CGCreature*>(m);
|
return dynamic_cast<const CGCreature*>(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CRandomGenerator & IGameCallback::getRandomGenerator()
|
||||||
|
{
|
||||||
|
return rand;
|
||||||
|
}
|
||||||
|
|
||||||
bool IGameCallback::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero)
|
bool IGameCallback::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero)
|
||||||
{
|
{
|
||||||
//only server knows
|
//only server knows
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CGameInfoCallback.h" // for CGameInfoCallback
|
#include "CGameInfoCallback.h" // for CGameInfoCallback
|
||||||
|
#include "CRandomGenerator.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IGameCallback.h, part of VCMI engine
|
* IGameCallback.h, part of VCMI engine
|
||||||
@ -32,7 +33,7 @@ public:
|
|||||||
void getFreeTiles (std::vector<int3> &tiles) const; //used for random spawns
|
void getFreeTiles (std::vector<int3> &tiles) const; //used for random spawns
|
||||||
void getTilesInRange(std::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int mode = 0, bool patrolDistance = false) const; //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only unrevealed
|
void getTilesInRange(std::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int mode = 0, bool patrolDistance = false) const; //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 - only unrevealed
|
||||||
void getAllTiles (std::unordered_set<int3, ShashInt3> &tiles, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int level=-1, int surface=0) const; //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water
|
void getAllTiles (std::unordered_set<int3, ShashInt3> &tiles, boost::optional<PlayerColor> player = boost::optional<PlayerColor>(), int level=-1, int surface=0) const; //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water
|
||||||
void pickAllowedArtsSet(std::vector<const CArtifact*> &out); //gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
|
void pickAllowedArtsSet(std::vector<const CArtifact*> &out, CRandomGenerator & rand); //gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
|
||||||
void getAllowedSpells(std::vector<SpellID> &out, ui16 level);
|
void getAllowedSpells(std::vector<SpellID> &out, ui16 level);
|
||||||
|
|
||||||
template<typename Saver>
|
template<typename Saver>
|
||||||
@ -123,6 +124,8 @@ public:
|
|||||||
|
|
||||||
//get info
|
//get info
|
||||||
virtual bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero);
|
virtual bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero);
|
||||||
|
CRandomGenerator rand;
|
||||||
|
CRandomGenerator & getRandomGenerator();
|
||||||
|
|
||||||
friend struct CPack;
|
friend struct CPack;
|
||||||
friend struct CPackForClient;
|
friend struct CPackForClient;
|
||||||
|
@ -332,7 +332,7 @@ void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= nullptr*/)
|
|||||||
dst = this;
|
dst = this;
|
||||||
|
|
||||||
int howManyStacks = 0; //how many stacks will hero receives <1 - 3>
|
int howManyStacks = 0; //how many stacks will hero receives <1 - 3>
|
||||||
int pom = cb->gameState()->getRandomGenerator().nextInt(99);
|
int pom = cb->getRandomGenerator().nextInt(99);
|
||||||
int warMachinesGiven = 0;
|
int warMachinesGiven = 0;
|
||||||
|
|
||||||
if(pom < 9)
|
if(pom < 9)
|
||||||
@ -348,7 +348,7 @@ void CGHeroInstance::initArmy(IArmyDescriptor *dst /*= nullptr*/)
|
|||||||
{
|
{
|
||||||
auto & stack = type->initialArmy[stackNo];
|
auto & stack = type->initialArmy[stackNo];
|
||||||
|
|
||||||
int count = cb->gameState()->getRandomGenerator().nextInt(stack.minAmount, stack.maxAmount);
|
int count = cb->getRandomGenerator().nextInt(stack.minAmount, stack.maxAmount);
|
||||||
|
|
||||||
if(stack.creature >= CreatureID::CATAPULT &&
|
if(stack.creature >= CreatureID::CATAPULT &&
|
||||||
stack.creature <= CreatureID::ARROW_TOWERS) //war machine
|
stack.creature <= CreatureID::ARROW_TOWERS) //war machine
|
||||||
@ -1059,7 +1059,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
|
|||||||
void CGHeroInstance::showNecromancyDialog(const CStackBasicDescriptor &raisedStack) const
|
void CGHeroInstance::showNecromancyDialog(const CStackBasicDescriptor &raisedStack) const
|
||||||
{
|
{
|
||||||
InfoWindow iw;
|
InfoWindow iw;
|
||||||
iw.soundID = soundBase::pickup01 + cb->gameState()->getRandomGenerator().nextInt(6);
|
iw.soundID = soundBase::pickup01 + cb->getRandomGenerator().nextInt(6);
|
||||||
iw.player = tempOwner;
|
iw.player = tempOwner;
|
||||||
iw.components.push_back(Component(raisedStack));
|
iw.components.push_back(Component(raisedStack));
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ void CGBlackMarket::newTurn() const
|
|||||||
|
|
||||||
SetAvailableArtifacts saa;
|
SetAvailableArtifacts saa;
|
||||||
saa.id = id.getNum();
|
saa.id = id.getNum();
|
||||||
cb->pickAllowedArtsSet(saa.arts);
|
cb->pickAllowedArtsSet(saa.arts, cb->getRandomGenerator());
|
||||||
cb->sendAndApply(&saa);
|
cb->sendAndApply(&saa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ void CGDwelling::newTurn() const
|
|||||||
|
|
||||||
if(ID == Obj::REFUGEE_CAMP) //if it's a refugee camp, we need to pick an available creature
|
if(ID == Obj::REFUGEE_CAMP) //if it's a refugee camp, we need to pick an available creature
|
||||||
{
|
{
|
||||||
cb->setObjProperty(id, ObjProperty::AVAILABLE_CREATURE, VLC->creh->pickRandomMonster(cb->gameState()->getRandomGenerator()));
|
cb->setObjProperty(id, ObjProperty::AVAILABLE_CREATURE, VLC->creh->pickRandomMonster(cb->getRandomGenerator()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool change = false;
|
bool change = false;
|
||||||
@ -641,7 +641,7 @@ void CGTownInstance::newTurn() const
|
|||||||
{
|
{
|
||||||
if (cb->getDate(Date::DAY_OF_WEEK) == 1) //reset on new week
|
if (cb->getDate(Date::DAY_OF_WEEK) == 1) //reset on new week
|
||||||
{
|
{
|
||||||
auto & rand = cb->gameState()->getRandomGenerator();
|
auto & rand = cb->getRandomGenerator();
|
||||||
|
|
||||||
//give resources for Rampart, Mystic Pond
|
//give resources for Rampart, Mystic Pond
|
||||||
if (hasBuilt(BuildingID::MYSTIC_POND, ETownType::RAMPART)
|
if (hasBuilt(BuildingID::MYSTIC_POND, ETownType::RAMPART)
|
||||||
|
@ -158,7 +158,7 @@ void CRewardableObject::onHeroVisit(const CGHeroInstance *h) const
|
|||||||
grantRewardWithMessage(rewards[0]);
|
grantRewardWithMessage(rewards[0]);
|
||||||
break;
|
break;
|
||||||
case SELECT_RANDOM: // select one randomly //TODO: use weights
|
case SELECT_RANDOM: // select one randomly //TODO: use weights
|
||||||
grantRewardWithMessage(rewards[cb->gameState()->getRandomGenerator().nextInt(rewards.size()-1)]);
|
grantRewardWithMessage(rewards[cb->getRandomGenerator().nextInt(rewards.size()-1)]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -434,7 +434,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const
|
|||||||
const auto & upgrades = getStack(slotID).type->upgrades;
|
const auto & upgrades = getStack(slotID).type->upgrades;
|
||||||
if(!upgrades.empty())
|
if(!upgrades.empty())
|
||||||
{
|
{
|
||||||
auto it = RandomGeneratorUtil::nextItem(upgrades, cb->gameState()->getRandomGenerator());
|
auto it = RandomGeneratorUtil::nextItem(upgrades, cb->getRandomGenerator());
|
||||||
cb->changeStackType(StackLocation(this, slotID), VLC->creh->creatures[*it]);
|
cb->changeStackType(StackLocation(this, slotID), VLC->creh->creatures[*it]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -987,7 +987,7 @@ ObjectInstanceID CGTeleport::getRandomExit(const CGHeroInstance * h) const
|
|||||||
{
|
{
|
||||||
auto passableExits = getPassableExits(cb->gameState(), h, getAllExits(true));
|
auto passableExits = getPassableExits(cb->gameState(), h, getAllExits(true));
|
||||||
if(passableExits.size())
|
if(passableExits.size())
|
||||||
return *RandomGeneratorUtil::nextItem(passableExits, cb->gameState()->getRandomGenerator());
|
return *RandomGeneratorUtil::nextItem(passableExits, cb->getRandomGenerator());
|
||||||
|
|
||||||
return ObjectInstanceID();
|
return ObjectInstanceID();
|
||||||
}
|
}
|
||||||
@ -1283,7 +1283,7 @@ void CGWhirlpool::teleportDialogAnswered(const CGHeroInstance *hero, ui32 answer
|
|||||||
{
|
{
|
||||||
auto obj = cb->getObj(getRandomExit(hero));
|
auto obj = cb->getObj(getRandomExit(hero));
|
||||||
std::set<int3> tiles = obj->getBlockedPos();
|
std::set<int3> tiles = obj->getBlockedPos();
|
||||||
dPos = CGHeroInstance::convertPosition(*RandomGeneratorUtil::nextItem(tiles, cb->gameState()->getRandomGenerator()), true);
|
dPos = CGHeroInstance::convertPosition(*RandomGeneratorUtil::nextItem(tiles, cb->getRandomGenerator()), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
cb->moveHero(hero->id, dPos, true);
|
cb->moveHero(hero->id, dPos, true);
|
||||||
@ -1714,7 +1714,7 @@ void CGScholar::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
))) //hero doesn't have a spellbook or already knows the spell or doesn't have Wisdom
|
))) //hero doesn't have a spellbook or already knows the spell or doesn't have Wisdom
|
||||||
{
|
{
|
||||||
type = PRIM_SKILL;
|
type = PRIM_SKILL;
|
||||||
bid = cb->gameState()->getRandomGenerator().nextInt(GameConstants::PRIMARY_SKILLS - 1);
|
bid = cb->getRandomGenerator().nextInt(GameConstants::PRIMARY_SKILLS - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoWindow iw;
|
InfoWindow iw;
|
||||||
|
@ -364,7 +364,7 @@ void CGameHandler::levelUpCommander(const CCommanderInstance * c)
|
|||||||
else if(skillAmount == 1 || hero->tempOwner == PlayerColor::NEUTRAL) //choose skill automatically
|
else if(skillAmount == 1 || hero->tempOwner == PlayerColor::NEUTRAL) //choose skill automatically
|
||||||
{
|
{
|
||||||
sendAndApply(&clu);
|
sendAndApply(&clu);
|
||||||
levelUpCommander(c, *RandomGeneratorUtil::nextItem(clu.skills, gs->getRandomGenerator()));
|
levelUpCommander(c, *RandomGeneratorUtil::nextItem(clu.skills, getRandomGenerator()));
|
||||||
}
|
}
|
||||||
else if(skillAmount > 1) //apply and ask for secondary skill
|
else if(skillAmount > 1) //apply and ask for secondary skill
|
||||||
{
|
{
|
||||||
@ -525,7 +525,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
|||||||
int maxLevel = eagleEyeLevel + 1;
|
int maxLevel = eagleEyeLevel + 1;
|
||||||
double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::EAGLE_EYE);
|
double eagleEyeChance = finishingBattle->winnerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::EAGLE_EYE);
|
||||||
for(const CSpell *sp : gs->curB->sides.at(!battleResult.data->winner).usedSpellsHistory)
|
for(const CSpell *sp : gs->curB->sides.at(!battleResult.data->winner).usedSpellsHistory)
|
||||||
if(sp->level <= maxLevel && !vstd::contains(finishingBattle->winnerHero->spells, sp->id) && gs->getRandomGenerator().nextInt(99) < eagleEyeChance)
|
if(sp->level <= maxLevel && !vstd::contains(finishingBattle->winnerHero->spells, sp->id) && getRandomGenerator().nextInt(99) < eagleEyeChance)
|
||||||
cs.spells.insert(sp->id);
|
cs.spells.insert(sp->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -789,20 +789,20 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
|
|||||||
|
|
||||||
if(!vstd::contains_if(gs->curB->sides, sideHeroBlocksLuck))
|
if(!vstd::contains_if(gs->curB->sides, sideHeroBlocksLuck))
|
||||||
{
|
{
|
||||||
if(attackerLuck > 0 && gs->getRandomGenerator().nextInt(23) < attackerLuck)
|
if(attackerLuck > 0 && getRandomGenerator().nextInt(23) < attackerLuck)
|
||||||
{
|
{
|
||||||
bat.flags |= BattleAttack::LUCKY;
|
bat.flags |= BattleAttack::LUCKY;
|
||||||
}
|
}
|
||||||
if (VLC->modh->settings.data["hardcodedFeatures"]["NEGATIVE_LUCK"].Bool()) // negative luck enabled
|
if (VLC->modh->settings.data["hardcodedFeatures"]["NEGATIVE_LUCK"].Bool()) // negative luck enabled
|
||||||
{
|
{
|
||||||
if (attackerLuck < 0 && gs->getRandomGenerator().nextInt(23) < abs(attackerLuck))
|
if (attackerLuck < 0 && getRandomGenerator().nextInt(23) < abs(attackerLuck))
|
||||||
{
|
{
|
||||||
bat.flags |= BattleAttack::UNLUCKY;
|
bat.flags |= BattleAttack::UNLUCKY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gs->getRandomGenerator().nextInt(99) < att->valOfBonuses(Bonus::DOUBLE_DAMAGE_CHANCE))
|
if(getRandomGenerator().nextInt(99) < att->valOfBonuses(Bonus::DOUBLE_DAMAGE_CHANCE))
|
||||||
{
|
{
|
||||||
bat.flags |= BattleAttack::DEATH_BLOW;
|
bat.flags |= BattleAttack::DEATH_BLOW;
|
||||||
}
|
}
|
||||||
@ -812,7 +812,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
|
|||||||
static const int artilleryLvlToChance[] = {0, 50, 75, 100};
|
static const int artilleryLvlToChance[] = {0, 50, 75, 100};
|
||||||
const CGHeroInstance * owner = gs->curB->getHero(att->owner);
|
const CGHeroInstance * owner = gs->curB->getHero(att->owner);
|
||||||
int chance = artilleryLvlToChance[owner->getSecSkillLevel(SecondarySkill::ARTILLERY)];
|
int chance = artilleryLvlToChance[owner->getSecSkillLevel(SecondarySkill::ARTILLERY)];
|
||||||
if(chance > gs->getRandomGenerator().nextInt(99))
|
if(chance > getRandomGenerator().nextInt(99))
|
||||||
{
|
{
|
||||||
bat.flags |= BattleAttack::BALLISTA_DOUBLE_DMG;
|
bat.flags |= BattleAttack::BALLISTA_DOUBLE_DMG;
|
||||||
}
|
}
|
||||||
@ -875,8 +875,8 @@ void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, cons
|
|||||||
bsa.attackerID = att->ID;
|
bsa.attackerID = att->ID;
|
||||||
bsa.stackAttacked = def->ID;
|
bsa.stackAttacked = def->ID;
|
||||||
bsa.damageAmount = gs->curB->calculateDmg(att, def, gs->curB->battleGetOwner(att), gs->curB->battleGetOwner(def),
|
bsa.damageAmount = gs->curB->calculateDmg(att, def, gs->curB->battleGetOwner(att), gs->curB->battleGetOwner(def),
|
||||||
bat.shot(), distance, bat.lucky(), bat.unlucky(), bat.deathBlow(), bat.ballistaDoubleDmg(), gs->getRandomGenerator());
|
bat.shot(), distance, bat.lucky(), bat.unlucky(), bat.deathBlow(), bat.ballistaDoubleDmg(), getRandomGenerator());
|
||||||
def->prepareAttacked(bsa, gs->getRandomGenerator()); //calculate casualties
|
def->prepareAttacked(bsa, getRandomGenerator()); //calculate casualties
|
||||||
|
|
||||||
//life drain handling
|
//life drain handling
|
||||||
if (att->hasBonusOfType(Bonus::LIFE_DRAIN) && def->isLiving())
|
if (att->hasBonusOfType(Bonus::LIFE_DRAIN) && def->isLiving())
|
||||||
@ -913,7 +913,7 @@ void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, cons
|
|||||||
bsa2.effect = 11;
|
bsa2.effect = 11;
|
||||||
|
|
||||||
bsa2.damageAmount = (std::min(def->totalHelth(), bsa.damageAmount) * def->valOfBonuses(Bonus::FIRE_SHIELD)) / 100; //TODO: scale with attack/defense
|
bsa2.damageAmount = (std::min(def->totalHelth(), bsa.damageAmount) * def->valOfBonuses(Bonus::FIRE_SHIELD)) / 100; //TODO: scale with attack/defense
|
||||||
att->prepareAttacked(bsa2, gameState()->getRandomGenerator());
|
att->prepareAttacked(bsa2, getRandomGenerator());
|
||||||
bat.bsa.push_back(bsa2);
|
bat.bsa.push_back(bsa2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1337,7 +1337,7 @@ void CGameHandler::init(StartInfo *si)
|
|||||||
logGlobal->info("Gamestate initialized!");
|
logGlobal->info("Gamestate initialized!");
|
||||||
|
|
||||||
// reset seed, so that clients can't predict any following random values
|
// reset seed, so that clients can't predict any following random values
|
||||||
gs->getRandomGenerator().resetSeed();
|
getRandomGenerator().resetSeed();
|
||||||
|
|
||||||
for(auto & elem : gs->players)
|
for(auto & elem : gs->players)
|
||||||
{
|
{
|
||||||
@ -1373,10 +1373,10 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dwelling = *RandomGeneratorUtil::nextItem(dwellings, gs->getRandomGenerator());
|
auto dwelling = *RandomGeneratorUtil::nextItem(dwellings, getRandomGenerator());
|
||||||
|
|
||||||
// for multi-creature dwellings like Golem Factory
|
// for multi-creature dwellings like Golem Factory
|
||||||
auto creatureId = RandomGeneratorUtil::nextItem(dwelling->creatures, gs->getRandomGenerator())->second[0];
|
auto creatureId = RandomGeneratorUtil::nextItem(dwelling->creatures, getRandomGenerator())->second[0];
|
||||||
|
|
||||||
if(clear)
|
if(clear)
|
||||||
{
|
{
|
||||||
@ -1436,7 +1436,7 @@ void CGameHandler::newTurn()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int monthType = gs->getRandomGenerator().nextInt(99);
|
int monthType = getRandomGenerator().nextInt(99);
|
||||||
if(newMonth) //new month
|
if(newMonth) //new month
|
||||||
{
|
{
|
||||||
if (monthType < 40) //double growth
|
if (monthType < 40) //double growth
|
||||||
@ -1444,13 +1444,13 @@ void CGameHandler::newTurn()
|
|||||||
n.specialWeek = NewTurn::DOUBLE_GROWTH;
|
n.specialWeek = NewTurn::DOUBLE_GROWTH;
|
||||||
if (VLC->modh->settings.ALL_CREATURES_GET_DOUBLE_MONTHS)
|
if (VLC->modh->settings.ALL_CREATURES_GET_DOUBLE_MONTHS)
|
||||||
{
|
{
|
||||||
std::pair<int, CreatureID> newMonster(54, VLC->creh->pickRandomMonster(gs->getRandomGenerator()));
|
std::pair<int, CreatureID> newMonster(54, VLC->creh->pickRandomMonster(getRandomGenerator()));
|
||||||
n.creatureid = newMonster.second;
|
n.creatureid = newMonster.second;
|
||||||
}
|
}
|
||||||
else if(VLC->creh->doubledCreatures.size())
|
else if(VLC->creh->doubledCreatures.size())
|
||||||
{
|
{
|
||||||
const std::vector<CreatureID> doubledCreatures (VLC->creh->doubledCreatures.begin(), VLC->creh->doubledCreatures.end());
|
const std::vector<CreatureID> doubledCreatures (VLC->creh->doubledCreatures.begin(), VLC->creh->doubledCreatures.end());
|
||||||
n.creatureid = *RandomGeneratorUtil::nextItem(doubledCreatures, gs->getRandomGenerator());
|
n.creatureid = *RandomGeneratorUtil::nextItem(doubledCreatures, getRandomGenerator());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1466,7 +1466,7 @@ void CGameHandler::newTurn()
|
|||||||
if (monthType < 25)
|
if (monthType < 25)
|
||||||
{
|
{
|
||||||
n.specialWeek = NewTurn::BONUS_GROWTH; //+5
|
n.specialWeek = NewTurn::BONUS_GROWTH; //+5
|
||||||
std::pair<int, CreatureID> newMonster(54, VLC->creh->pickRandomMonster(gs->getRandomGenerator()));
|
std::pair<int, CreatureID> newMonster(54, VLC->creh->pickRandomMonster(getRandomGenerator()));
|
||||||
//TODO do not pick neutrals
|
//TODO do not pick neutrals
|
||||||
n.creatureid = newMonster.second;
|
n.creatureid = newMonster.second;
|
||||||
}
|
}
|
||||||
@ -1515,7 +1515,7 @@ void CGameHandler::newTurn()
|
|||||||
for (int j = 0; j < GameConstants::AVAILABLE_HEROES_PER_PLAYER; j++)
|
for (int j = 0; j < GameConstants::AVAILABLE_HEROES_PER_PLAYER; j++)
|
||||||
{
|
{
|
||||||
//first hero - native if possible, second hero -> any other class
|
//first hero - native if possible, second hero -> any other class
|
||||||
if(CGHeroInstance *h = gs->hpool.pickHeroFor(j == 0, elem.first, getNativeTown(elem.first), pool, gs->getRandomGenerator(), banned))
|
if(CGHeroInstance *h = gs->hpool.pickHeroFor(j == 0, elem.first, getNativeTown(elem.first), pool, getRandomGenerator(), banned))
|
||||||
{
|
{
|
||||||
sah.hid[j] = h->subID;
|
sah.hid[j] = h->subID;
|
||||||
h->initArmy(&sah.army[j]);
|
h->initArmy(&sah.army[j]);
|
||||||
@ -1647,7 +1647,7 @@ void CGameHandler::newTurn()
|
|||||||
{
|
{
|
||||||
SetAvailableArtifacts saa;
|
SetAvailableArtifacts saa;
|
||||||
saa.id = -1;
|
saa.id = -1;
|
||||||
pickAllowedArtsSet(saa.arts);
|
pickAllowedArtsSet(saa.arts, getRandomGenerator());
|
||||||
sendAndApply(&saa);
|
sendAndApply(&saa);
|
||||||
}
|
}
|
||||||
sendAndApply(&n);
|
sendAndApply(&n);
|
||||||
@ -1691,12 +1691,12 @@ void CGameHandler::newTurn()
|
|||||||
if (newMonth)
|
if (newMonth)
|
||||||
{
|
{
|
||||||
iw.text.addTxt(MetaString::ARRAY_TXT, (130));
|
iw.text.addTxt(MetaString::ARRAY_TXT, (130));
|
||||||
iw.text.addReplacement(MetaString::ARRAY_TXT, gs->getRandomGenerator().nextInt(32, 41));
|
iw.text.addReplacement(MetaString::ARRAY_TXT, getRandomGenerator().nextInt(32, 41));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
iw.text.addTxt(MetaString::ARRAY_TXT, (133));
|
iw.text.addTxt(MetaString::ARRAY_TXT, (133));
|
||||||
iw.text.addReplacement(MetaString::ARRAY_TXT, gs->getRandomGenerator().nextInt(43, 57));
|
iw.text.addReplacement(MetaString::ARRAY_TXT, getRandomGenerator().nextInt(43, 57));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto & elem : gs->players)
|
for (auto & elem : gs->players)
|
||||||
@ -3569,7 +3569,7 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, PlayerColor pl
|
|||||||
const CGHeroInstance *newHero = nullptr;
|
const CGHeroInstance *newHero = nullptr;
|
||||||
if (theOtherHero) //on XXL maps all heroes can be imprisoned :(
|
if (theOtherHero) //on XXL maps all heroes can be imprisoned :(
|
||||||
{
|
{
|
||||||
newHero = gs->hpool.pickHeroFor(false, player, getNativeTown(player), pool, gs->getRandomGenerator(), theOtherHero->type->heroClass);
|
newHero = gs->hpool.pickHeroFor(false, player, getNativeTown(player), pool, getRandomGenerator(), theOtherHero->type->heroClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetAvailableHeroes sah;
|
SetAvailableHeroes sah;
|
||||||
@ -3978,7 +3978,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
|||||||
{
|
{
|
||||||
if(currentHP.at(attackedPart) != EWallState::DESTROYED && // this part can be hit
|
if(currentHP.at(attackedPart) != EWallState::DESTROYED && // this part can be hit
|
||||||
currentHP.at(attackedPart) != EWallState::NONE &&
|
currentHP.at(attackedPart) != EWallState::NONE &&
|
||||||
gs->getRandomGenerator().nextInt(99) < getCatapultHitChance(attackedPart, sbi))//hit is successful
|
getRandomGenerator().nextInt(99) < getCatapultHitChance(attackedPart, sbi))//hit is successful
|
||||||
{
|
{
|
||||||
hitSuccessfull = true;
|
hitSuccessfull = true;
|
||||||
}
|
}
|
||||||
@ -3993,7 +3993,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
|||||||
}
|
}
|
||||||
if (allowedTargets.empty())
|
if (allowedTargets.empty())
|
||||||
break;
|
break;
|
||||||
attackedPart = *RandomGeneratorUtil::nextItem(allowedTargets, gs->getRandomGenerator());
|
attackedPart = *RandomGeneratorUtil::nextItem(allowedTargets, getRandomGenerator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!hitSuccessfull);
|
while (!hitSuccessfull);
|
||||||
@ -4009,7 +4009,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
|||||||
|
|
||||||
int dmgChance[] = { sbi.noDmg, sbi.oneDmg, sbi.twoDmg }; //dmgChance[i] - chance for doing i dmg when hit is successful
|
int dmgChance[] = { sbi.noDmg, sbi.oneDmg, sbi.twoDmg }; //dmgChance[i] - chance for doing i dmg when hit is successful
|
||||||
|
|
||||||
int dmgRand = gs->getRandomGenerator().nextInt(99);
|
int dmgRand = getRandomGenerator().nextInt(99);
|
||||||
//accumulating dmgChance
|
//accumulating dmgChance
|
||||||
dmgChance[1] += dmgChance[0];
|
dmgChance[1] += dmgChance[0];
|
||||||
dmgChance[2] += dmgChance[1];
|
dmgChance[2] += dmgChance[1];
|
||||||
@ -4507,7 +4507,7 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
|||||||
}
|
}
|
||||||
if (fearsomeCreature)
|
if (fearsomeCreature)
|
||||||
{
|
{
|
||||||
if (gs->getRandomGenerator().nextInt(99) < 10) //fixed 10%
|
if (getRandomGenerator().nextInt(99) < 10) //fixed 10%
|
||||||
{
|
{
|
||||||
bte.effect = Bonus::FEAR;
|
bte.effect = Bonus::FEAR;
|
||||||
sendAndApply(&bte);
|
sendAndApply(&bte);
|
||||||
@ -4521,7 +4521,7 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
|||||||
bool cast = false;
|
bool cast = false;
|
||||||
while (!bl.empty() && !cast)
|
while (!bl.empty() && !cast)
|
||||||
{
|
{
|
||||||
auto bonus = *RandomGeneratorUtil::nextItem(bl, gs->getRandomGenerator());
|
auto bonus = *RandomGeneratorUtil::nextItem(bl, getRandomGenerator());
|
||||||
auto spellID = SpellID(bonus->subtype);
|
auto spellID = SpellID(bonus->subtype);
|
||||||
const CSpell * spell = SpellID(spellID).toSpell();
|
const CSpell * spell = SpellID(spellID).toSpell();
|
||||||
bl.remove_if([&bonus](Bonus * b){return b==bonus;});
|
bl.remove_if([&bonus](Bonus * b){return b==bonus;});
|
||||||
@ -4636,7 +4636,7 @@ void CGameHandler::handleDamageFromObstacle(const CObstacleInstance &obstacle, c
|
|||||||
bsa.damageAmount = damage;
|
bsa.damageAmount = damage;
|
||||||
bsa.stackAttacked = curStack->ID;
|
bsa.stackAttacked = curStack->ID;
|
||||||
bsa.attackerID = -1;
|
bsa.attackerID = -1;
|
||||||
curStack->prepareAttacked(bsa, gameState()->getRandomGenerator());
|
curStack->prepareAttacked(bsa, getRandomGenerator());
|
||||||
|
|
||||||
StacksInjured si;
|
StacksInjured si;
|
||||||
si.stacks.push_back(bsa);
|
si.stacks.push_back(bsa);
|
||||||
@ -5233,7 +5233,7 @@ void CGameHandler::attackCasting(const BattleAttack & bat, Bonus::BonusType atta
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
//check if spell should be cast (probability handling)
|
//check if spell should be cast (probability handling)
|
||||||
if(gs->getRandomGenerator().nextInt(99) >= chance)
|
if(getRandomGenerator().nextInt(99) >= chance)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//casting
|
//casting
|
||||||
@ -5317,7 +5317,7 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
|||||||
TBonusListPtr acidBreath = attacker->getBonuses(Selector::type(Bonus::ACID_BREATH));
|
TBonusListPtr acidBreath = attacker->getBonuses(Selector::type(Bonus::ACID_BREATH));
|
||||||
for(const Bonus *b : *acidBreath)
|
for(const Bonus *b : *acidBreath)
|
||||||
{
|
{
|
||||||
if (b->additionalInfo > gs->getRandomGenerator().nextInt(99))
|
if (b->additionalInfo > getRandomGenerator().nextInt(99))
|
||||||
acidDamage += b->val;
|
acidDamage += b->val;
|
||||||
}
|
}
|
||||||
if (acidDamage)
|
if (acidDamage)
|
||||||
@ -5629,7 +5629,7 @@ void CGameHandler::runBattle()
|
|||||||
|| NBonus::hasOfType(gs->curB->battleGetFightingHero(1), Bonus::BLOCK_MORALE)) //checking if gs->curB->heroes have (or don't have) morale blocking bonuses)
|
|| NBonus::hasOfType(gs->curB->battleGetFightingHero(1), Bonus::BLOCK_MORALE)) //checking if gs->curB->heroes have (or don't have) morale blocking bonuses)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if(gs->getRandomGenerator().nextInt(23) < -2 * nextStackMorale)
|
if(getRandomGenerator().nextInt(23) < -2 * nextStackMorale)
|
||||||
{
|
{
|
||||||
//unit loses its turn - empty freeze action
|
//unit loses its turn - empty freeze action
|
||||||
BattleAction ba;
|
BattleAction ba;
|
||||||
@ -5701,7 +5701,7 @@ void CGameHandler::runBattle()
|
|||||||
{
|
{
|
||||||
BattleAction attack;
|
BattleAction attack;
|
||||||
attack.destinationTile = *RandomGeneratorUtil::nextItem(attackableBattleHexes,
|
attack.destinationTile = *RandomGeneratorUtil::nextItem(attackableBattleHexes,
|
||||||
gs->getRandomGenerator());
|
getRandomGenerator());
|
||||||
attack.actionType = Battle::CATAPULT;
|
attack.actionType = Battle::CATAPULT;
|
||||||
attack.additionalInfo = 0;
|
attack.additionalInfo = 0;
|
||||||
attack.side = !next->attackerOwned;
|
attack.side = !next->attackerOwned;
|
||||||
@ -5806,7 +5806,7 @@ void CGameHandler::runBattle()
|
|||||||
|| NBonus::hasOfType(gs->curB->battleGetFightingHero(1), Bonus::BLOCK_MORALE)) //checking if gs->curB->heroes have (or don't have) morale blocking bonuses
|
|| NBonus::hasOfType(gs->curB->battleGetFightingHero(1), Bonus::BLOCK_MORALE)) //checking if gs->curB->heroes have (or don't have) morale blocking bonuses
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if(gs->getRandomGenerator().nextInt(23) < nextStackMorale) //this stack hasn't got morale this turn
|
if(getRandomGenerator().nextInt(23) < nextStackMorale) //this stack hasn't got morale this turn
|
||||||
|
|
||||||
{
|
{
|
||||||
BattleTriggerEffect bte;
|
BattleTriggerEffect bte;
|
||||||
@ -6247,7 +6247,7 @@ void ServerSpellCastEnvironment::sendAndApply(CPackForClient * info) const
|
|||||||
|
|
||||||
CRandomGenerator & ServerSpellCastEnvironment::getRandomGenerator() const
|
CRandomGenerator & ServerSpellCastEnvironment::getRandomGenerator() const
|
||||||
{
|
{
|
||||||
return gh->gameState()->getRandomGenerator();
|
return gh->getRandomGenerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerSpellCastEnvironment::complain(const std::string& problem) const
|
void ServerSpellCastEnvironment::complain(const std::string& problem) const
|
||||||
|
@ -247,6 +247,10 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & QID & states & finishingBattle;
|
h & QID & states & finishingBattle;
|
||||||
|
if(version >= 760)
|
||||||
|
{
|
||||||
|
h & rand;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendMessageToAll(const std::string &message);
|
void sendMessageToAll(const std::string &message);
|
||||||
|
Loading…
Reference in New Issue
Block a user