mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-29 23:07:48 +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:
@@ -2180,13 +2180,26 @@ void CPlayerInterface::acceptTurn()
|
|||||||
if(howManyPeople > 1)
|
if(howManyPeople > 1)
|
||||||
adventureInt->startTurn();
|
adventureInt->startTurn();
|
||||||
|
|
||||||
//select first hero if available.
|
|
||||||
//TODO: check if hero is slept
|
|
||||||
adventureInt->heroList.update();
|
adventureInt->heroList.update();
|
||||||
adventureInt->townList.update();
|
adventureInt->townList.update();
|
||||||
|
|
||||||
if(wanderingHeroes.size())
|
const CGHeroInstance * heroToSelect = nullptr;
|
||||||
adventureInt->select(wanderingHeroes.front());
|
|
||||||
|
// 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
|
else
|
||||||
adventureInt->select(towns.front());
|
adventureInt->select(towns.front());
|
||||||
|
|
||||||
|
|||||||
@@ -165,7 +165,6 @@ void SetMovePoints::applyCl( CClient *cl )
|
|||||||
|
|
||||||
void FoWChange::applyCl( CClient *cl )
|
void FoWChange::applyCl( CClient *cl )
|
||||||
{
|
{
|
||||||
|
|
||||||
for(auto &i : cl->playerint)
|
for(auto &i : cl->playerint)
|
||||||
if(cl->getPlayerRelations(i.first, player) != PlayerRelations::ENEMIES)
|
if(cl->getPlayerRelations(i.first, player) != PlayerRelations::ENEMIES)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"index": 144,
|
"index": 144,
|
||||||
"class" : "knight",
|
"class" : "knight",
|
||||||
"female": false,
|
"female": false,
|
||||||
"special" : true,
|
"special" : false, // available in single scenario, replacement for no longer available Lord Haart
|
||||||
"skills":
|
"skills":
|
||||||
[
|
[
|
||||||
{ "skill" : "leadership", "level": "advanced" }
|
{ "skill" : "leadership", "level": "advanced" }
|
||||||
|
|||||||
@@ -1410,8 +1410,8 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
|
|||||||
{
|
{
|
||||||
const ui8 necromancyLevel = getSecSkillLevel(SecondarySkill::NECROMANCY);
|
const ui8 necromancyLevel = getSecSkillLevel(SecondarySkill::NECROMANCY);
|
||||||
|
|
||||||
// Hero knows necromancy.
|
// Hero knows necromancy or has Necromancer Cloak
|
||||||
if (necromancyLevel > 0)
|
if (necromancyLevel > 0 || hasBonusOfType(Bonus::IMPROVED_NECROMANCY))
|
||||||
{
|
{
|
||||||
double necromancySkill = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::NECROMANCY)/100.0;
|
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...
|
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.
|
// Get lost enemy hit points convertible to units.
|
||||||
CCreature * c = VLC->creh->creatures[casualtie.first];
|
CCreature * c = VLC->creh->creatures[casualtie.first];
|
||||||
if (c->isLiving())
|
|
||||||
{
|
const ui32 raisedHP = c->valOfBonuses(Bonus::STACK_HEALTH) * casualtie.second * necromancySkill;
|
||||||
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
|
||||||
raisedUnits += std::min<ui32>(raisedHP / raisedUnitHP, casualtie.second * necromancySkill); //limit to % of HP and % of original stack count
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make room for new units.
|
// Make room for new units.
|
||||||
@@ -1966,7 +1964,7 @@ int CGTownInstance::getSightRadious() const //returns sight distance
|
|||||||
{
|
{
|
||||||
if (hasBuilt(BuildingID::GRAIL)) //skyship
|
if (hasBuilt(BuildingID::GRAIL)) //skyship
|
||||||
return -1; //entire map
|
return -1; //entire map
|
||||||
else if (hasBuilt(BuildingID::LOOKOUT_TOWER)) //lookout tower
|
if (hasBuilt(BuildingID::LOOKOUT_TOWER)) //lookout tower
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
return 5;
|
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
|
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
|
int3 getSightCenter() const override; //"center" tile from which the sight distance is calculated
|
||||||
int getSightRadious() const; //returns sight distance
|
int getSightRadious() const override; //returns sight distance
|
||||||
int getBoatType() const; //0 - evil (if a ship can be evil...?), 1 - good, 2 - neutral
|
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
|
void getOutOffsets(std::vector<int3> &offsets) const; //offsets to obj pos when we boat can be placed
|
||||||
int getMarketEfficiency() const override; //=market count
|
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
|
//Fill BattleResult structure with exp info
|
||||||
giveExp(*battleResult.data);
|
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)
|
if (hero1)
|
||||||
battleResult.data->exp[0] = hero1->calculateXp(battleResult.data->exp[0]);//scholar skill
|
battleResult.data->exp[0] = hero1->calculateXp(battleResult.data->exp[0]);//scholar skill
|
||||||
if (hero2)
|
if (hero2)
|
||||||
@@ -2440,7 +2449,7 @@ bool CGameHandler::buildStructure( ObjectInstanceID tid, BuildingID requestedID,
|
|||||||
ssi.creatures[level].second.push_back(crea->idNumber);
|
ssi.creatures[level].second.push_back(crea->idNumber);
|
||||||
sendAndApply(&ssi);
|
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);
|
setPortalDwelling(t);
|
||||||
}
|
}
|
||||||
@@ -2464,8 +2473,6 @@ bool CGameHandler::buildStructure( ObjectInstanceID tid, BuildingID requestedID,
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Init the vectors
|
//Init the vectors
|
||||||
for(auto & build : t->town->buildings)
|
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
|
//Other post-built events
|
||||||
for(auto builtID : ns.bid)
|
for(auto builtID : ns.bid)
|
||||||
processBuiltStructure(builtID);
|
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
|
//We know what has been built, appluy changes. Do this as final step to properly update town window
|
||||||
sendAndApply(&ns);
|
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)
|
if(t->visitingHero)
|
||||||
vistiCastleObjects (t, t->visitingHero);
|
vistiCastleObjects (t, t->visitingHero);
|
||||||
if(t->garrisonHero)
|
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!
|
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());
|
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.pos = gs->curB->getAvaliableHex(bsa.creID, bsa.attacker, destStack->position);
|
||||||
bsa.summoned = false;
|
bsa.summoned = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user