mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-25 21:38:59 +02:00
Rewritten code handling growth to eliminate duplication and make it conformant to OH3 mechanics. Proper support for Statue of Legion.
Displaying shield over minimap during AI turn.
This commit is contained in:
parent
74620dc685
commit
18444fc72f
10
ChangeLog
10
ChangeLog
@ -1,11 +1,13 @@
|
||||
0.85 -> 0.86 (Aug 01 2011)
|
||||
0.85 -> 0.86 (Sep 01 2011?)
|
||||
GENERAL:
|
||||
* Reinstated music support
|
||||
* Bonus system optimizations (caching)
|
||||
* converted many config files to JSON
|
||||
* .tga file support
|
||||
* New artifacts supported
|
||||
- Admiral's Hat
|
||||
- Statue of Legion
|
||||
- Titan's Thunder
|
||||
* vERM parser & interpreter
|
||||
* Bonus caching system
|
||||
* .tga file support
|
||||
|
||||
BATTLES:
|
||||
* Correct handling of siege obstacles
|
||||
|
@ -58,6 +58,8 @@ CAdvMapInt *adventureInt;
|
||||
|
||||
CMinimap::CMinimap(bool draw)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
used = LCLICK | RCLICK | HOVER;
|
||||
int3 mapSizes = LOCPLINT->cb->getMapSize();
|
||||
statusbarTxt = CGI->generaltexth->zelp[291].first;
|
||||
rcText = CGI->generaltexth->zelp[291].second;
|
||||
@ -67,6 +69,7 @@ CMinimap::CMinimap(bool draw)
|
||||
pos.w=ADVOPT.minimapH;
|
||||
|
||||
temps = newSurface(pos.w,pos.h);
|
||||
aiShield = new CPicture("AISHIELD.bmp");
|
||||
|
||||
const JsonNode config(DATA_DIR "/config/minimap.json");
|
||||
const JsonVector &minimap_vec = config["MinimapColors"].Vector();
|
||||
@ -114,48 +117,55 @@ CMinimap::~CMinimap()
|
||||
|
||||
void CMinimap::draw(SDL_Surface * to)
|
||||
{
|
||||
int3 mapSizes = LOCPLINT->cb->getMapSize();
|
||||
//draw terrain
|
||||
blitAt(map[adventureInt->position.z],0,0,temps);
|
||||
|
||||
//draw heroes
|
||||
std::vector <const CGHeroInstance *> hh = LOCPLINT->cb->getHeroesInfo(false);
|
||||
int mw = map[0]->w, mh = map[0]->h,
|
||||
wo = mw/mapSizes.x, ho = mh/mapSizes.y;
|
||||
|
||||
for (size_t i=0; i < hh.size(); ++i)
|
||||
if(LOCPLINT->makingTurn)
|
||||
{
|
||||
int3 hpos = hh[i]->getPosition(false);
|
||||
if(hpos.z!=adventureInt->position.z)
|
||||
continue;
|
||||
//float zawx = ((float)hpos.x/CGI->mh->sizes.x), zawy = ((float)hpos.y/CGI->mh->sizes.y);
|
||||
int3 maplgp ( (hpos.x*mw)/mapSizes.x, (hpos.y*mh)/mapSizes.y, hpos.z );
|
||||
for (int ii=0; ii<wo; ii++)
|
||||
int3 mapSizes = LOCPLINT->cb->getMapSize();
|
||||
//draw terrain
|
||||
blitAt(map[adventureInt->position.z],0,0,temps);
|
||||
|
||||
//draw heroes
|
||||
std::vector <const CGHeroInstance *> hh = LOCPLINT->cb->getHeroesInfo(false);
|
||||
int mw = map[0]->w, mh = map[0]->h,
|
||||
wo = mw/mapSizes.x, ho = mh/mapSizes.y;
|
||||
|
||||
for (size_t i=0; i < hh.size(); ++i)
|
||||
{
|
||||
for (int jj=0; jj<ho; jj++)
|
||||
int3 hpos = hh[i]->getPosition(false);
|
||||
if(hpos.z!=adventureInt->position.z)
|
||||
continue;
|
||||
//float zawx = ((float)hpos.x/CGI->mh->sizes.x), zawy = ((float)hpos.y/CGI->mh->sizes.y);
|
||||
int3 maplgp ( (hpos.x*mw)/mapSizes.x, (hpos.y*mh)/mapSizes.y, hpos.z );
|
||||
for (int ii=0; ii<wo; ii++)
|
||||
{
|
||||
SDL_PutPixelWithoutRefresh(temps,maplgp.x+ii,maplgp.y+jj,graphics->playerColors[hh[i]->getOwner()].r,
|
||||
for (int jj=0; jj<ho; jj++)
|
||||
{
|
||||
SDL_PutPixelWithoutRefresh(temps,maplgp.x+ii,maplgp.y+jj,graphics->playerColors[hh[i]->getOwner()].r,
|
||||
graphics->playerColors[hh[i]->getOwner()].g,graphics->playerColors[hh[i]->getOwner()].b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blitAt(flObjs[adventureInt->position.z],0,0,temps);
|
||||
|
||||
blitAt(FoW[adventureInt->position.z],0,0,temps);
|
||||
|
||||
//draw radar
|
||||
const int tilesw=(ADVOPT.advmapW+31)/32;
|
||||
const int tilesh=(ADVOPT.advmapH+31)/32;
|
||||
int bx = (((float)adventureInt->position.x)/(((float)mapSizes.x)))*pos.w,
|
||||
by = (((float)adventureInt->position.y)/(((float)mapSizes.y)))*pos.h,
|
||||
rx = (((float)tilesw)/(mapSizes.x))*((float)pos.w), //width
|
||||
ry = (((float)tilesh)/(mapSizes.y))*((float)pos.h); //height
|
||||
|
||||
CSDL_Ext::drawDashedBorder(temps, Rect(bx, by, rx, ry), int3(255,75,125));
|
||||
|
||||
//blitAt(radar,bx,by,temps);
|
||||
blitAt(temps,pos.x,pos.y,to);
|
||||
}
|
||||
else
|
||||
{
|
||||
aiShield->showAll(to);
|
||||
}
|
||||
|
||||
blitAt(flObjs[adventureInt->position.z],0,0,temps);
|
||||
|
||||
blitAt(FoW[adventureInt->position.z],0,0,temps);
|
||||
|
||||
//draw radar
|
||||
const int tilesw=(ADVOPT.advmapW+31)/32;
|
||||
const int tilesh=(ADVOPT.advmapH+31)/32;
|
||||
int bx = (((float)adventureInt->position.x)/(((float)mapSizes.x)))*pos.w,
|
||||
by = (((float)adventureInt->position.y)/(((float)mapSizes.y)))*pos.h,
|
||||
rx = (((float)tilesw)/(mapSizes.x))*((float)pos.w), //width
|
||||
ry = (((float)tilesh)/(mapSizes.y))*((float)pos.h); //height
|
||||
|
||||
CSDL_Ext::drawDashedBorder(temps, Rect(bx, by, rx, ry), int3(255,75,125));
|
||||
|
||||
//blitAt(radar,bx,by,temps);
|
||||
blitAt(temps,pos.x,pos.y,to);
|
||||
}
|
||||
void CMinimap::redraw(int level)// (level==-1) => redraw all levels
|
||||
{
|
||||
@ -275,13 +285,11 @@ void CMinimap::clickRight(tribool down, bool previousState)
|
||||
|
||||
void CMinimap::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if (down && (!previousState))
|
||||
activateMouseMove();
|
||||
else if (!down)
|
||||
{
|
||||
if (std::find(GH.motioninterested.begin(),GH.motioninterested.end(),this)!=GH.motioninterested.end())
|
||||
deactivateMouseMove();
|
||||
}
|
||||
if (down && !(used & MOVE))
|
||||
changeUsedEvents(MOVE, true);
|
||||
else if (!down && used & MOVE)
|
||||
changeUsedEvents(MOVE, false);
|
||||
|
||||
//ClickableL::clickLeft(down);
|
||||
if (!((bool)down))
|
||||
return;
|
||||
@ -314,20 +322,12 @@ void CMinimap::mouseMoved (const SDL_MouseMotionEvent & sEvent)
|
||||
}
|
||||
void CMinimap::activate()
|
||||
{
|
||||
activateLClick();
|
||||
activateRClick();
|
||||
activateHover();
|
||||
if (pressedL)
|
||||
activateMouseMove();
|
||||
CIntObject::activate();
|
||||
}
|
||||
|
||||
void CMinimap::deactivate()
|
||||
{
|
||||
if (pressedL)
|
||||
deactivateMouseMove();
|
||||
deactivateLClick();
|
||||
deactivateRClick();
|
||||
deactivateHover();
|
||||
CIntObject::deactivate();
|
||||
}
|
||||
|
||||
void CMinimap::showTile(const int3 &pos)
|
||||
@ -439,11 +439,6 @@ void CMinimap::hideTile(const int3 &pos)
|
||||
}
|
||||
}
|
||||
|
||||
void CMinimap::show( SDL_Surface * to )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CTerrainRect::CTerrainRect()
|
||||
:curHoveredTile(-1,-1,-1), currentPath(NULL)
|
||||
{
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
class CMinimap : public CIntObject
|
||||
{
|
||||
public:
|
||||
CPicture *aiShield; //the graphic displayed during AI turn
|
||||
SDL_Surface * temps;
|
||||
std::map<int,SDL_Color> colors;
|
||||
std::map<int,SDL_Color> colorsBlocked;
|
||||
@ -52,7 +53,6 @@ public:
|
||||
|
||||
CMinimap(bool draw=true);
|
||||
~CMinimap();
|
||||
void show(SDL_Surface * to);
|
||||
void draw(SDL_Surface * to);
|
||||
void redraw(int level=-1);// (level==-1) => redraw all levels
|
||||
void initMap(int level=-1);// (level==-1) => redraw all levels
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <boost/assign/std/vector.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "CCastleInterface.h"
|
||||
#include "../CCallback.h"
|
||||
@ -1130,76 +1131,14 @@ int CCreaInfo::AddToString(std::string from, std::string & to, int numb)
|
||||
|
||||
std::string CCreaInfo::genGrowthText()
|
||||
{
|
||||
int summ=0;
|
||||
std::string descr=CGI->generaltexth->allTexts[589];//Growth of creature is number
|
||||
boost::algorithm::replace_first(descr,"%s", creature->nameSing);
|
||||
boost::algorithm::replace_first(descr,"%d", boost::lexical_cast<std::string>(town->creatureGrowth(level)));
|
||||
GrowthInfo gi = town->getGrowthInfo(level);
|
||||
std::string descr = boost::str(boost::format(CGI->generaltexth->allTexts[589]) % creature->nameSing % gi.totalGrowth());
|
||||
|
||||
descr +="\n"+CGI->generaltexth->allTexts[590];
|
||||
summ = creature->growth;
|
||||
boost::algorithm::replace_first(descr,"%d", boost::lexical_cast<std::string>(summ));
|
||||
|
||||
if ( level>=0 && level<CREATURES_PER_TOWN)
|
||||
BOOST_FOREACH(const GrowthInfo::Entry &entry, gi.entries)
|
||||
{
|
||||
|
||||
if ( vstd::contains(town->builtBuildings, Buildings::CASTLE))
|
||||
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::CASTLE]->Name()+" %+d",descr,summ);
|
||||
else if ( vstd::contains(town->builtBuildings, Buildings::CITADEL))
|
||||
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::CITADEL]->Name()+" %+d",descr,summ/2);
|
||||
|
||||
summ+=AddToString(CGI->generaltexth->allTexts[63] + " %+d",descr, //double growth or plague
|
||||
summ * creature->valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100);
|
||||
|
||||
summ+=AddToString(CGI->generaltexth->artifNames[133] + " %+d",descr,
|
||||
summ * town->valOfGlobalBonuses
|
||||
(Selector::type(Bonus::CREATURE_GROWTH_PERCENT) && Selector::sourceType(Bonus::ARTIFACT))/100); //Statue of Legion
|
||||
|
||||
if(town->town->hordeLvl[0]==level)//horde, x to summ
|
||||
if( vstd::contains(town->builtBuildings, Buildings::HORDE_1) || vstd::contains(town->builtBuildings, Buildings::HORDE_1_UPGR))
|
||||
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::HORDE_1]->Name()+" %+d",descr,
|
||||
creature->hordeGrowth);
|
||||
|
||||
if(town->town->hordeLvl[1]==level)//horde, x to summ
|
||||
if( vstd::contains(town->builtBuildings, Buildings::HORDE_2) || vstd::contains(town->builtBuildings, Buildings::HORDE_2_UPGR))
|
||||
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::HORDE_2]->Name()+" %+d",descr,
|
||||
creature->hordeGrowth);
|
||||
|
||||
int cnt = 0;
|
||||
|
||||
std::vector< const CGDwelling * > myDwellings = LOCPLINT->cb->getMyDwellings();
|
||||
for (std::vector<const CGDwelling*>::const_iterator it = myDwellings.begin(); it != myDwellings.end(); ++it)
|
||||
if (CGI->creh->creatures[town->town->basicCreatures[level]]->idNumber == (*it)->creatures[0].second[0])
|
||||
cnt++;//external dwellings count to summ
|
||||
summ+=AddToString(CGI->generaltexth->allTexts[591],descr,cnt);
|
||||
|
||||
boost::shared_ptr<BonusList> bl;
|
||||
const CGHeroInstance *hero = town->garrisonHero;
|
||||
if (hero)
|
||||
{
|
||||
bl = hero->getAllBonuses(Selector::type(Bonus::CREATURE_GROWTH) && Selector::subtype(level)
|
||||
&& Selector::sourceType(Bonus::ARTIFACT), 0, hero);
|
||||
}
|
||||
hero = town->visitingHero;
|
||||
if (hero)
|
||||
{
|
||||
boost::shared_ptr<BonusList> blAppend = hero->getAllBonuses(Selector::type(Bonus::CREATURE_GROWTH) && Selector::subtype(level)
|
||||
&& Selector::sourceType(Bonus::ARTIFACT), 0, hero);
|
||||
if (town->garrisonHero)
|
||||
bl->insert(bl->size(), blAppend->begin(), blAppend->end());
|
||||
else
|
||||
bl = blAppend;
|
||||
}
|
||||
|
||||
if (bl->size())
|
||||
summ+=AddToString (CGI->arth->artifacts[bl->front()->sid]->Name()+" %+d", descr, bl->totalValue());
|
||||
|
||||
//TODO: player bonuses
|
||||
|
||||
if(vstd::contains(town->builtBuildings, Buildings::GRAIL)) //grail - +50% to ALL growth
|
||||
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::GRAIL]->Name()+" %+d",descr,summ/2);
|
||||
|
||||
summ+=AddToString(CGI->generaltexth->allTexts[63] + " %+d",descr, creature->valOfBonuses(Bonus::CREATURE_GROWTH));
|
||||
descr +="\n" + entry.description;
|
||||
}
|
||||
|
||||
return descr;
|
||||
}
|
||||
|
||||
|
@ -502,8 +502,22 @@ void CArtHandler::giveArtBonus( int aid, Bonus::BonusType type, int val, int sub
|
||||
Bonus *added = new Bonus(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,aid,subtype);
|
||||
added->valType = valType;
|
||||
added->limiter.reset(limiter);
|
||||
if(type == Bonus::MORALE || Bonus::LUCK)
|
||||
if(type == Bonus::MORALE || type == Bonus::LUCK)
|
||||
added->description = artifacts[aid]->Name() + (val > 0 ? " +" : " ") + boost::lexical_cast<std::string>(val);
|
||||
else
|
||||
added->description = artifacts[aid]->Name();
|
||||
artifacts[aid]->addNewBonus(added);
|
||||
}
|
||||
|
||||
void CArtHandler::giveArtBonus(int aid, Bonus::BonusType type, int val, int subtype, IPropagator* propagator /*= NULL*/)
|
||||
{
|
||||
Bonus *added = new Bonus(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,aid,subtype);
|
||||
added->valType = Bonus::BASE_NUMBER;
|
||||
added->propagator.reset(propagator);
|
||||
if(type == Bonus::MORALE || type == Bonus::LUCK)
|
||||
added->description = artifacts[aid]->Name() + (val > 0 ? " +" : " ") + boost::lexical_cast<std::string>(val);
|
||||
else
|
||||
added->description = artifacts[aid]->Name();
|
||||
artifacts[aid]->addNewBonus(added);
|
||||
}
|
||||
|
||||
@ -677,11 +691,11 @@ void CArtHandler::addBonuses()
|
||||
giveArtBonus(116,Bonus::GENERATE_RESOURCE,+750, Res::GOLD); //Endless Bag of Gold
|
||||
giveArtBonus(117,Bonus::GENERATE_RESOURCE,+500, Res::GOLD); //Endless Purse of Gold
|
||||
|
||||
giveArtBonus(118,Bonus::CREATURE_GROWTH,+5,1); //Legs of Legion
|
||||
giveArtBonus(119,Bonus::CREATURE_GROWTH,+4,2); //Loins of Legion
|
||||
giveArtBonus(120,Bonus::CREATURE_GROWTH,+3,3); //Torso of Legion
|
||||
giveArtBonus(121,Bonus::CREATURE_GROWTH,+2,4); //Arms of Legion
|
||||
giveArtBonus(122,Bonus::CREATURE_GROWTH,+1,5); //Head of Legion
|
||||
giveArtBonus(118,Bonus::CREATURE_GROWTH,+5,1, new CPropagatorNodeType(CBonusSystemNode::TOWN_AND_VISITOR)); //Legs of Legion
|
||||
giveArtBonus(119,Bonus::CREATURE_GROWTH,+4,2, new CPropagatorNodeType(CBonusSystemNode::TOWN_AND_VISITOR)); //Loins of Legion
|
||||
giveArtBonus(120,Bonus::CREATURE_GROWTH,+3,3, new CPropagatorNodeType(CBonusSystemNode::TOWN_AND_VISITOR)); //Torso of Legion
|
||||
giveArtBonus(121,Bonus::CREATURE_GROWTH,+2,4, new CPropagatorNodeType(CBonusSystemNode::TOWN_AND_VISITOR)); //Arms of Legion
|
||||
giveArtBonus(122,Bonus::CREATURE_GROWTH,+1,5, new CPropagatorNodeType(CBonusSystemNode::TOWN_AND_VISITOR)); //Head of Legion
|
||||
|
||||
//Sea Captain's Hat
|
||||
giveArtBonus(123,Bonus::WHIRLPOOL_PROTECTION,0);
|
||||
@ -722,7 +736,7 @@ void CArtHandler::addBonuses()
|
||||
giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 52); // Misfortune
|
||||
|
||||
// Statue of Legion - gives only 50% growth
|
||||
giveArtBonus(133, Bonus::CREATURE_GROWTH_PERCENT, 50, -1);
|
||||
giveArtBonus(133, Bonus::CREATURE_GROWTH_PERCENT, 50, -1, new CPropagatorNodeType(CBonusSystemNode::PLAYER));
|
||||
|
||||
//Power of the Dragon Father
|
||||
giveArtBonus(134, Bonus::LEVEL_SPELL_IMMUNITY, 4, -1, Bonus::INDEPENDENT_MAX);
|
||||
@ -880,7 +894,6 @@ CArtifactInstance::CArtifactInstance( CArtifact *Art)
|
||||
{
|
||||
init();
|
||||
setType(Art);
|
||||
|
||||
}
|
||||
|
||||
// CArtifactInstance::CArtifactInstance(int aid)
|
||||
@ -911,6 +924,7 @@ CArtifactInstance * CArtifactInstance::createScroll( const CSpell *s)
|
||||
void CArtifactInstance::init()
|
||||
{
|
||||
id = -1;
|
||||
setNodeType(ARTIFACT_INSTANCE);
|
||||
}
|
||||
|
||||
int CArtifactInstance::firstAvailableSlot(const CGHeroInstance *h) const
|
||||
|
@ -198,6 +198,7 @@ public:
|
||||
class DLL_EXPORT CArtHandler //handles artifacts
|
||||
{
|
||||
void giveArtBonus(int aid, Bonus::BonusType type, int val, int subtype = -1, int valType = Bonus::BASE_NUMBER, ILimiter * limiter = NULL);
|
||||
void giveArtBonus(int aid, Bonus::BonusType type, int val, int subtype, IPropagator* propagator);
|
||||
public:
|
||||
std::vector<CArtifact*> treasures, minors, majors, relics;
|
||||
std::vector< ConstTransitivePtr<CArtifact> > artifacts;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include "CBuildingHandler.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
@ -1871,49 +1872,64 @@ int CGTownInstance::getHordeLevel(const int & HID) const//HID - 0 or 1; returns
|
||||
}
|
||||
int CGTownInstance::creatureGrowth(const int & level) const
|
||||
{
|
||||
if (level<0 || level >=CREATURES_PER_TOWN)
|
||||
return 0;
|
||||
if (!vstd::contains(builtBuildings, Buildings::DWELL_FIRST+level))
|
||||
return 0; //no dwelling
|
||||
TCreature creid = town->basicCreatures[level];
|
||||
|
||||
int ret = VLC->creh->creatures[creid]->growth;
|
||||
switch(fortLevel())
|
||||
{
|
||||
case 3:
|
||||
ret*=2;break;
|
||||
case 2:
|
||||
ret*=(1.5); break;
|
||||
}
|
||||
ret *= (1 + VLC->creh->creatures[creid]->valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100); // double growth or plague
|
||||
if(tempOwner != NEUTRAL_PLAYER)
|
||||
{
|
||||
ret *= (100.0f + cb->gameState()->players[tempOwner].valOfBonuses
|
||||
(Selector::type(Bonus::CREATURE_GROWTH_PERCENT) && Selector::sourceType(Bonus::ARTIFACT)))/100; //Statue of Legion
|
||||
for (std::vector<ConstTransitivePtr<CGDwelling> >::const_iterator it = cb->gameState()->players[tempOwner].dwellings.begin(); it != cb->gameState()->players[tempOwner].dwellings.end(); ++it)
|
||||
{ //+1 for each dwelling
|
||||
if (VLC->creh->creatures[creid]->idNumber == (*it)->creatures[0].second[0])
|
||||
++ret;
|
||||
}
|
||||
}
|
||||
if(getHordeLevel(0)==level)
|
||||
if((builtBuildings.find(18)!=builtBuildings.end()) || (builtBuildings.find(19)!=builtBuildings.end()))
|
||||
ret+=VLC->creh->creatures[creid]->hordeGrowth;
|
||||
if(getHordeLevel(1)==level)
|
||||
if((builtBuildings.find(24)!=builtBuildings.end()) || (builtBuildings.find(25)!=builtBuildings.end()))
|
||||
ret+=VLC->creh->creatures[creid]->hordeGrowth;
|
||||
|
||||
//support for legs of legion etc.
|
||||
if(garrisonHero)
|
||||
ret += garrisonHero->valOfBonuses(Bonus::CREATURE_GROWTH, level);
|
||||
if(visitingHero)
|
||||
ret += visitingHero->valOfBonuses(Bonus::CREATURE_GROWTH, level);
|
||||
if(builtBuildings.find(26)!=builtBuildings.end()) //grail - +50% to ALL growth
|
||||
ret*=1.5;
|
||||
//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
|
||||
return getGrowthInfo(level).totalGrowth();
|
||||
}
|
||||
|
||||
GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
{
|
||||
GrowthInfo ret;
|
||||
|
||||
if (level<0 || level >=CREATURES_PER_TOWN)
|
||||
return ret;
|
||||
if (!vstd::contains(builtBuildings, Buildings::DWELL_FIRST+level))
|
||||
return ret; //no dwelling
|
||||
|
||||
const CCreature *creature = VLC->creh->creatures[town->basicCreatures[level]];
|
||||
const int base = creature->growth;
|
||||
int castleBonus = 0;
|
||||
|
||||
ret.entries.push_back(GrowthInfo::Entry(VLC->generaltexth->allTexts[590], base));// \n\nBasic growth %d"
|
||||
|
||||
if ( vstd::contains(builtBuildings, Buildings::CASTLE))
|
||||
ret.entries.push_back(GrowthInfo::Entry(subID, Buildings::CASTLE, castleBonus = base));
|
||||
else if ( vstd::contains(builtBuildings, Buildings::CITADEL))
|
||||
ret.entries.push_back(GrowthInfo::Entry(subID, Buildings::CITADEL, castleBonus = base / 2));
|
||||
|
||||
if(town->hordeLvl[0] == level)//horde 1
|
||||
if( vstd::contains(builtBuildings, Buildings::HORDE_1) || vstd::contains(builtBuildings, Buildings::HORDE_1_UPGR))
|
||||
ret.entries.push_back(GrowthInfo::Entry(subID, Buildings::HORDE_1, creature->hordeGrowth));
|
||||
|
||||
if(town->hordeLvl[1] == level)//horde 2
|
||||
if(vstd::contains(builtBuildings, Buildings::HORDE_2) || vstd::contains(builtBuildings, Buildings::HORDE_2_UPGR))
|
||||
ret.entries.push_back(GrowthInfo::Entry(subID, Buildings::HORDE_2, creature->hordeGrowth));
|
||||
|
||||
int dwellingBonus = 0;
|
||||
if(const PlayerState *p = cb->getPlayer(tempOwner, false))
|
||||
{
|
||||
BOOST_FOREACH(const CGDwelling *dwelling, p->dwellings)
|
||||
if(creature->idNumber == dwelling->creatures[0].second[0])
|
||||
dwellingBonus++;
|
||||
}
|
||||
|
||||
if(dwellingBonus)
|
||||
ret.entries.push_back(GrowthInfo::Entry(VLC->generaltexth->allTexts[591], dwellingBonus));// \nExternal dwellings %+d
|
||||
|
||||
//other *-of-legion-like bonuses (%d to growth cumulative with grail)
|
||||
boost::shared_ptr<BonusList> bonuses = getBonuses(Selector::type(Bonus::CREATURE_GROWTH) && Selector::subtype(level));
|
||||
BOOST_FOREACH(const Bonus *b, *bonuses)
|
||||
ret.entries.push_back(GrowthInfo::Entry(b->Description() + " %+d", b->val));
|
||||
|
||||
//statue-of-legion-like bonus: % to base+castle
|
||||
boost::shared_ptr<BonusList> bonuses2 = getBonuses(Selector::type(Bonus::CREATURE_GROWTH_PERCENT));
|
||||
BOOST_FOREACH(const Bonus *b, *bonuses2)
|
||||
ret.entries.push_back(GrowthInfo::Entry(b->Description() + " %+d", b->val * (base + castleBonus) / 100));
|
||||
|
||||
if(vstd::contains(builtBuildings, Buildings::GRAIL)) //grail - +50% to ALL (so far added) growth
|
||||
ret.entries.push_back(GrowthInfo::Entry(subID, Buildings::GRAIL, ret.totalGrowth() / 2));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CGTownInstance::dailyIncome() const
|
||||
{
|
||||
int ret = 0;
|
||||
@ -7070,3 +7086,29 @@ void CGUniversity::onHeroVisit(const CGHeroInstance * h) const
|
||||
ow.window = OpenWindow::UNIVERSITY_WINDOW;
|
||||
cb->sendAndApply(&ow);
|
||||
}
|
||||
|
||||
GrowthInfo::Entry::Entry(const std::string &format, int _count)
|
||||
: count(_count)
|
||||
{
|
||||
description = boost::str(boost::format(format) % count);
|
||||
}
|
||||
|
||||
GrowthInfo::Entry::Entry(int subID, Buildings::EBuilding building, int _count)
|
||||
: count(_count)
|
||||
{
|
||||
description = boost::str(boost::format("%s %+d") % VLC->buildh->buildings[subID][building]->Name() % count);
|
||||
}
|
||||
|
||||
CTownAndVisitingHero::CTownAndVisitingHero()
|
||||
{
|
||||
setNodeType(TOWN_AND_VISITOR);
|
||||
}
|
||||
|
||||
int GrowthInfo::totalGrowth() const
|
||||
{
|
||||
int ret = 0;
|
||||
BOOST_FOREACH(const Entry &entry, entries)
|
||||
ret += entry.count;
|
||||
|
||||
return ret;
|
||||
}
|
@ -519,6 +519,22 @@ public:
|
||||
|
||||
class DLL_EXPORT CTownAndVisitingHero : public CBonusSystemNode
|
||||
{
|
||||
public:
|
||||
CTownAndVisitingHero();
|
||||
};
|
||||
|
||||
struct DLL_EXPORT GrowthInfo
|
||||
{
|
||||
struct Entry
|
||||
{
|
||||
int count;
|
||||
std::string description;
|
||||
Entry(const std::string &format, int _count);
|
||||
Entry(int subID, Buildings::EBuilding building, int _count);
|
||||
};
|
||||
|
||||
std::vector<Entry> entries;
|
||||
int totalGrowth() const;
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGTownInstance : public CGDwelling, public IShipyard, public IMarket
|
||||
@ -591,6 +607,7 @@ public:
|
||||
bool creatureDwelling(const int & level, bool upgraded=false) const;
|
||||
int getHordeLevel(const int & HID) const; //HID - 0 or 1; returns creature level or -1 if that horde structure is not present
|
||||
int creatureGrowth(const int & level) const;
|
||||
GrowthInfo getGrowthInfo(int level) const;
|
||||
bool hasFort() const;
|
||||
bool hasCapitol() const;
|
||||
int dailyIncome() const; //calculates daily income of this town
|
||||
|
@ -587,7 +587,7 @@ public:
|
||||
}
|
||||
enum ENodeTypes
|
||||
{
|
||||
UNKNOWN, STACK_INSTANCE, STACK_BATTLE, SPECIALITY, ARTIFACT, CREATURE, ARTIFACT_INSTANCE, HERO, PLAYER, TEAM
|
||||
UNKNOWN, STACK_INSTANCE, STACK_BATTLE, SPECIALITY, ARTIFACT, CREATURE, ARTIFACT_INSTANCE, HERO, PLAYER, TEAM, TOWN_AND_VISITOR
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -950,7 +950,7 @@ struct HeroVisit : CPackForClient //531
|
||||
|
||||
struct NewTurn : public CPackForClient //101
|
||||
{
|
||||
enum weekType {NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, DEITYOFFIRE, PLAGUE, CUSTOM, NO_ACTION, NONE};
|
||||
enum weekType {NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, DEITYOFFIRE, PLAGUE, NO_ACTION};
|
||||
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
@ -766,65 +766,23 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
|
||||
BOOST_FOREACH(SetAvailableCreatures h, cres) //set available creatures in towns
|
||||
h.applyGs(gs);
|
||||
|
||||
if (specialWeek != NO_ACTION) //first pack applied, reset all effects and aplly new
|
||||
gs->globalEffects.popBonuses(Bonus::OneDay); //works for children -> all game objs
|
||||
if(gs->getDate(1)) //new week
|
||||
gs->globalEffects.popBonuses(Bonus::OneWeek); //works for children -> all game objs
|
||||
|
||||
//TODO not really a single root hierarchy, what about bonuses placed elsewhere? [not an issue with H3 mechanics but in the future...]
|
||||
|
||||
//count days without town
|
||||
for( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
|
||||
{
|
||||
//TODO? won't work for battles lasting several turns (not an issue now but...)
|
||||
gs->globalEffects.popBonuses(Bonus::OneDay); //works for children -> all game objs
|
||||
|
||||
if(gs->getDate(1)) //new week, Monday that is
|
||||
{
|
||||
gs->globalEffects.popBonuses(Bonus::OneWeek); //works for children -> all game objs
|
||||
|
||||
Bonus *b = new Bonus();
|
||||
b->duration = Bonus::ONE_WEEK;
|
||||
b->source = Bonus::SPECIAL_WEEK;
|
||||
b->effectRange = Bonus::NO_LIMIT;
|
||||
b->valType = Bonus::BASE_NUMBER; //certainly not intuitive
|
||||
switch (specialWeek)
|
||||
{
|
||||
case DOUBLE_GROWTH:
|
||||
b->val = 100;
|
||||
b->type = Bonus::CREATURE_GROWTH_PERCENT;
|
||||
b->limiter.reset(new CCreatureTypeLimiter(*VLC->creh->creatures[creatureid], false));
|
||||
break;
|
||||
case BONUS_GROWTH:
|
||||
b->val = 5;
|
||||
b->type = Bonus::CREATURE_GROWTH;
|
||||
b->limiter.reset(new CCreatureTypeLimiter(*VLC->creh->creatures[creatureid], false));
|
||||
break;
|
||||
case DEITYOFFIRE:
|
||||
b->val = 15;
|
||||
b->type = Bonus::CREATURE_GROWTH;
|
||||
b->limiter.reset(new CCreatureTypeLimiter(*VLC->creh->creatures[42], true));
|
||||
break;
|
||||
case PLAGUE:
|
||||
b->val = -100; //no basic creatures
|
||||
b->type = Bonus::CREATURE_GROWTH_PERCENT;
|
||||
break;
|
||||
default:
|
||||
b->val = 0;
|
||||
|
||||
}
|
||||
if (b->val)
|
||||
gs->globalEffects.addNewBonus(b);
|
||||
}
|
||||
}
|
||||
else //second pack is applied
|
||||
{
|
||||
//count days without town
|
||||
for( std::map<ui8, PlayerState>::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++;
|
||||
}
|
||||
if(resetBuilded) //reset amount of structures set in this turn in towns
|
||||
{
|
||||
BOOST_FOREACH(CGTownInstance* t, gs->map->towns)
|
||||
t->builded = 0;
|
||||
}
|
||||
if(i->second.towns.size() || gs->day == 1)
|
||||
i->second.daysWithoutCastle = 0;
|
||||
else
|
||||
i->second.daysWithoutCastle++;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(CGTownInstance* t, gs->map->towns)
|
||||
t->builded = 0;
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetObjectProperty::applyGs( CGameState *gs )
|
||||
|
@ -853,55 +853,70 @@ void CGameHandler::newTurn()
|
||||
{
|
||||
tlog5 << "Turn " << gs->day+1 << std::endl;
|
||||
NewTurn n;
|
||||
n.specialWeek = NewTurn::NO_ACTION;
|
||||
n.creatureid = -1;
|
||||
n.day = gs->day + 1;
|
||||
n.resetBuilded = true;
|
||||
bool newmonth = false;
|
||||
|
||||
bool firstTurn = !getDate(0);
|
||||
bool newWeek = getDate(1) == 7; //day numbers are confusing, as day was not yet switched
|
||||
bool newMonth = getDate(4) == 28;
|
||||
|
||||
std::map<ui8, si32> hadGold;//starting gold - for buildings like dwarven treasury
|
||||
srand(time(NULL));
|
||||
|
||||
if (getDate(1) == 7 && getDate(0)>1) //new week (day numbers are confusing, as day was not yet switched)
|
||||
if (newWeek && !firstTurn)
|
||||
{
|
||||
int monthType = rand()%100;
|
||||
if(getDate(4) == 28) //new month
|
||||
n.specialWeek = NewTurn::NORMAL;
|
||||
bool deityOfFireBuilt = false;
|
||||
BOOST_FOREACH(const CGTownInstance *t, gs->map->towns)
|
||||
{
|
||||
newmonth = true;
|
||||
if (monthType < 40) //double growth
|
||||
if(t->subID == 3 && vstd::contains(t->builtBuildings, Buildings::GRAIL))
|
||||
{
|
||||
n.specialWeek = NewTurn::DOUBLE_GROWTH;
|
||||
if (ALLCREATURESGETDOUBLEMONTHS)
|
||||
deityOfFireBuilt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(deityOfFireBuilt)
|
||||
{
|
||||
n.specialWeek = NewTurn::DEITYOFFIRE;
|
||||
n.creatureid = 42;
|
||||
}
|
||||
else
|
||||
{
|
||||
int monthType = rand()%100;
|
||||
if(newMonth) //new month
|
||||
{
|
||||
if (monthType < 40) //double growth
|
||||
{
|
||||
std::pair<int,int> newMonster(54, VLC->creh->pickRandomMonster(boost::ref(rand)));
|
||||
n.specialWeek = NewTurn::DOUBLE_GROWTH;
|
||||
if (ALLCREATURESGETDOUBLEMONTHS)
|
||||
{
|
||||
std::pair<int,int> newMonster(54, VLC->creh->pickRandomMonster(boost::ref(rand)));
|
||||
n.creatureid = newMonster.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::set<TCreature>::const_iterator it = VLC->creh->doubledCreatures.begin();
|
||||
std::advance (it, rand() % VLC->creh->doubledCreatures.size()); //picking random element of set is tiring
|
||||
n.creatureid = *it;
|
||||
}
|
||||
}
|
||||
else if (monthType < 50)
|
||||
n.specialWeek = NewTurn::PLAGUE;
|
||||
}
|
||||
else //it's a week, but not full month
|
||||
{
|
||||
if (monthType < 25)
|
||||
{
|
||||
n.specialWeek = NewTurn::BONUS_GROWTH; //+5
|
||||
std::pair<int,int> newMonster (54, VLC->creh->pickRandomMonster(boost::ref(rand)));
|
||||
//TODO do not pick neutrals
|
||||
n.creatureid = newMonster.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::set<TCreature>::const_iterator it = VLC->creh->doubledCreatures.begin();
|
||||
std::advance (it, rand() % VLC->creh->doubledCreatures.size()); //picking random elelemnt of set is tiring
|
||||
n.creatureid = *it;
|
||||
}
|
||||
}
|
||||
else if (monthType < 90)
|
||||
n.specialWeek = NewTurn::NORMAL;
|
||||
else
|
||||
n.specialWeek = NewTurn::PLAGUE;
|
||||
}
|
||||
else //it's a week, but not full month
|
||||
{
|
||||
newmonth = false;
|
||||
if (monthType < 25)
|
||||
{
|
||||
n.specialWeek = NewTurn::BONUS_GROWTH; //+5
|
||||
std::pair<int,int> newMonster (54, VLC->creh->pickRandomMonster(boost::ref(rand)));
|
||||
n.creatureid = newMonster.second;
|
||||
}
|
||||
else
|
||||
n.specialWeek = NewTurn::NORMAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
n.specialWeek = NewTurn::NO_ACTION; //don't remove bonuses
|
||||
|
||||
bmap<ui32, ConstTransitivePtr<CGHeroInstance> > pool = gs->hpool.heroesPool;
|
||||
|
||||
@ -915,7 +930,7 @@ void CGameHandler::newTurn()
|
||||
std::pair<ui8,si32> playerGold(i->first,i->second.resources[Res::GOLD]);
|
||||
hadGold.insert(playerGold);
|
||||
|
||||
if(gs->getDate(1)==7) //first day of week - new heroes in tavern
|
||||
if(newWeek) //new heroes in tavern
|
||||
{
|
||||
SetAvailableHeroes sah;
|
||||
sah.player = i->first;
|
||||
@ -955,7 +970,7 @@ void CGameHandler::newTurn()
|
||||
|
||||
n.heroes.insert(hth);
|
||||
|
||||
if(gs->day) //not first day
|
||||
if(!firstTurn) //not first day
|
||||
{
|
||||
n.res[i->first][Res::GOLD] += h->valOfBonuses(Selector::typeSubtype(Bonus::SECONDARY_SKILL_PREMY, CGHeroInstance::ESTATES)); //estates
|
||||
|
||||
@ -969,131 +984,113 @@ void CGameHandler::newTurn()
|
||||
// townID, creatureID, amount
|
||||
std::map<si32, std::map<si32, si32> > newCreas;//creatures that needs to be added by town events
|
||||
|
||||
for(std::vector<ConstTransitivePtr<CGTownInstance> >::iterator j = gs->map->towns.begin(); j!=gs->map->towns.end(); j++)//handle towns
|
||||
BOOST_FOREACH(CGTownInstance *t, gs->map->towns)
|
||||
{
|
||||
ui8 player = (*j)->tempOwner;
|
||||
if(gs->getDate(1)==7) //first day of week
|
||||
ui8 player = t->tempOwner;
|
||||
handleTownEvents(t, n, newCreas);
|
||||
if(newWeek) //first day of week
|
||||
{
|
||||
if ((*j)->subID == 5 && vstd::contains((*j)->builtBuildings, 22))
|
||||
setPortalDwelling(*j, true, (n.specialWeek == NewTurn::PLAGUE ? true : false)); //set creatures for Portal of Summoning
|
||||
if(t->subID == 5 && vstd::contains(t->builtBuildings, Buildings::SPECIAL_3))
|
||||
setPortalDwelling(t, true, (n.specialWeek == NewTurn::PLAGUE ? true : false)); //set creatures for Portal of Summoning
|
||||
|
||||
if ((**j).subID == 1 && gs->getDate(0) && player < PLAYER_LIMIT && vstd::contains((**j).builtBuildings, 22))//dwarven treasury
|
||||
n.res[player][Res::GOLD] += hadGold[player]/10; //give 10% of starting gold
|
||||
}
|
||||
if(gs->day && player < PLAYER_LIMIT)//not the first day and town not neutral
|
||||
{
|
||||
////SetResources r;
|
||||
//r.player = (**j).tempOwner;
|
||||
if(vstd::contains((**j).builtBuildings, Buildings::RESOURCE_SILO)) //there is resource silo
|
||||
if(!firstTurn)
|
||||
if (t->subID == 1 && player < PLAYER_LIMIT && vstd::contains(t->builtBuildings, Buildings::SPECIAL_3))//dwarven treasury
|
||||
n.res[player][Res::GOLD] += hadGold[player]/10; //give 10% of starting gold
|
||||
|
||||
SetAvailableCreatures sac;
|
||||
sac.tid = t->id;
|
||||
sac.creatures = t->creatures;
|
||||
for (int k=0; k < CREATURES_PER_TOWN; k++) //creature growths
|
||||
{
|
||||
if((**j).town->primaryRes == 127) //we'll give wood and ore
|
||||
if(t->creatureDwelling(k))//there is dwelling (k-level)
|
||||
{
|
||||
ui32 &availableCount = sac.creatures[k].first;
|
||||
const CCreature *cre = VLC->creh->creatures[t->creatureDwelling(k, true) ? t->town->upgradedCreatures[k] : t->town->basicCreatures[k]];
|
||||
|
||||
if (n.specialWeek == NewTurn::PLAGUE)
|
||||
availableCount = t->creatures[k].first / 2; //halve their number, no growth
|
||||
else
|
||||
{
|
||||
if(firstTurn) //first day of game: use only basic growths
|
||||
availableCount = cre->growth;
|
||||
else
|
||||
availableCount += t->creatureGrowth(k);
|
||||
|
||||
if(n.creatureid == cre->idNumber
|
||||
|| n.specialWeek == NewTurn::DEITYOFFIRE && (cre->idNumber == 42 || cre->idNumber == 43))
|
||||
{
|
||||
if(n.specialWeek == NewTurn::DOUBLE_GROWTH)
|
||||
availableCount *= 2;
|
||||
else if(n.specialWeek == NewTurn::BONUS_GROWTH)
|
||||
availableCount += 5;
|
||||
else if(n.specialWeek == NewTurn::DEITYOFFIRE)
|
||||
availableCount += 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//add creatures from town events
|
||||
if (vstd::contains(newCreas, t->id))
|
||||
for(std::map<si32, si32>::iterator i=newCreas[t->id].begin() ; i!=newCreas[t->id].end(); i++)
|
||||
sac.creatures[i->first].first += i->second;
|
||||
|
||||
n.cres.push_back(sac);
|
||||
}
|
||||
if(!firstTurn && player < PLAYER_LIMIT)//not the first day and town not neutral
|
||||
{
|
||||
if(vstd::contains(t->builtBuildings, Buildings::RESOURCE_SILO)) //there is resource silo
|
||||
{
|
||||
if(t->town->primaryRes == 127) //we'll give wood and ore
|
||||
{
|
||||
n.res[player][Res::WOOD] ++;
|
||||
n.res[player][Res::ORE] ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
n.res[player][(**j).town->primaryRes] ++;;
|
||||
n.res[player][t->town->primaryRes] ++;
|
||||
}
|
||||
}
|
||||
n.res[player][Res::GOLD] += (**j).dailyIncome();
|
||||
|
||||
n.res[player][Res::GOLD] += t->dailyIncome();
|
||||
}
|
||||
handleTownEvents(*j, n, newCreas);
|
||||
if (vstd::contains((**j).builtBuildings, Buildings::GRAIL))
|
||||
if(vstd::contains(t->builtBuildings, Buildings::GRAIL) && t->subID == 2)
|
||||
{
|
||||
switch ((**j).subID)
|
||||
{
|
||||
case 2: // Skyship, probably easier to handle same as Veil of darkness
|
||||
{ //do it every new day after veils apply
|
||||
FoWChange fw;
|
||||
fw.mode = 1;
|
||||
fw.player = player;
|
||||
getAllTiles(fw.tiles, player, -1, 0);
|
||||
sendAndApply (&fw);
|
||||
}
|
||||
break;
|
||||
case 3: //Deity of Fire
|
||||
{
|
||||
if (getDate(0) > 1)
|
||||
{
|
||||
n.specialWeek = NewTurn::DEITYOFFIRE; //spawn familiars on new month
|
||||
n.creatureid = 42; //familiar
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Skyship, probably easier to handle same as Veil of darkness
|
||||
//do it every new day after veils apply
|
||||
FoWChange fw;
|
||||
fw.mode = 1;
|
||||
fw.player = player;
|
||||
getAllTiles(fw.tiles, player, -1, 0);
|
||||
sendAndApply (&fw);
|
||||
}
|
||||
if ((**j).hasBonusOfType (Bonus::DARKNESS))
|
||||
if (t->hasBonusOfType (Bonus::DARKNESS))
|
||||
{
|
||||
(**j).hideTiles((**j).getOwner(), (**j).getBonus(Selector::type(Bonus::DARKNESS))->val);
|
||||
t->hideTiles(t->getOwner(), t->getBonus(Selector::type(Bonus::DARKNESS))->val);
|
||||
}
|
||||
//unhiding what shouldn't be hidden? //that's handled in netpacks client
|
||||
}
|
||||
|
||||
if(getDate(2) == 1) //first week
|
||||
if(newMonth)
|
||||
{
|
||||
SetAvailableArtifacts saa;
|
||||
saa.id = -1;
|
||||
pickAllowedArtsSet(saa.arts);
|
||||
sendAndApply(&saa);
|
||||
}
|
||||
|
||||
sendAndApply(&n);
|
||||
|
||||
if (gs->getDate(1)==1) //first day of week, day has already been changed
|
||||
if(newWeek)
|
||||
{
|
||||
if (getDate(4) == 1 && (n.specialWeek == NewTurn::DOUBLE_GROWTH || n.specialWeek == NewTurn::DEITYOFFIRE))
|
||||
{ //spawn wandering monsters
|
||||
std::vector<int3>::iterator tile;
|
||||
std::vector<int3> tiles;
|
||||
getFreeTiles(tiles);
|
||||
ui32 amount = (tiles.size()) >> 6;
|
||||
std::random_shuffle(tiles.begin(), tiles.end(), p_myrandom);
|
||||
tlog5 << "Spawning wandering monsters. Found " << tiles.size() << " free tiles. Creature type: " << n.creatureid << std::endl;
|
||||
const CCreature *cre = VLC->creh->creatures[n.creatureid];
|
||||
for (int i = 0; i < amount; ++i)
|
||||
{
|
||||
tile = tiles.begin();
|
||||
tlog5 << "\tSpawning monster at " << *tile << std::endl;
|
||||
putNewMonster(n.creatureid, cre->getRandomAmount(std::rand), *tile);
|
||||
tiles.erase(tile); //not use it again
|
||||
}
|
||||
//spawn wandering monsters
|
||||
if (newMonth && (n.specialWeek == NewTurn::DOUBLE_GROWTH || n.specialWeek == NewTurn::DEITYOFFIRE))
|
||||
{
|
||||
spawnWanderingMonsters(n.creatureid);
|
||||
}
|
||||
|
||||
NewTurn n2; //just to handle creature growths after bonuses are applied
|
||||
n2.specialWeek = NewTurn::NO_ACTION;
|
||||
n2.day = gs->day;
|
||||
n2.resetBuilded = true;
|
||||
|
||||
for(std::vector<ConstTransitivePtr<CGTownInstance> >::iterator j = gs->map->towns.begin(); j!=gs->map->towns.end(); j++)//handle towns
|
||||
//new week info popup
|
||||
if(!firstTurn)
|
||||
{
|
||||
SetAvailableCreatures sac;
|
||||
sac.tid = (**j).id;
|
||||
sac.creatures = (**j).creatures;
|
||||
for (int k=0; k < CREATURES_PER_TOWN; k++) //creature growths
|
||||
{
|
||||
if((**j).creatureDwelling(k))//there is dwelling (k-level)
|
||||
{
|
||||
if (n.specialWeek == NewTurn::PLAGUE)
|
||||
sac.creatures[k].first = (**j).creatures[k].first / 2; //halve their number, no growth
|
||||
else
|
||||
{
|
||||
sac.creatures[k].first += (**j).creatureGrowth(k);
|
||||
if(gs->getDate(0) == 1) //first day of game: use only basic growths
|
||||
amin(sac.creatures[k].first, VLC->creh->creatures[(*j)->town->basicCreatures[k]]->growth);
|
||||
}
|
||||
}
|
||||
}
|
||||
//creatures from town events
|
||||
if (vstd::contains(newCreas, (**j).id))
|
||||
for(std::map<si32, si32>::iterator i=newCreas[(**j).id].begin() ; i!=newCreas[(**j).id].end(); i++)
|
||||
sac.creatures[i->first].first += i->second;
|
||||
|
||||
n2.cres.push_back(sac);
|
||||
}
|
||||
if (gs->getDate(0) > 1)
|
||||
{
|
||||
InfoWindow iw; //new week info
|
||||
InfoWindow iw;
|
||||
switch (n.specialWeek)
|
||||
{
|
||||
case NewTurn::DOUBLE_GROWTH:
|
||||
@ -1118,7 +1115,7 @@ void CGameHandler::newTurn()
|
||||
iw.text.addReplacement2(15); //%+d 15
|
||||
break;
|
||||
default:
|
||||
iw.text.addTxt(MetaString::ARRAY_TXT, (newmonth ? 130 : 133));
|
||||
iw.text.addTxt(MetaString::ARRAY_TXT, (newMonth ? 130 : 133));
|
||||
iw.text.addReplacement(MetaString::ARRAY_TXT, 43 + rand()%15);
|
||||
}
|
||||
for (std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end(); i++)
|
||||
@ -1127,9 +1124,8 @@ void CGameHandler::newTurn()
|
||||
sendAndApply(&iw);
|
||||
}
|
||||
}
|
||||
|
||||
sendAndApply(&n2);
|
||||
}
|
||||
|
||||
tlog5 << "Info about turn " << n.day << "has been sent!" << std::endl;
|
||||
handleTimeEvents();
|
||||
//call objects
|
||||
@ -3884,6 +3880,7 @@ void CGameHandler::handleTimeEvents()
|
||||
|
||||
void CGameHandler::handleTownEvents(CGTownInstance * town, NewTurn &n, std::map<si32, std::map<si32, si32> > &newCreas)
|
||||
{
|
||||
//TODO event removing desync!!!
|
||||
town->events.sort(evntCmp);
|
||||
while(town->events.size() && town->events.front()->firstOccurence == gs->day)
|
||||
{
|
||||
@ -5208,6 +5205,23 @@ void CGameHandler::commitPackage( CPackForClient *pack )
|
||||
sendAndApply(pack);
|
||||
}
|
||||
|
||||
void CGameHandler::spawnWanderingMonsters(int creatureID)
|
||||
{
|
||||
std::vector<int3>::iterator tile;
|
||||
std::vector<int3> tiles;
|
||||
getFreeTiles(tiles);
|
||||
ui32 amount = (tiles.size()) >> 6;
|
||||
std::random_shuffle(tiles.begin(), tiles.end(), p_myrandom);
|
||||
tlog5 << "Spawning wandering monsters. Found " << tiles.size() << " free tiles. Creature type: " << creatureID << std::endl;
|
||||
const CCreature *cre = VLC->creh->creatures[creatureID];
|
||||
for (int i = 0; i < amount; ++i)
|
||||
{
|
||||
tile = tiles.begin();
|
||||
tlog5 << "\tSpawning monster at " << *tile << std::endl;
|
||||
putNewMonster(creatureID, cre->getRandomAmount(std::rand), *tile);
|
||||
tiles.erase(tile); //not use it again
|
||||
}
|
||||
}
|
||||
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleInfo *bat)
|
||||
{
|
||||
int color = army->tempOwner;
|
||||
|
@ -254,6 +254,7 @@ public:
|
||||
void handleAfterAttackCasting (const BattleAttack & bat);
|
||||
void attackCasting(const BattleAttack & bat, Bonus::BonusType attackMode, const CStack * attacker);
|
||||
bool sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, int slot);
|
||||
void spawnWanderingMonsters(int creatureID);
|
||||
friend class CVCMIServer;
|
||||
friend class CScriptCallback;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user