diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 2c6b2052b..db3eb38ab 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -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()); diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 040428239..70ddaf18e 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -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) { diff --git a/config/heroes/special.json b/config/heroes/special.json index 4227c2c77..72675bc5a 100644 --- a/config/heroes/special.json +++ b/config/heroes/special.json @@ -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" } diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp index 9c41afbd1..ed62c42b4 100644 --- a/lib/CObjectHandler.cpp +++ b/lib/CObjectHandler.cpp @@ -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(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(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; diff --git a/lib/CObjectHandler.h b/lib/CObjectHandler.h index f30fe42a9..c7eca91bd 100644 --- a/lib/CObjectHandler.h +++ b/lib/CObjectHandler.h @@ -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 &offsets) const; //offsets to obj pos when we boat can be placed int getMarketEfficiency() const override; //=market count diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 967e90ad4..c8e689fc6 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -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;