diff --git a/client/CCastleInterface.cpp b/client/CCastleInterface.cpp index f97eb1c19..03b641b0d 100644 --- a/client/CCastleInterface.cpp +++ b/client/CCastleInterface.cpp @@ -1142,8 +1142,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState) int summ=0, cnt=0; std::string descr=CGI->generaltexth->allTexts[589];//Growth of creature is number boost::algorithm::replace_first(descr,"%s",CGI->creh->creatures[crid]->nameSing); - boost::algorithm::replace_first(descr,"%d", boost::lexical_cast( - ci->town->creatureGrowth(level))); + boost::algorithm::replace_first(descr,"%d", boost::lexical_cast(ci->town->creatureGrowth(level))); descr +="\n"+CGI->generaltexth->allTexts[590]; summ = CGI->creh->creatures[crid]->growth; @@ -1157,6 +1156,9 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState) else if ( bld.find(8)!=bld.end())//else if citadel+50% to basic summ+=AddToString(CGI->buildh->buildings[ci->town->subID][8]->Name()+" %+d",descr,summ/2); + summ+=AddToString(CGI->generaltexth->allTexts[63] + " %+d",descr, + summ * CGI->creh->creatures[crid]->valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100); + if(ci->town->town->hordeLvl[0]==level)//horde, x to summ if((bld.find(18)!=bld.end()) || (bld.find(19)!=bld.end())) summ+=AddToString(CGI->buildh->buildings[ci->town->subID][18]->Name()+" %+d",descr, @@ -1187,11 +1189,12 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState) }; ch = ci->town->visitingHero; }; - - //TODO player bonuses + //TODO: player bonuses if(bld.find(26)!=bld.end()) //grail - +50% to ALL growth summ+=AddToString(CGI->buildh->buildings[ci->town->subID][26]->Name()+" %+d",descr,summ/2); + + summ+=AddToString(CGI->generaltexth->allTexts[63] + " %+d",descr, CGI->creh->creatures[crid]->valOfBonuses(Bonus::CREATURE_GROWTH)); } CInfoPopup *mess = new CInfoPopup();//creating popup diff --git a/hch/CCreatureHandler.cpp b/hch/CCreatureHandler.cpp index 0ea639cdf..0ef1d93a1 100644 --- a/hch/CCreatureHandler.cpp +++ b/hch/CCreatureHandler.cpp @@ -121,6 +121,7 @@ si32 CCreature::maxAmount(const std::vector &res) const //how many creatur CCreature::CCreature() { doubleWide = false; + nodeType = CBonusSystemNode::CREATURE; } ui32 CCreature::getMinDamage() const diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index ce15f59ed..8084d58d2 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -1960,11 +1960,10 @@ int CGTownInstance::creatureGrowth(const int & level) const ret += garrisonHero->valOfBonuses(Bonus::CREATURE_GROWTH, level); if(visitingHero) ret += visitingHero->valOfBonuses(Bonus::CREATURE_GROWTH, level); - //spcecial week - ret += VLC->creh->creatures[creid]->valOfBonuses(Bonus::CREATURE_GROWTH); if(builtBuildings.find(26)!=builtBuildings.end()) //grail - +50% to ALL growth ret*=1.5; - amax(ret, 1); //even plague week gives at least one creature + //spcecial week unaffected by grail (bug in original game?) + ret += VLC->creh->creatures[creid]->valOfBonuses(Bonus::CREATURE_GROWTH); return ret;//check CCastleInterface.cpp->CCastleInterface::CCreaInfo::clickRight if this one will be modified } int CGTownInstance::dailyIncome() const diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 5d084f7d1..7de2c09c9 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -269,6 +269,9 @@ DLL_EXPORT void MetaString::toString(std::string &dst) const case TREPLACE_NUMBER: dst.replace (dst.find("%d"), 2, boost::lexical_cast(numbers[nums++])); break; + case TREPLACE_PLUSNUMBER: + dst.replace (dst.find("%+d"), 3, '+' + boost::lexical_cast(numbers[nums++])); + break; default: tlog1 << "MetaString processing error!\n"; break; diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index 015a8f5d2..fc66d1c07 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -493,7 +493,8 @@ bool CCreatureTypeLimiter::limit(const Bonus &b, const CBonusSystemNode &node) c } break; default: - return false; //don't delete it if it's other type of node + //return false; //don't delete it if it's other type of node + return true; } } CCreatureTypeLimiter::CCreatureTypeLimiter(const CCreature &Creature, ui8 IncludeUpgrades /*= true*/) diff --git a/lib/NetPacks.h b/lib/NetPacks.h index a508275e6..ea2427755 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -73,7 +73,7 @@ struct Query : public CPackForClient struct MetaString : public CPack //2001 helper for object scrips { private: - enum EMessage {TEXACT_STRING, TLOCAL_STRING, TNUMBER, TREPLACE_ESTRING, TREPLACE_LSTRING, TREPLACE_NUMBER}; + enum EMessage {TEXACT_STRING, TLOCAL_STRING, TNUMBER, TREPLACE_ESTRING, TREPLACE_LSTRING, TREPLACE_NUMBER, TREPLACE_PLUSNUMBER}; public: enum {GENERAL_TXT=1, XTRAINFO_TXT, OBJ_NAMES, RES_NAMES, ART_NAMES, ARRAY_TXT, CRE_PL_NAMES, CREGENS, MINE_NAMES, MINE_EVNTS, ADVOB_TXT, ART_EVNTS, SPELL_NAME, SEC_SKILL_NAME, CRE_SING_NAMES, CREGENS4, COLOR, ART_DESCR}; @@ -126,6 +126,11 @@ public: message.push_back(TREPLACE_NUMBER); numbers.push_back(txt); } + void addReplacement2(int txt) + { + message.push_back(TREPLACE_PLUSNUMBER); + numbers.push_back(txt); + } DLL_EXPORT void addReplacement(const CStackInstance &stack); //adds sing or plural name; DLL_EXPORT std::string buildList () const; void clear() @@ -690,7 +695,7 @@ struct SetAvailableArtifacts : public CPackForClient //519 struct NewTurn : public CPackForClient //101 { - enum weekType {NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, PLAGUE, CUSTOM, NO_ACTION, NONE}; + enum weekType {NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, DEITYOFFIRE, PLAGUE, CUSTOM, NO_ACTION, NONE}; DLL_EXPORT void applyGs(CGameState *gs); @@ -710,14 +715,14 @@ struct NewTurn : public CPackForClient //101 std::vector cres;//creatures to be placed in towns ui32 day; bool resetBuilded; - weekType specialWeek; - TQuantity creatureid; //for creature weeks + ui8 specialWeek; //weekType + TCreature creatureid; //for creature weeks NewTurn(){type = 101;}; template void serialize(Handler &h, const int version) { - h & heroes & cres & res & day & resetBuilded; + h & heroes & cres & res & day & resetBuilded & specialWeek & creatureid; } }; diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index cdc84ec9f..5dc7844f5 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -625,62 +625,74 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs ) BOOST_FOREACH(SetAvailableCreatures h, cres) //set available creatures in towns h.applyGs(gs); - if(resetBuilded) //reset amount of structures set in this turn in towns - BOOST_FOREACH(CGTownInstance* t, gs->map->towns) - t->builded = 0; - - BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes) - h->bonuses.remove_if(Bonus::OneDay); - - if(gs->getDate(1) == 1 && specialWeek != NO_ACTION) //new week, Monday that is + if (specialWeek != NO_ACTION) //first pack applied, reset all effects and aplly new { BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes) - h->bonuses.remove_if(Bonus::OneWeek); + h->bonuses.remove_if(Bonus::OneDay); - gs->globalEffects.bonuses.remove_if(Bonus::OneWeek); - - Bonus b; - b.duration = Bonus::ONE_WEEK; - b.source = Bonus::SPECIAL_WEEK; - b.effectRange = Bonus::NO_LIMIT; - switch (specialWeek) + if(resetBuilded) //reset amount of structures set in this turn in towns { - case DOUBLE_GROWTH: - b.val = 100; - b.type = Bonus::CREATURE_GROWTH_PERCENT; - b.limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[creatureid], false); - b.valType = Bonus::BASE_NUMBER; //certainly not intuitive - break; - case BONUS_GROWTH: - b.val = 5; - b.type = Bonus::CREATURE_GROWTH; - b.limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[creatureid], false); - b.valType = Bonus::BASE_NUMBER; - break; - case PLAGUE: - b.val = -50; - b.type = Bonus::CREATURE_GROWTH_PERCENT; - b.valType = Bonus::BASE_NUMBER; - break; - default: - b.val = 0; - + BOOST_FOREACH(CGTownInstance* t, gs->map->towns) + t->builded = 0; + } + if(gs->getDate(1)) //new week, Monday that is + { + for( std::map::iterator i=gs->players.begin() ; i!=gs->players.end();i++) + i->second.bonuses.remove_if(Bonus::OneWeek); + BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes) + h->bonuses.remove_if(Bonus::OneWeek); + + gs->globalEffects.bonuses.remove_if(Bonus::OneWeek); + + Bonus b; + b.duration = Bonus::ONE_WEEK; + b.source = Bonus::SPECIAL_WEEK; + b.effectRange = Bonus::NO_LIMIT; + switch (specialWeek) + { + case DOUBLE_GROWTH: + b.val = 100; + b.type = Bonus::CREATURE_GROWTH_PERCENT; + b.limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[creatureid], false); + b.valType = Bonus::BASE_NUMBER; //certainly not intuitive + break; + case BONUS_GROWTH: + b.val = 5; + b.type = Bonus::CREATURE_GROWTH; + b.limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[creatureid], false); + b.valType = Bonus::BASE_NUMBER; + break; + case DEITYOFFIRE: + b.val = 15; + b.type = Bonus::CREATURE_GROWTH; + b.limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[42], true); + b.valType = Bonus::BASE_NUMBER; + break; + case PLAGUE: + b.val = -100; //no basic creatures + b.type = Bonus::CREATURE_GROWTH_PERCENT; + b.valType = Bonus::BASE_NUMBER; + break; + default: + b.val = 0; + + } + if (b.val) + gs->globalEffects.bonuses.push_back(b); } - if (b.val) - gs->globalEffects.bonuses.push_back(b); } - - //count days without town - for( std::map::iterator i=gs->players.begin() ; i!=gs->players.end();i++) + else //second pack is applied { - if(i->second.towns.size() || gs->day == 1) - i->second.daysWithoutCastle = 0; - else - i->second.daysWithoutCastle++; + //count days without town + for( std::map::iterator i=gs->players.begin() ; i!=gs->players.end();i++) + { + if(i->second.towns.size() || gs->day == 1) + i->second.daysWithoutCastle = 0; + else + i->second.daysWithoutCastle++; - i->second.bonuses.remove_if(Bonus::OneDay); - if(gs->getDate(1) == 1) //new week - i->second.bonuses.remove_if(Bonus::OneWeek); + i->second.bonuses.remove_if(Bonus::OneDay); + } } } @@ -705,7 +717,6 @@ DLL_EXPORT void SetObjectProperty::applyGs( CGameState *gs ) gs->getPlayer(val)->towns.push_back(t); } } - obj->setProperty(what,val); } diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index b1ba9da43..eea05ff7b 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -999,6 +999,7 @@ void CGameHandler::newTurn() { tlog5 << "Turn " << gs->day+1 << std::endl; NewTurn n; + n.creatureid = -1; n.day = gs->day + 1; n.resetBuilded = true; bool newmonth = false; @@ -1013,32 +1014,14 @@ void CGameHandler::newTurn() if(getDate(4) == 28) //new month { newmonth = true; - if (monthType < 60) //double growth + if (monthType < 40) //double growth { - //spawn wandering monsters n.specialWeek = NewTurn::DOUBLE_GROWTH; - std::vector::iterator tile; - std::vector tiles; - getFreeTiles(tiles); - ui32 amount = (tiles.size()) >> 6; - std::random_shuffle(tiles.begin(), tiles.end(), p_myrandom); - //std::pair newMonster(54, VLC->creh->pickRandomMonster(boost::ref(rand))); - std::pair newMonster(54, 1); //pikeman + std::pair newMonster(54, VLC->creh->pickRandomMonster(boost::ref(rand))); n.creatureid = newMonster.second; - for (int i = 0; i < amount; ++i) - { - tile = tiles.begin(); - TerrainTile *tinfo = &gs->map->terrain[tile->x][tile->y][tile->z]; - NewObject no; - no.ID = newMonster.first; - no.subID= newMonster.second; - no.pos = *tile; - sendAndApply(&no); - tiles.erase(tile); //not use it again - } } - else if (monthType < 98) + else if (monthType < 90) n.specialWeek = NewTurn::NORMAL; else n.specialWeek = NewTurn::PLAGUE; @@ -1046,12 +1029,14 @@ void CGameHandler::newTurn() else //it's a week, but not full month { newmonth = false; - if (monthType < 20) + if (monthType < 25) { n.specialWeek = NewTurn::BONUS_GROWTH; //+5 std::pair newMonster (54, VLC->creh->pickRandomMonster(boost::ref(rand))); monsterid = newMonster.second; } + else + n.specialWeek = NewTurn::NORMAL; } } @@ -1173,7 +1158,7 @@ void CGameHandler::newTurn() { if (getDate(0) > 1) { - n.specialWeek = NewTurn::DOUBLE_GROWTH; + n.specialWeek = NewTurn::DEITYOFFIRE; //spawn familiars on new month n.creatureid = 42; //familiar } } @@ -1199,6 +1184,26 @@ void CGameHandler::newTurn() if (gs->getDate(1)==1) //first day of week, day has already been changed { + if (getDate(4) == 1 && (n.specialWeek == NewTurn::DOUBLE_GROWTH || n.specialWeek == NewTurn::DEITYOFFIRE)) + { //spawn wandering monsters + std::vector::iterator tile; + std::vector tiles; + getFreeTiles(tiles); + ui32 amount = (tiles.size()) >> 6; + std::random_shuffle(tiles.begin(), tiles.end(), p_myrandom); + for (int i = 0; i < amount; ++i) + { + tile = tiles.begin(); + TerrainTile *tinfo = &gs->map->terrain[tile->x][tile->y][tile->z]; + NewObject no; + no.ID = 54; //creature + no.subID= n.creatureid; + no.pos = *tile; + sendAndApply(&no); + tiles.erase(tile); //not use it again + } + } + NewTurn n2; //just to handle creature growths after bonuses are applied n2.specialWeek = NewTurn::NO_ACTION; n2.day = gs->day; @@ -1228,7 +1233,6 @@ void CGameHandler::newTurn() if (gs->getDate(0) > 1) { InfoWindow iw; //new week info - int msgid; switch (n.specialWeek) { case NewTurn::DOUBLE_GROWTH: @@ -1244,11 +1248,18 @@ void CGameHandler::newTurn() iw.text.addReplacement(MetaString::CRE_SING_NAMES, n.creatureid); iw.text.addReplacement(MetaString::CRE_SING_NAMES, n.creatureid); break; + case NewTurn::DEITYOFFIRE: + iw.text.addTxt(MetaString::ARRAY_TXT, 135); + iw.text.addReplacement(MetaString::CRE_SING_NAMES, 42); //%s imp + iw.text.addReplacement(MetaString::CRE_SING_NAMES, 42); //%s imp + iw.text.addReplacement2(15); //%+d 15 + iw.text.addReplacement(MetaString::CRE_SING_NAMES, 43); //%s familiar + iw.text.addReplacement2(15); //%+d 15 + break; default: iw.text.addTxt(MetaString::ARRAY_TXT, (newmonth ? 130 : 133)); iw.text.addReplacement(MetaString::ARRAY_TXT, 43 + rand()%15); } - for (std::map::iterator i=gs->players.begin() ; i!=gs->players.end(); i++) { iw.player = i->first;