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/find.hpp>
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
#include "../lib/VCMI_Lib.h"
|
#include "../lib/VCMI_Lib.h"
|
||||||
|
#include "../lib/CGameState.h"
|
||||||
|
|
||||||
using namespace boost::assign;
|
using namespace boost::assign;
|
||||||
extern CLodHandler * bitmaph;
|
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);
|
Bonus added(Bonus::PERMANENT, type, Bonus::CREATURE_ABILITY, val, idNumber, subtype, Bonus::BASE_NUMBER);
|
||||||
bonuses.push_back(added);
|
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
|
bool CCreature::isMyUpgrade(const CCreature *anotherCre) const
|
||||||
{
|
{
|
||||||
//TODO upgrade of upgrade?
|
//TODO upgrade of upgrade?
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "CSoundBase.h"
|
#include "CSoundBase.h"
|
||||||
#include "../lib/HeroBonus.h"
|
#include "../lib/HeroBonus.h"
|
||||||
|
#include "../lib/CGameState.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CCreatureHandler.h, part of VCMI engine
|
* CCreatureHandler.h, part of VCMI engine
|
||||||
@ -21,6 +22,7 @@
|
|||||||
|
|
||||||
class CLodHandler;
|
class CLodHandler;
|
||||||
class CCreatureHandler;
|
class CCreatureHandler;
|
||||||
|
class CCreature;
|
||||||
|
|
||||||
class DLL_EXPORT CCreature : public CBonusSystemNode
|
class DLL_EXPORT CCreature : public CBonusSystemNode
|
||||||
{
|
{
|
||||||
@ -60,7 +62,7 @@ public:
|
|||||||
ui32 getMaxDamage() const;
|
ui32 getMaxDamage() const;
|
||||||
|
|
||||||
void addBonus(int val, int type, int subtype = -1);
|
void addBonus(int val, int type, int subtype = -1);
|
||||||
|
void getParents(TNodes &out, const CBonusSystemNode *root /*= NULL*/) const;
|
||||||
|
|
||||||
template<typename RanGen>
|
template<typename RanGen>
|
||||||
int getRandomAmount(RanGen &ranGen)
|
int getRandomAmount(RanGen &ranGen)
|
||||||
@ -97,6 +99,7 @@ public:
|
|||||||
class DLL_EXPORT CCreatureHandler
|
class DLL_EXPORT CCreatureHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CBonusSystemNode *globalEffects;
|
||||||
std::set<int> notUsedMonsters;
|
std::set<int> notUsedMonsters;
|
||||||
std::vector<CCreature*> creatures; //creature ID -> creature info
|
std::vector<CCreature*> creatures; //creature ID -> creature info
|
||||||
std::map<int,std::vector<CCreature*> > levelCreatures; //level -> list of creatures
|
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)
|
//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature)
|
||||||
h & notUsedMonsters & creatures & nameToID & idToProjectile & idToProjectileSpin & factionToTurretCreature;
|
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())
|
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*/)
|
if(false /*accumulate creatures*/)
|
||||||
sac.creatures[i].first += VLC->creh->creatures[creatures[i].second[0]]->growth;
|
sac.creatures[i].first += amount;
|
||||||
else
|
else
|
||||||
sac.creatures[i].first = VLC->creh->creatures[creatures[i].second[0]]->growth;
|
sac.creatures[i].first = amount;
|
||||||
change = true;
|
change = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1923,8 +1925,9 @@ int CGTownInstance::creatureGrowth(const int & level) const
|
|||||||
{
|
{
|
||||||
if (level<0 || level >=CREATURES_PER_TOWN)
|
if (level<0 || level >=CREATURES_PER_TOWN)
|
||||||
return 0;
|
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())
|
switch(fortLevel())
|
||||||
{
|
{
|
||||||
case 3:
|
case 3:
|
||||||
@ -1932,29 +1935,33 @@ int CGTownInstance::creatureGrowth(const int & level) const
|
|||||||
case 2:
|
case 2:
|
||||||
ret*=(1.5); break;
|
ret*=(1.5); break;
|
||||||
}
|
}
|
||||||
|
ret *= (1 + VLC->creh->creatures[creid]->valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100); // double growth or plague
|
||||||
if(tempOwner != NEUTRAL_PLAYER)
|
if(tempOwner != NEUTRAL_PLAYER)
|
||||||
{
|
{
|
||||||
ret *= (1 + cb->gameState()->players[tempOwner].valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100); //Statue of Legion
|
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)
|
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
|
{ //+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;
|
++ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(getHordeLevel(0)==level)
|
if(getHordeLevel(0)==level)
|
||||||
if((builtBuildings.find(18)!=builtBuildings.end()) || (builtBuildings.find(19)!=builtBuildings.end()))
|
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(getHordeLevel(1)==level)
|
||||||
if((builtBuildings.find(24)!=builtBuildings.end()) || (builtBuildings.find(25)!=builtBuildings.end()))
|
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.
|
//support for legs of legion etc.
|
||||||
if(garrisonHero)
|
if(garrisonHero)
|
||||||
ret += garrisonHero->valOfBonuses(Bonus::CREATURE_GROWTH, level);
|
ret += garrisonHero->valOfBonuses(Bonus::CREATURE_GROWTH, level);
|
||||||
if(visitingHero)
|
if(visitingHero)
|
||||||
ret += visitingHero->valOfBonuses(Bonus::CREATURE_GROWTH, level);
|
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
|
if(builtBuildings.find(26)!=builtBuildings.end()) //grail - +50% to ALL growth
|
||||||
ret*=1.5;
|
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
|
return ret;//check CCastleInterface.cpp->CCastleInterface::CCreaInfo::clickRight if this one will be modified
|
||||||
}
|
}
|
||||||
int CGTownInstance::dailyIncome() const
|
int CGTownInstance::dailyIncome() const
|
||||||
@ -6518,11 +6525,11 @@ void CArmedInstance::randomizeArmy(int type)
|
|||||||
void CArmedInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
|
void CArmedInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
|
||||||
{
|
{
|
||||||
const PlayerState *p = cb->getPlayerState(tempOwner);
|
const PlayerState *p = cb->getPlayerState(tempOwner);
|
||||||
if(!p) //occurs when initializing starting hero and heroes from the pool, also for neutral armed objects
|
if(p)
|
||||||
out.insert(&cb->gameState()->globalEffects);
|
|
||||||
else
|
|
||||||
out.insert(p); //hero always inherits bonuses from player
|
out.insert(p); //hero always inherits bonuses from player
|
||||||
|
|
||||||
|
out.insert(&cb->gameState()->globalEffects); //global effect are always active I believe
|
||||||
|
|
||||||
if(battle)
|
if(battle)
|
||||||
out.insert(battle);
|
out.insert(battle);
|
||||||
}
|
}
|
||||||
|
@ -1202,6 +1202,7 @@ CGameState::~CGameState()
|
|||||||
|
|
||||||
void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
||||||
{
|
{
|
||||||
|
VLC->creh->globalEffects = &globalEffects;
|
||||||
struct HLP
|
struct HLP
|
||||||
{
|
{
|
||||||
//it's assumed that given hero should receive the bonus
|
//it's assumed that given hero should receive the bonus
|
||||||
|
@ -64,6 +64,54 @@ int DLL_EXPORT BonusList::totalValue() const
|
|||||||
return valFirst;
|
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
|
const DLL_EXPORT Bonus * BonusList::getFirst(const CSelector &selector) const
|
||||||
{
|
{
|
||||||
for (const_iterator i = begin(); i != end(); i++)
|
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
|
bool CCreatureTypeLimiter::limit(const Bonus &b, const CBonusSystemNode &node) const
|
||||||
{
|
{
|
||||||
if(node.nodeType != CBonusSystemNode::STACK)
|
switch (node.nodeType)
|
||||||
return true;
|
{
|
||||||
|
case CBonusSystemNode::STACK:
|
||||||
const CCreature *c = (static_cast<const CStackInstance *>(&node))->type;
|
{
|
||||||
|
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)
|
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*/)
|
CCreatureTypeLimiter::CCreatureTypeLimiter(const CCreature &Creature, ui8 IncludeUpgrades /*= true*/)
|
||||||
:creature(&Creature), includeUpgrades(IncludeUpgrades)
|
:creature(&Creature), includeUpgrades(IncludeUpgrades)
|
||||||
|
@ -69,7 +69,7 @@ namespace PrimarySkill
|
|||||||
BONUS_NAME(WATER_SPELLS) \
|
BONUS_NAME(WATER_SPELLS) \
|
||||||
BONUS_NAME(EARTH_SPELLS) \
|
BONUS_NAME(EARTH_SPELLS) \
|
||||||
BONUS_NAME(GENERATE_RESOURCE) /*daily value, uses subtype (resource type)*/ \
|
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(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(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*/ \
|
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,
|
SECONDARY_SKILL,
|
||||||
HERO_SPECIAL,
|
HERO_SPECIAL,
|
||||||
ARMY,
|
ARMY,
|
||||||
CAMPAIGN_BONUS
|
CAMPAIGN_BONUS,
|
||||||
|
SPECIAL_WEEK
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LimitEffect
|
enum LimitEffect
|
||||||
@ -298,6 +299,7 @@ class BonusList : public std::list<Bonus>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int DLL_EXPORT totalValue() const; //subtype -> subtype of bonus, if -1 then any
|
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 CBonusSystemNode *source = NULL) const;
|
||||||
void DLL_EXPORT getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, 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;
|
void DLL_EXPORT getModifiersWDescr(TModDescr &out) const;
|
||||||
@ -379,7 +381,7 @@ public:
|
|||||||
|
|
||||||
enum ENodeTypes
|
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
|
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);
|
DLL_EXPORT void applyGs(CGameState *gs);
|
||||||
|
|
||||||
@ -711,6 +711,7 @@ struct NewTurn : public CPackForClient //101
|
|||||||
ui32 day;
|
ui32 day;
|
||||||
bool resetBuilded;
|
bool resetBuilded;
|
||||||
weekType specialWeek;
|
weekType specialWeek;
|
||||||
|
TQuantity creatureid; //for creature weeks
|
||||||
|
|
||||||
NewTurn(){type = 101;};
|
NewTurn(){type = 101;};
|
||||||
|
|
||||||
|
@ -632,10 +632,42 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
|
|||||||
BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
|
BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
|
||||||
h->bonuses.remove_if(Bonus::OneDay);
|
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)
|
BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
|
||||||
h->bonuses.remove_if(Bonus::OneWeek);
|
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
|
//count days without town
|
||||||
|
@ -965,7 +965,7 @@ static bool evntCmp(const CMapEvent *a, const CMapEvent *b)
|
|||||||
return *a < *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
|
{// 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
|
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 creapos = rand()%dwellings[dwellpos]->creatures.size();//for multi-creature dwellings like Golem Factory
|
||||||
ui32 creature = dwellings[dwellpos]->creatures[creapos].second[0];
|
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);
|
ssi.creatures[CREATURES_PER_TOWN].second.push_back(creature);
|
||||||
sendAndApply(&ssi);
|
sendAndApply(&ssi);
|
||||||
}
|
}
|
||||||
@ -998,10 +1001,60 @@ void CGameHandler::newTurn()
|
|||||||
NewTurn n;
|
NewTurn n;
|
||||||
n.day = gs->day + 1;
|
n.day = gs->day + 1;
|
||||||
n.resetBuilded = true;
|
n.resetBuilded = true;
|
||||||
|
bool newmonth = false;
|
||||||
|
|
||||||
std::map<ui8, si32> hadGold;//starting gold - for buildings like dwarven treasury
|
std::map<ui8, si32> hadGold;//starting gold - for buildings like dwarven treasury
|
||||||
srand(time(NULL));
|
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;
|
std::map<ui32,CGHeroInstance *> pool = gs->hpool.heroesPool;
|
||||||
|
|
||||||
for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
|
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
|
if(gs->day) //not first day
|
||||||
{
|
{
|
||||||
switch(h->getSecSkillLevel(13)) //handle estates - give gold
|
n.res[i->first][6] += h->valOfBonuses(Selector::typeSybtype(Bonus::SECONDARY_SKILL, 13)); //estates
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
for (int k = 0; k < RESOURCE_QUANTITY; k++)
|
for (int k = 0; k < RESOURCE_QUANTITY; k++)
|
||||||
{
|
{
|
||||||
n.res[i->first][k] += h->valOfBonuses(Bonus::GENERATE_RESOURCE, k);
|
n.res[i->first][k] += h->valOfBonuses(Bonus::GENERATE_RESOURCE, k);
|
||||||
}
|
}
|
||||||
//TODO player bonuses
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//n.res.push_back(r);
|
//n.res.push_back(r);
|
||||||
@ -1088,24 +1129,10 @@ void CGameHandler::newTurn()
|
|||||||
if(gs->getDate(1)==7) //first day of week
|
if(gs->getDate(1)==7) //first day of week
|
||||||
{
|
{
|
||||||
if ((*j)->subID == 5 && vstd::contains((*j)->builtBuildings, 22))
|
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
|
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
|
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
|
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();
|
n.res[player][6] += (**j).dailyIncome();
|
||||||
}
|
}
|
||||||
handleTownEvents(*j, n);
|
handleTownEvents(*j, n);
|
||||||
if ((**j).subID == 2 && vstd::contains((**j).builtBuildings, 26)) // Skyship, probably easier to handle same as Veil of darkness
|
if (vstd::contains((**j).builtBuildings, 26))
|
||||||
{ //do it every new day after veils apply
|
{
|
||||||
FoWChange fw;
|
switch ((**j).subID)
|
||||||
fw.mode = 1;
|
{
|
||||||
fw.player = player;
|
case 2: // Skyship, probably easier to handle same as Veil of darkness
|
||||||
getAllTiles(fw.tiles, player, -1, 0);
|
{ //do it every new day after veils apply
|
||||||
sendAndApply (&fw);
|
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))
|
if ((**j).hasBonusOfType (Bonus::DARKNESS))
|
||||||
{
|
{
|
||||||
@ -1148,84 +1191,65 @@ void CGameHandler::newTurn()
|
|||||||
pickAllowedArtsSet(saa.arts);
|
pickAllowedArtsSet(saa.arts);
|
||||||
sendAndApply(&saa);
|
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);
|
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;
|
tlog5 << "Info about turn " << n.day << "has been sent!" << std::endl;
|
||||||
handleTimeEvents();
|
handleTimeEvents();
|
||||||
//call objects
|
//call objects
|
||||||
@ -2020,7 +2044,7 @@ void CGameHandler::setOwner(int objid, ui8 owner)
|
|||||||
{
|
{
|
||||||
const CGTownInstance * town = getTown(objid);
|
const CGTownInstance * town = getTown(objid);
|
||||||
if (town->subID == 5 && vstd::contains(town->builtBuildings, 22))
|
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
|
if (!gs->getPlayer(owner)->towns.size())//player lost last town
|
||||||
{
|
{
|
||||||
|
@ -159,7 +159,7 @@ public:
|
|||||||
void changeObjPos(int objid, int3 newPos, ui8 flags);
|
void changeObjPos(int objid, int3 newPos, ui8 flags);
|
||||||
void useScholarSkill(si32 hero1, si32 hero2);
|
void useScholarSkill(si32 hero1, si32 hero2);
|
||||||
void heroExchange(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);
|
void init(StartInfo *si, int Seed);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user