1
0
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:
Ivan Savenko 2013-07-21 18:27:33 +00:00
parent 0eb496fb57
commit 491bd557ef
6 changed files with 49 additions and 27 deletions

View File

@ -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());

View File

@ -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)
{

View File

@ -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" }

View File

@ -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;

View File

@ -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

View File

@ -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;