mirror of
https://github.com/vcmi/vcmi.git
synced 2025-05-13 22:06:58 +02:00
Next part of creature weeks code.
This commit is contained in:
parent
7b5fefb65e
commit
630dc7f7f2
@ -11,6 +11,7 @@
|
||||
#include <boost/algorithm/string/find.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "../lib/CGameState.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
extern CLodHandler * bitmaph;
|
||||
@ -136,7 +137,10 @@ void CCreature::addBonus(int val, int type, int subtype /*= -1*/)
|
||||
Bonus added(Bonus::PERMANENT, type, Bonus::CREATURE_ABILITY, val, idNumber, subtype, Bonus::BASE_NUMBER);
|
||||
bonuses.push_back(added);
|
||||
}
|
||||
|
||||
void CCreature::getParents(TNodes &out, const CBonusSystemNode *root /*= NULL*/) const
|
||||
{
|
||||
out.insert(VLC->creh->globalEffects);
|
||||
}
|
||||
bool CCreature::isMyUpgrade(const CCreature *anotherCre) const
|
||||
{
|
||||
//TODO upgrade of upgrade?
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "CSoundBase.h"
|
||||
#include "../lib/HeroBonus.h"
|
||||
#include "../lib/CGameState.h"
|
||||
|
||||
/*
|
||||
* CCreatureHandler.h, part of VCMI engine
|
||||
@ -21,6 +22,7 @@
|
||||
|
||||
class CLodHandler;
|
||||
class CCreatureHandler;
|
||||
class CCreature;
|
||||
|
||||
class DLL_EXPORT CCreature : public CBonusSystemNode
|
||||
{
|
||||
@ -60,7 +62,7 @@ public:
|
||||
ui32 getMaxDamage() const;
|
||||
|
||||
void addBonus(int val, int type, int subtype = -1);
|
||||
|
||||
void getParents(TNodes &out, const CBonusSystemNode *root /*= NULL*/) const;
|
||||
|
||||
template<typename RanGen>
|
||||
int getRandomAmount(RanGen &ranGen)
|
||||
@ -95,8 +97,9 @@ public:
|
||||
|
||||
|
||||
class DLL_EXPORT CCreatureHandler
|
||||
{
|
||||
{
|
||||
public:
|
||||
CBonusSystemNode *globalEffects;
|
||||
std::set<int> notUsedMonsters;
|
||||
std::vector<CCreature*> creatures; //creature ID -> creature info
|
||||
std::map<int,std::vector<CCreature*> > levelCreatures; //level -> list of creatures
|
||||
@ -123,7 +126,7 @@ public:
|
||||
{
|
||||
//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature)
|
||||
h & notUsedMonsters & creatures & nameToID & idToProjectile & idToProjectileSpin & factionToTurretCreature;
|
||||
h & levelCreatures;
|
||||
h & levelCreatures & globalEffects;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1736,10 +1736,12 @@ void CGDwelling::newTurn() const
|
||||
{
|
||||
if(creatures[i].second.size())
|
||||
{
|
||||
CCreature *cre = VLC->creh->creatures[creatures[i].second[0]];
|
||||
TQuantity amount = cre->growth * (1 + cre->valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100) + cre->valOfBonuses(Bonus::CREATURE_GROWTH);
|
||||
if(false /*accumulate creatures*/)
|
||||
sac.creatures[i].first += VLC->creh->creatures[creatures[i].second[0]]->growth;
|
||||
sac.creatures[i].first += amount;
|
||||
else
|
||||
sac.creatures[i].first = VLC->creh->creatures[creatures[i].second[0]]->growth;
|
||||
sac.creatures[i].first = amount;
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
@ -1923,8 +1925,9 @@ int CGTownInstance::creatureGrowth(const int & level) const
|
||||
{
|
||||
if (level<0 || level >=CREATURES_PER_TOWN)
|
||||
return 0;
|
||||
TCreature creid = town->basicCreatures[level];
|
||||
|
||||
int ret = VLC->creh->creatures[town->basicCreatures[level]]->growth;
|
||||
int ret = VLC->creh->creatures[creid]->growth;
|
||||
switch(fortLevel())
|
||||
{
|
||||
case 3:
|
||||
@ -1932,29 +1935,33 @@ int CGTownInstance::creatureGrowth(const int & level) const
|
||||
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 *= (1 + cb->gameState()->players[tempOwner].valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100); //Statue of Legion
|
||||
for (std::vector<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[town->basicCreatures[level]]->idNumber == (*it)->creatures[0].second[0])
|
||||
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[town->basicCreatures[level]]->hordeGrowth;
|
||||
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[town->basicCreatures[level]]->hordeGrowth;
|
||||
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);
|
||||
//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
|
||||
return ret;//check CCastleInterface.cpp->CCastleInterface::CCreaInfo::clickRight if this one will be modified
|
||||
}
|
||||
int CGTownInstance::dailyIncome() const
|
||||
@ -6518,11 +6525,11 @@ void CArmedInstance::randomizeArmy(int type)
|
||||
void CArmedInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
|
||||
{
|
||||
const PlayerState *p = cb->getPlayerState(tempOwner);
|
||||
if(!p) //occurs when initializing starting hero and heroes from the pool, also for neutral armed objects
|
||||
out.insert(&cb->gameState()->globalEffects);
|
||||
else
|
||||
if(p)
|
||||
out.insert(p); //hero always inherits bonuses from player
|
||||
|
||||
out.insert(&cb->gameState()->globalEffects); //global effect are always active I believe
|
||||
|
||||
if(battle)
|
||||
out.insert(battle);
|
||||
}
|
||||
|
@ -1202,6 +1202,7 @@ CGameState::~CGameState()
|
||||
|
||||
void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
||||
{
|
||||
VLC->creh->globalEffects = &globalEffects;
|
||||
struct HLP
|
||||
{
|
||||
//it's assumed that given hero should receive the bonus
|
||||
|
@ -64,6 +64,54 @@ int DLL_EXPORT BonusList::totalValue() const
|
||||
return valFirst;
|
||||
}
|
||||
|
||||
int DLL_EXPORT BonusList::valPercent(Bonus::BonusType type, const CSelector &selector, int val) const
|
||||
{
|
||||
int base = val;
|
||||
int percentToBase = 0;
|
||||
int percentToAll = 0;
|
||||
int additive = 0;
|
||||
int indepMax = 0;
|
||||
bool hasIndepMax = false;
|
||||
|
||||
for(const_iterator i = begin(); i != end(); i++)
|
||||
{
|
||||
switch(i->valType)
|
||||
{
|
||||
case Bonus::BASE_NUMBER:
|
||||
base += i->val;
|
||||
break;
|
||||
case Bonus::PERCENT_TO_ALL:
|
||||
percentToAll += i->val;
|
||||
break;
|
||||
case Bonus::PERCENT_TO_BASE:
|
||||
percentToBase += i->val;
|
||||
break;
|
||||
case Bonus::ADDITIVE_VALUE:
|
||||
additive += i->val;
|
||||
break;
|
||||
case Bonus::INDEPENDENT_MAX:
|
||||
if (!indepMax)
|
||||
{
|
||||
indepMax = i->val;
|
||||
hasIndepMax = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
amax(indepMax, i->val);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
int modifiedBase = base + (base * percentToBase) / 100;
|
||||
modifiedBase += additive;
|
||||
int valFirst = (modifiedBase * (100 + percentToAll)) / 100;
|
||||
if (hasIndepMax)
|
||||
return std::max(valFirst, indepMax);
|
||||
else
|
||||
return valFirst;
|
||||
}
|
||||
|
||||
const DLL_EXPORT Bonus * BonusList::getFirst(const CSelector &selector) const
|
||||
{
|
||||
for (const_iterator i = begin(); i != end(); i++)
|
||||
@ -482,12 +530,23 @@ bool ILimiter::limit(const Bonus &b, const CBonusSystemNode &node) const /*retur
|
||||
|
||||
bool CCreatureTypeLimiter::limit(const Bonus &b, const CBonusSystemNode &node) const
|
||||
{
|
||||
if(node.nodeType != CBonusSystemNode::STACK)
|
||||
return true;
|
||||
|
||||
const CCreature *c = (static_cast<const CStackInstance *>(&node))->type;
|
||||
|
||||
return c != creature && (!includeUpgrades || !creature->isMyUpgrade(c)); //drop bonus if it's not our creature and (we dont check upgrades or its not our upgrade)
|
||||
switch (node.nodeType)
|
||||
{
|
||||
case CBonusSystemNode::STACK:
|
||||
{
|
||||
const CCreature *c = (static_cast<const CStackInstance *>(&node))->type;
|
||||
return c != creature && (!includeUpgrades || !creature->isMyUpgrade(c));
|
||||
} //drop bonus if it's not our creature and (we dont check upgrades or its not our upgrade)
|
||||
break;
|
||||
case CBonusSystemNode::CREATURE:
|
||||
{
|
||||
const CCreature *c = (static_cast<const CCreature *>(&node));
|
||||
return c != creature && (!includeUpgrades || !creature->isMyUpgrade(c));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
CCreatureTypeLimiter::CCreatureTypeLimiter(const CCreature &Creature, ui8 IncludeUpgrades /*= true*/)
|
||||
:creature(&Creature), includeUpgrades(IncludeUpgrades)
|
||||
|
@ -69,7 +69,7 @@ namespace PrimarySkill
|
||||
BONUS_NAME(WATER_SPELLS) \
|
||||
BONUS_NAME(EARTH_SPELLS) \
|
||||
BONUS_NAME(GENERATE_RESOURCE) /*daily value, uses subtype (resource type)*/ \
|
||||
BONUS_NAME(CREATURE_GROWTH) /*for legion artifacts: value - week growth bonus, subtype - monster level*/ \
|
||||
BONUS_NAME(CREATURE_GROWTH) /*for legion artifacts: value - week growth bonus, subtype - monster level if aplicable*/ \
|
||||
BONUS_NAME(WHIRLPOOL_PROTECTION) /*hero won't lose army when teleporting through whirlpool*/ \
|
||||
BONUS_NAME(SPELL) /*hero knows spell, val - skill level (0 - 3), subtype - spell id*/ \
|
||||
BONUS_NAME(SPELLS_OF_LEVEL) /*hero knows all spells of given level, val - skill level; subtype - level*/ \
|
||||
@ -192,7 +192,8 @@ struct DLL_EXPORT Bonus
|
||||
SECONDARY_SKILL,
|
||||
HERO_SPECIAL,
|
||||
ARMY,
|
||||
CAMPAIGN_BONUS
|
||||
CAMPAIGN_BONUS,
|
||||
SPECIAL_WEEK
|
||||
};
|
||||
|
||||
enum LimitEffect
|
||||
@ -298,6 +299,7 @@ class BonusList : public std::list<Bonus>
|
||||
{
|
||||
public:
|
||||
int DLL_EXPORT totalValue() const; //subtype -> subtype of bonus, if -1 then any
|
||||
int DLL_EXPORT valPercent(Bonus::BonusType type, const CSelector &selector, int val) const;
|
||||
void DLL_EXPORT getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *source = NULL) const;
|
||||
void DLL_EXPORT getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *source = NULL) const;
|
||||
void DLL_EXPORT getModifiersWDescr(TModDescr &out) const;
|
||||
@ -379,7 +381,7 @@ public:
|
||||
|
||||
enum ENodeTypes
|
||||
{
|
||||
UNKNOWN, STACK, SPECIALITY, ARTIFACT
|
||||
UNKNOWN, STACK, SPECIALITY, ARTIFACT, CREATURE
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -690,7 +690,7 @@ struct SetAvailableArtifacts : public CPackForClient //519
|
||||
|
||||
struct NewTurn : public CPackForClient //101
|
||||
{
|
||||
enum weekType {NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, PLAGUE, CUSTOM};
|
||||
enum weekType {NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, PLAGUE, CUSTOM, NO_ACTION, NONE};
|
||||
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
@ -711,6 +711,7 @@ struct NewTurn : public CPackForClient //101
|
||||
ui32 day;
|
||||
bool resetBuilded;
|
||||
weekType specialWeek;
|
||||
TQuantity creatureid; //for creature weeks
|
||||
|
||||
NewTurn(){type = 101;};
|
||||
|
||||
|
@ -632,10 +632,42 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
|
||||
BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
|
||||
h->bonuses.remove_if(Bonus::OneDay);
|
||||
|
||||
if(gs->getDate(1) == 1) //new week, Monday that is
|
||||
if(gs->getDate(1) == 1 && specialWeek != NO_ACTION) //new week, Monday that is
|
||||
{
|
||||
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::PERCENT_TO_ALL;
|
||||
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::PERCENT_TO_ALL;
|
||||
break;
|
||||
default:
|
||||
b.val = 0;
|
||||
|
||||
}
|
||||
if (b.val)
|
||||
gs->globalEffects.bonuses.push_back(b);
|
||||
}
|
||||
|
||||
//count days without town
|
||||
|
@ -965,7 +965,7 @@ static bool evntCmp(const CMapEvent *a, const CMapEvent *b)
|
||||
return *a < *b;
|
||||
}
|
||||
|
||||
void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=false)
|
||||
void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=false, bool clear = false)
|
||||
{// bool forced = true - if creature should be replaced, if false - only if no creature was set
|
||||
|
||||
if (forced || town->creatures[CREATURES_PER_TOWN].second.empty())//we need to change creature
|
||||
@ -986,7 +986,10 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
|
||||
ui32 creapos = rand()%dwellings[dwellpos]->creatures.size();//for multi-creature dwellings like Golem Factory
|
||||
ui32 creature = dwellings[dwellpos]->creatures[creapos].second[0];
|
||||
|
||||
ssi.creatures[CREATURES_PER_TOWN].first = VLC->creh->creatures[creature]->growth;
|
||||
if (clear)
|
||||
ssi.creatures[CREATURES_PER_TOWN].first = std::max((ui32)1, (VLC->creh->creatures[creature]->growth)/2);
|
||||
else
|
||||
ssi.creatures[CREATURES_PER_TOWN].first = VLC->creh->creatures[creature]->growth;
|
||||
ssi.creatures[CREATURES_PER_TOWN].second.push_back(creature);
|
||||
sendAndApply(&ssi);
|
||||
}
|
||||
@ -998,10 +1001,60 @@ void CGameHandler::newTurn()
|
||||
NewTurn n;
|
||||
n.day = gs->day + 1;
|
||||
n.resetBuilded = true;
|
||||
bool newmonth = false;
|
||||
|
||||
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)
|
||||
{
|
||||
int monsterid;
|
||||
int monthType = rand()%100;
|
||||
if(getDate(4) == 28) //new month
|
||||
{
|
||||
newmonth = true;
|
||||
if (monthType < 100) //double growth
|
||||
{
|
||||
//spawn wandering monsters
|
||||
n.specialWeek = NewTurn::DOUBLE_GROWTH;
|
||||
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);
|
||||
|
||||
//std::pair<int,int> newMonster(54, VLC->creh->pickRandomMonster(boost::ref(rand)));
|
||||
std::pair<int,int> newMonster(54, 1); //pikeman
|
||||
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)
|
||||
n.specialWeek = NewTurn::NORMAL;
|
||||
else
|
||||
n.specialWeek = NewTurn::PLAGUE;
|
||||
}
|
||||
else //it's a week, but not full month
|
||||
{
|
||||
newmonth = false;
|
||||
if (monthType < 20)
|
||||
{
|
||||
n.specialWeek = NewTurn::BONUS_GROWTH; //+5
|
||||
std::pair<int,int> newMonster (54, VLC->creh->pickRandomMonster(boost::ref(rand)));
|
||||
monsterid = newMonster.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::map<ui32,CGHeroInstance *> pool = gs->hpool.heroesPool;
|
||||
|
||||
for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
|
||||
@ -1060,24 +1113,12 @@ void CGameHandler::newTurn()
|
||||
|
||||
if(gs->day) //not first day
|
||||
{
|
||||
switch(h->getSecSkillLevel(13)) //handle estates - give gold
|
||||
{
|
||||
case 1: //basic
|
||||
n.res[i->first][6] += 125;
|
||||
break;
|
||||
case 2: //advanced
|
||||
n.res[i->first][6] += 250;
|
||||
break;
|
||||
case 3: //expert
|
||||
n.res[i->first][6] += 500;
|
||||
break;
|
||||
}
|
||||
n.res[i->first][6] += h->valOfBonuses(Selector::typeSybtype(Bonus::SECONDARY_SKILL, 13)); //estates
|
||||
|
||||
for (int k = 0; k < RESOURCE_QUANTITY; k++)
|
||||
{
|
||||
n.res[i->first][k] += h->valOfBonuses(Bonus::GENERATE_RESOURCE, k);
|
||||
}
|
||||
//TODO player bonuses
|
||||
|
||||
}
|
||||
}
|
||||
//n.res.push_back(r);
|
||||
@ -1088,24 +1129,10 @@ void CGameHandler::newTurn()
|
||||
if(gs->getDate(1)==7) //first day of week
|
||||
{
|
||||
if ((*j)->subID == 5 && vstd::contains((*j)->builtBuildings, 22))
|
||||
setPortalDwelling(*j, true);//set creatures for Portal of Summoning
|
||||
|
||||
setPortalDwelling(*j, 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][6] += hadGold[player]/10; //give 10% of starting gold
|
||||
|
||||
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)
|
||||
{
|
||||
sac.creatures[k].first += (**j).creatureGrowth(k);
|
||||
if(!gs->getDate(0)) //first day of game: use only basic growths
|
||||
amin(sac.creatures[k].first, VLC->creh->creatures[(*j)->town->basicCreatures[k]]->growth);
|
||||
}
|
||||
}
|
||||
n.cres.push_back(sac);
|
||||
}
|
||||
if(gs->day && player < PLAYER_LIMIT)//not the first day and town not neutral
|
||||
{
|
||||
@ -1126,13 +1153,29 @@ void CGameHandler::newTurn()
|
||||
n.res[player][6] += (**j).dailyIncome();
|
||||
}
|
||||
handleTownEvents(*j, n);
|
||||
if ((**j).subID == 2 && vstd::contains((**j).builtBuildings, 26)) // 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 (vstd::contains((**j).builtBuildings, 26))
|
||||
{
|
||||
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::DOUBLE_GROWTH;
|
||||
n.creatureid = 42; //familiar
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((**j).hasBonusOfType (Bonus::DARKNESS))
|
||||
{
|
||||
@ -1148,84 +1191,65 @@ void CGameHandler::newTurn()
|
||||
pickAllowedArtsSet(saa.arts);
|
||||
sendAndApply(&saa);
|
||||
}
|
||||
if (getDate(1) == 7 && getDate(0)>1) //new week (day numbers are confusing, as day was not yet switched)
|
||||
{
|
||||
int monsterid;
|
||||
bool newmonth;
|
||||
int monthType = rand()%100;
|
||||
if(getDate(4) == 28) //new month
|
||||
{
|
||||
newmonth = true;
|
||||
if (monthType < 60) //double growth
|
||||
{
|
||||
//spawn wandering monsters
|
||||
n.specialWeek = NewTurn::DOUBLE_GROWTH;
|
||||
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);
|
||||
|
||||
std::pair<int,int> newMonster(54, VLC->creh->pickRandomMonster(boost::ref(rand)));
|
||||
monsterid = 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)
|
||||
n.specialWeek = NewTurn::NORMAL;
|
||||
else
|
||||
n.specialWeek = NewTurn::PLAGUE;
|
||||
}
|
||||
else //it's a week, but not full month
|
||||
{
|
||||
newmonth = false;
|
||||
if (monthType < 20)
|
||||
{
|
||||
n.specialWeek = NewTurn::BONUS_GROWTH; //+5
|
||||
std::pair<int,int> newMonster (54, VLC->creh->pickRandomMonster(boost::ref(rand)));
|
||||
monsterid = newMonster.second;
|
||||
}
|
||||
}
|
||||
|
||||
InfoWindow iw;
|
||||
int msgid;
|
||||
switch (n.specialWeek)
|
||||
{
|
||||
case NewTurn::DOUBLE_GROWTH:
|
||||
iw.text.addTxt(MetaString::ARRAY_TXT, 131);
|
||||
iw.text.addReplacement(MetaString::CRE_SING_NAMES, monsterid);
|
||||
iw.text.addReplacement(MetaString::CRE_SING_NAMES, monsterid);
|
||||
break;
|
||||
case NewTurn::PLAGUE:
|
||||
iw.text.addTxt(MetaString::ARRAY_TXT, 132);
|
||||
break;
|
||||
case NewTurn::BONUS_GROWTH:
|
||||
iw.text.addTxt(MetaString::ARRAY_TXT, 134);
|
||||
iw.text.addReplacement(MetaString::CRE_SING_NAMES, monsterid);
|
||||
iw.text.addReplacement(MetaString::CRE_SING_NAMES, monsterid);
|
||||
break;
|
||||
default:
|
||||
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++)
|
||||
{
|
||||
iw.player = i->first;
|
||||
sendAndApply(&iw);
|
||||
}
|
||||
}
|
||||
|
||||
sendAndApply(&n);
|
||||
|
||||
if (gs->getDate(1)==1) //first day of week, day has already been changed
|
||||
{
|
||||
NewTurn n2; //just to handle creature growths after bonuses are applied
|
||||
n2.specialWeek = NewTurn::NO_ACTION;
|
||||
n2.day = gs->day;
|
||||
|
||||
for(std::vector<CGTownInstance *>::iterator j = gs->map->towns.begin(); j!=gs->map->towns.end(); j++)//handle towns
|
||||
{
|
||||
ui8 player = (*j)->tempOwner;
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
n2.cres.push_back(sac);
|
||||
}
|
||||
if (gs->getDate(0) > 1)
|
||||
{
|
||||
InfoWindow iw; //new week info
|
||||
int msgid;
|
||||
switch (n.specialWeek)
|
||||
{
|
||||
case NewTurn::DOUBLE_GROWTH:
|
||||
iw.text.addTxt(MetaString::ARRAY_TXT, 131);
|
||||
iw.text.addReplacement(MetaString::CRE_SING_NAMES, n.creatureid);
|
||||
iw.text.addReplacement(MetaString::CRE_SING_NAMES, n.creatureid);
|
||||
break;
|
||||
case NewTurn::PLAGUE:
|
||||
iw.text.addTxt(MetaString::ARRAY_TXT, 132);
|
||||
break;
|
||||
case NewTurn::BONUS_GROWTH:
|
||||
iw.text.addTxt(MetaString::ARRAY_TXT, 134);
|
||||
iw.text.addReplacement(MetaString::CRE_SING_NAMES, n.creatureid);
|
||||
iw.text.addReplacement(MetaString::CRE_SING_NAMES, n.creatureid);
|
||||
break;
|
||||
default:
|
||||
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++)
|
||||
{
|
||||
iw.player = i->first;
|
||||
sendAndApply(&iw);
|
||||
}
|
||||
}
|
||||
|
||||
sendAndApply(&n2);
|
||||
}
|
||||
tlog5 << "Info about turn " << n.day << "has been sent!" << std::endl;
|
||||
handleTimeEvents();
|
||||
//call objects
|
||||
@ -2020,7 +2044,7 @@ void CGameHandler::setOwner(int objid, ui8 owner)
|
||||
{
|
||||
const CGTownInstance * town = getTown(objid);
|
||||
if (town->subID == 5 && vstd::contains(town->builtBuildings, 22))
|
||||
setPortalDwelling(town);
|
||||
setPortalDwelling(town, true, false);
|
||||
|
||||
if (!gs->getPlayer(owner)->towns.size())//player lost last town
|
||||
{
|
||||
|
@ -159,7 +159,7 @@ public:
|
||||
void changeObjPos(int objid, int3 newPos, ui8 flags);
|
||||
void useScholarSkill(si32 hero1, si32 hero2);
|
||||
void heroExchange(si32 hero1, si32 hero2);
|
||||
void setPortalDwelling(const CGTownInstance * town, bool forced);
|
||||
void setPortalDwelling(const CGTownInstance * town, bool forced, bool clear);
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void init(StartInfo *si, int Seed);
|
||||
|
Loading…
x
Reference in New Issue
Block a user