mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
fixed several bugs reported on forum:
- necromancy issues - fix for lookout tower - Sir Mullich is unavailable - first hero is awakened on next turn - give 500 XP on defeating hero
This commit is contained in:
parent
0eb496fb57
commit
491bd557ef
@ -2180,13 +2180,26 @@ void CPlayerInterface::acceptTurn()
|
||||
if(howManyPeople > 1)
|
||||
adventureInt->startTurn();
|
||||
|
||||
//select first hero if available.
|
||||
//TODO: check if hero is slept
|
||||
adventureInt->heroList.update();
|
||||
adventureInt->townList.update();
|
||||
|
||||
if(wanderingHeroes.size())
|
||||
adventureInt->select(wanderingHeroes.front());
|
||||
const CGHeroInstance * heroToSelect = nullptr;
|
||||
|
||||
// find first non-sleeping hero
|
||||
for (auto hero : wanderingHeroes)
|
||||
{
|
||||
if (boost::range::find(sleepingHeroes, hero) == sleepingHeroes.end())
|
||||
{
|
||||
heroToSelect = hero;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//select first hero if available.
|
||||
if(heroToSelect != nullptr)
|
||||
{
|
||||
adventureInt->select(heroToSelect);
|
||||
}
|
||||
else
|
||||
adventureInt->select(towns.front());
|
||||
|
||||
|
@ -165,7 +165,6 @@ void SetMovePoints::applyCl( CClient *cl )
|
||||
|
||||
void FoWChange::applyCl( CClient *cl )
|
||||
{
|
||||
|
||||
for(auto &i : cl->playerint)
|
||||
if(cl->getPlayerRelations(i.first, player) != PlayerRelations::ENEMIES)
|
||||
{
|
||||
|
@ -5,7 +5,7 @@
|
||||
"index": 144,
|
||||
"class" : "knight",
|
||||
"female": false,
|
||||
"special" : true,
|
||||
"special" : false, // available in single scenario, replacement for no longer available Lord Haart
|
||||
"skills":
|
||||
[
|
||||
{ "skill" : "leadership", "level": "advanced" }
|
||||
|
@ -1410,8 +1410,8 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
|
||||
{
|
||||
const ui8 necromancyLevel = getSecSkillLevel(SecondarySkill::NECROMANCY);
|
||||
|
||||
// Hero knows necromancy.
|
||||
if (necromancyLevel > 0)
|
||||
// Hero knows necromancy or has Necromancer Cloak
|
||||
if (necromancyLevel > 0 || hasBonusOfType(Bonus::IMPROVED_NECROMANCY))
|
||||
{
|
||||
double necromancySkill = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::NECROMANCY)/100.0;
|
||||
vstd::amin(necromancySkill, 1.0); //it's impossible to raise more creatures than all...
|
||||
@ -1429,11 +1429,9 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
|
||||
{
|
||||
// Get lost enemy hit points convertible to units.
|
||||
CCreature * c = VLC->creh->creatures[casualtie.first];
|
||||
if (c->isLiving())
|
||||
{
|
||||
const ui32 raisedHP = c->valOfBonuses(Bonus::STACK_HEALTH) * casualtie.second * necromancySkill;
|
||||
raisedUnits += std::min<ui32>(raisedHP / raisedUnitHP, casualtie.second * necromancySkill); //limit to % of HP and % of original stack count
|
||||
}
|
||||
|
||||
const ui32 raisedHP = c->valOfBonuses(Bonus::STACK_HEALTH) * casualtie.second * necromancySkill;
|
||||
raisedUnits += std::min<ui32>(raisedHP / raisedUnitHP, casualtie.second * necromancySkill); //limit to % of HP and % of original stack count
|
||||
}
|
||||
|
||||
// Make room for new units.
|
||||
@ -1966,7 +1964,7 @@ int CGTownInstance::getSightRadious() const //returns sight distance
|
||||
{
|
||||
if (hasBuilt(BuildingID::GRAIL)) //skyship
|
||||
return -1; //entire map
|
||||
else if (hasBuilt(BuildingID::LOOKOUT_TOWER)) //lookout tower
|
||||
if (hasBuilt(BuildingID::LOOKOUT_TOWER)) //lookout tower
|
||||
return 20;
|
||||
}
|
||||
return 5;
|
||||
|
@ -633,8 +633,8 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ui8 getPassableness() const; //bitmap - if the bit is set the corresponding player can pass through the visitable tiles of object, even if it's blockvis; if not set - default properties from definfo are used
|
||||
int3 getSightCenter() const; //"center" tile from which the sight distance is calculated
|
||||
int getSightRadious() const; //returns sight distance
|
||||
int3 getSightCenter() const override; //"center" tile from which the sight distance is calculated
|
||||
int getSightRadious() const override; //returns sight distance
|
||||
int getBoatType() const; //0 - evil (if a ship can be evil...?), 1 - good, 2 - neutral
|
||||
void getOutOffsets(std::vector<int3> &offsets) const; //offsets to obj pos when we boat can be placed
|
||||
int getMarketEfficiency() const override; //=market count
|
||||
|
@ -414,6 +414,15 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
||||
|
||||
//Fill BattleResult structure with exp info
|
||||
giveExp(*battleResult.data);
|
||||
|
||||
if (battleResult.get()->result == BattleResult::NORMAL) // give 500 exp for defeating hero, unless he escaped
|
||||
{
|
||||
if (hero1)
|
||||
battleResult.data->exp[1] += 500;
|
||||
if (hero2)
|
||||
battleResult.data->exp[0] += 500;
|
||||
}
|
||||
|
||||
if (hero1)
|
||||
battleResult.data->exp[0] = hero1->calculateXp(battleResult.data->exp[0]);//scholar skill
|
||||
if (hero2)
|
||||
@ -2440,7 +2449,7 @@ bool CGameHandler::buildStructure( ObjectInstanceID tid, BuildingID requestedID,
|
||||
ssi.creatures[level].second.push_back(crea->idNumber);
|
||||
sendAndApply(&ssi);
|
||||
}
|
||||
else if ( t->subID == ETownType::DUNGEON && buildingID == BuildingID::PORTAL_OF_SUMMON )
|
||||
if ( t->subID == ETownType::DUNGEON && buildingID == BuildingID::PORTAL_OF_SUMMON )
|
||||
{
|
||||
setPortalDwelling(t);
|
||||
}
|
||||
@ -2464,8 +2473,6 @@ bool CGameHandler::buildStructure( ObjectInstanceID tid, BuildingID requestedID,
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//Init the vectors
|
||||
for(auto & build : t->town->buildings)
|
||||
{
|
||||
@ -2499,13 +2506,6 @@ bool CGameHandler::buildStructure( ObjectInstanceID tid, BuildingID requestedID,
|
||||
}
|
||||
}
|
||||
|
||||
//reveal ground for lookout tower
|
||||
FoWChange fw;
|
||||
fw.player = t->tempOwner;
|
||||
fw.mode = 1;
|
||||
t->getSightTiles(fw.tiles);
|
||||
sendAndApply(&fw);
|
||||
|
||||
//Other post-built events
|
||||
for(auto builtID : ns.bid)
|
||||
processBuiltStructure(builtID);
|
||||
@ -2522,6 +2522,13 @@ bool CGameHandler::buildStructure( ObjectInstanceID tid, BuildingID requestedID,
|
||||
//We know what has been built, appluy changes. Do this as final step to properly update town window
|
||||
sendAndApply(&ns);
|
||||
|
||||
// now when everything is built - reveal tiles for lookout tower
|
||||
FoWChange fw;
|
||||
fw.player = t->tempOwner;
|
||||
fw.mode = 1;
|
||||
t->getSightTiles(fw.tiles);
|
||||
sendAndApply(&fw);
|
||||
|
||||
if(t->visitingHero)
|
||||
vistiCastleObjects (t, t->visitingHero);
|
||||
if(t->garrisonHero)
|
||||
@ -3665,7 +3672,12 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
|
||||
bsa.creID = CreatureID(summoner->getBonusLocalFirst(Selector::type(Bonus::DAEMON_SUMMONING))->subtype); //in case summoner can summon more than one type of monsters... scream!
|
||||
ui64 risedHp = summoner->count * summoner->valOfBonuses(Bonus::DAEMON_SUMMONING, bsa.creID.toEnum());
|
||||
bsa.amount = std::min ((ui32)(risedHp / VLC->creh->creatures[bsa.creID]->MaxHealth()), destStack->baseAmount);
|
||||
ui64 targetHealth = destStack->getCreature()->MaxHealth() * destStack->baseAmount;
|
||||
|
||||
ui64 canRiseHp = std::min(targetHealth, risedHp);
|
||||
ui32 canRiseAmount = canRiseHp / VLC->creh->creatures[bsa.creID]->MaxHealth();
|
||||
|
||||
bsa.amount = std::min(canRiseAmount, destStack->baseAmount);
|
||||
|
||||
bsa.pos = gs->curB->getAvaliableHex(bsa.creID, bsa.attacker, destStack->position);
|
||||
bsa.summoned = false;
|
||||
|
Loading…
Reference in New Issue
Block a user