mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* added shots limit
* improved hero hiring * tree of knowledge will give right number of exp points * fixed bug with double showing "getting hit" animation * more logs in initialization of creature handler * added 'vcmiglorfindel' cheat (works as woggandalfwhite) * minor improvements
This commit is contained in:
parent
ee54e5d2e2
commit
248b5e8677
@ -1819,6 +1819,7 @@ void CBattleHex::clickRight(boost::logic::tribool down)
|
||||
pom->defenseBonus = h->primSkills[1];
|
||||
pom->luck = h->getCurrentLuck();
|
||||
pom->morale = h->getCurrentMorale();
|
||||
pom->shotsLeft = myst.shots;
|
||||
}
|
||||
pom->currentHealth = myst.firstHPleft;
|
||||
(new CCreInfoWindow(myst.creature->idNumber,0,myst.amount,pom,boost::function<void()>(),boost::function<void()>(),NULL))
|
||||
|
@ -523,7 +523,7 @@ bool CCallback::battleIsStackMine(int ID)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool CCallback::battleCanShoot(int ID, int dest) //TODO: check arrows amount
|
||||
bool CCallback::battleCanShoot(int ID, int dest)
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
CStack *our=battleGetStackByID(ID), *dst=battleGetStackByPos(dest);
|
||||
@ -532,6 +532,7 @@ bool CCallback::battleCanShoot(int ID, int dest) //TODO: check arrows amount
|
||||
&& our->owner != dst->owner
|
||||
&& dst->alive()
|
||||
&& !gs->curB->isStackBlocked(ID)
|
||||
&& our->shots
|
||||
)
|
||||
return true;
|
||||
return false;
|
||||
|
@ -247,6 +247,62 @@ CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
|
||||
abilities = C->abilities;
|
||||
state.insert(ALIVE);
|
||||
}
|
||||
|
||||
CGHeroInstance* CGameState::HeroesPool::pickHeroFor(bool native, int player, const CTown *town, int notThatOne)
|
||||
{
|
||||
if(player<0 || player>=PLAYER_LIMIT)
|
||||
{
|
||||
tlog1 << "Cannot pick hero for " << town->name << ". Wrong owner!\n";
|
||||
return NULL;
|
||||
}
|
||||
std::vector<CGHeroInstance *> pool;
|
||||
int sum=0, r;
|
||||
if(native)
|
||||
{
|
||||
for(std::map<ui32,CGHeroInstance *>::iterator i=heroesPool.begin(); i!=heroesPool.end(); i++)
|
||||
{
|
||||
if(pavailable[i->first] & 1<<player
|
||||
&& i->second->type->heroType/2 == town->typeID
|
||||
&& i->second->subID != notThatOne
|
||||
)
|
||||
{
|
||||
pool.push_back(i->second);
|
||||
}
|
||||
}
|
||||
if(!pool.size())
|
||||
return pickHeroFor(false,player,town,notThatOne);
|
||||
else
|
||||
return pool[rand()%pool.size()];
|
||||
}
|
||||
else
|
||||
{
|
||||
for(std::map<ui32,CGHeroInstance *>::iterator i=heroesPool.begin(); i!=heroesPool.end(); i++)
|
||||
{
|
||||
if(pavailable[i->first] & 1<<player
|
||||
&& i->second->subID != notThatOne
|
||||
)
|
||||
{
|
||||
pool.push_back(i->second);
|
||||
sum += i->second->type->heroClass->selectionProbability[town->typeID];
|
||||
}
|
||||
}
|
||||
if(!pool.size())
|
||||
{
|
||||
tlog1 << "There are no heroes available for player " << player<<"!\n";
|
||||
return NULL;
|
||||
}
|
||||
r = rand()%sum;
|
||||
for(int i=0; i<pool.size(); i++)
|
||||
{
|
||||
r -= pool[i]->type->heroClass->selectionProbability[town->typeID];
|
||||
if(r<0)
|
||||
return pool[i];
|
||||
}
|
||||
return pool[pool.size()-1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CGameState::applyNL(IPack * pack)
|
||||
{
|
||||
switch(pack->getType())
|
||||
@ -401,6 +457,16 @@ void CGameState::applyNL(IPack * pack)
|
||||
players[rh->player].availableHeroes.clear();
|
||||
players[rh->player].availableHeroes.push_back(hpool.heroesPool[rh->hid1]);
|
||||
players[rh->player].availableHeroes.push_back(hpool.heroesPool[rh->hid2]);
|
||||
if(rh->flags & 1)
|
||||
{
|
||||
hpool.heroesPool[rh->hid1]->army.slots.clear();
|
||||
hpool.heroesPool[rh->hid1]->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[hpool.heroesPool[rh->hid1]->type->refTypeStack[0]],1);
|
||||
}
|
||||
if(rh->flags & 2)
|
||||
{
|
||||
hpool.heroesPool[rh->hid2]->army.slots.clear();
|
||||
hpool.heroesPool[rh->hid2]->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[hpool.heroesPool[rh->hid2]->type->refTypeStack[0]],1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 500:
|
||||
@ -622,8 +688,11 @@ void CGameState::applyNL(IPack * pack)
|
||||
case 3006:
|
||||
{
|
||||
BattleAttack *br = static_cast<BattleAttack*>(pack);
|
||||
CStack *attacker = curB->getStack(br->stackAttacking);
|
||||
if(br->counter())
|
||||
curB->getStack(br->stackAttacking)->counterAttacks--;
|
||||
attacker->counterAttacks--;
|
||||
if(br->shot())
|
||||
attacker->shots--;
|
||||
applyNL(&br->bsa);
|
||||
break;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "tchar_amigaos4.h"
|
||||
#endif
|
||||
|
||||
class CTown;
|
||||
class CScriptCallback;
|
||||
class CCallback;
|
||||
class CLuaCallback;
|
||||
@ -91,6 +92,7 @@ public:
|
||||
ui8 attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
|
||||
ui16 position; //position on battlefield
|
||||
ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1)
|
||||
si16 shots; //how many shots left
|
||||
|
||||
std::set<EAbilities> abilities;
|
||||
std::set<ECombatInfo> state;
|
||||
@ -108,6 +110,7 @@ public:
|
||||
h & id;
|
||||
creature = &VLC->creh->creatures[id];
|
||||
abilities = creature->abilities;
|
||||
shots = creature->shots;
|
||||
}
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -144,10 +147,12 @@ private:
|
||||
std::map<int, CGDefInfo*> villages, forts, capitols; //def-info for town graphics
|
||||
std::vector<ui32> resVals;
|
||||
|
||||
struct HeroesPool
|
||||
struct DLL_EXPORT HeroesPool
|
||||
{
|
||||
std::map<ui32,CGHeroInstance *> heroesPool; //[subID] - heroes available to buy; NULL if not available
|
||||
std::map<ui32,ui8> pavailable; // [subid] -> which players can recruit hero
|
||||
|
||||
CGHeroInstance * pickHeroFor(bool native, int player, const CTown *town, int notThatOne=-1);
|
||||
} hpool; //we have here all heroes available on this map that are not hired
|
||||
|
||||
boost::shared_mutex *mx;
|
||||
|
@ -231,7 +231,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
|
||||
secSkillAreas[g]->hoverText = std::string(bufor);
|
||||
}
|
||||
|
||||
sprintf(bufor, CGI->generaltexth->allTexts[2].substr(1, CGI->generaltexth->allTexts[2].size()-2).c_str(), hero->level, CGI->heroh->reqExp(hero->level+1), hero->exp);
|
||||
sprintf(bufor, CGI->generaltexth->allTexts[2].c_str(), hero->level, CGI->heroh->reqExp(hero->level+1), hero->exp);
|
||||
expArea->text = std::string(bufor);
|
||||
|
||||
sprintf(bufor, CGI->generaltexth->allTexts[205].substr(1, CGI->generaltexth->allTexts[205].size()-2).c_str(), hero->name.c_str(), hero->mana, hero->getPrimSkillLevel(3)*10);
|
||||
|
2
CLua.cpp
2
CLua.cpp
@ -310,7 +310,7 @@ void CVisitableOPH::onNAHeroVisit(int objid, int heroID, bool alreadyVisited)
|
||||
case 102:
|
||||
{
|
||||
const CGHeroInstance *h = cb->getHero(heroID);
|
||||
val = VLC->heroh->reqExp(h->level) + VLC->heroh->reqExp(h->level+val);
|
||||
val = VLC->heroh->reqExp(h->level+val) - VLC->heroh->reqExp(h->level);
|
||||
if(!typeOfTree[objid])
|
||||
{
|
||||
visitors[objid].insert(heroID);
|
||||
|
2
CMT.cpp
2
CMT.cpp
@ -277,7 +277,7 @@ void processCommand(const std::string &message, CClient *&client)
|
||||
boost::filesystem::create_directory("Extracted_txts");
|
||||
tlog0<<"Command accepted. Opening .lod file...\t";
|
||||
CLodHandler * txth = new CLodHandler;
|
||||
txth->init(std::string(DATA_DIR "Data" PATHSEPARATOR "H3bitmap.lod"),"data");
|
||||
txth->init(std::string(DATA_DIR "Data" PATHSEPARATOR "H3bitmap.lod"),"");
|
||||
tlog0<<"done.\nScanning .lod file\n";
|
||||
int curp=0;
|
||||
std::string pattern = ".TXT", pom;
|
||||
|
@ -2086,9 +2086,9 @@ void CPlayerInterface::battleStackAttacked(BattleStackAttacked * bsa)
|
||||
battleInt->displayEffect(bsa->effect, cb->battleGetStackByID(bsa->stackAttacked)->position, cb->battleGetStackByID(bsa->stackAttacked)->attackerOwned);
|
||||
}
|
||||
if(bsa->killed())
|
||||
battleInt->stackKilled(bsa->stackAttacked, bsa->damageAmount, bsa->killedAmount, -1, false);
|
||||
battleInt->stackKilled(bsa->stackAttacked, bsa->damageAmount, bsa->killedAmount, LOCPLINT->curAction->stackNumber, LOCPLINT->curAction->actionType==7 );
|
||||
else
|
||||
battleInt->stackIsAttacked(bsa->stackAttacked, bsa->damageAmount, bsa->killedAmount, -1, false);
|
||||
battleInt->stackIsAttacked(bsa->stackAttacked, bsa->damageAmount, bsa->killedAmount, LOCPLINT->curAction->stackNumber, LOCPLINT->curAction->actionType==7);
|
||||
}
|
||||
void CPlayerInterface::battleAttack(BattleAttack *ba)
|
||||
{
|
||||
@ -3129,7 +3129,7 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState
|
||||
anim = new CCreaturePic(c);
|
||||
if(!type) anim->anim->setType(1);
|
||||
|
||||
char pom[25];int hlp=0;
|
||||
char pom[75];int hlp=0;
|
||||
|
||||
if(creatureCount)
|
||||
{
|
||||
@ -3169,7 +3169,10 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState
|
||||
if(c->shots)
|
||||
{
|
||||
printAt(CGI->generaltexth->allTexts[198],155,86,GEOR13,zwykly,bitmap);
|
||||
SDL_itoa(c->shots,pom,10);
|
||||
if(State)
|
||||
sprintf(pom,"%d(%d)",c->shots,State->shotsLeft);
|
||||
else
|
||||
SDL_itoa(c->shots,pom,10);
|
||||
printToWR(pom,276,99,GEOR13,zwykly,bitmap);
|
||||
}
|
||||
|
||||
@ -3930,8 +3933,10 @@ void CTavernWindow::show(SDL_Surface * to)
|
||||
|
||||
HeroPortrait *sel = selected ? &h2 : &h1;
|
||||
char descr[300];
|
||||
int artifs = sel->h->artifWorn.size()+sel->h->artifacts.size() - 1; //artifacts amount; - 1 is for catapult
|
||||
if(vstd::contains(sel->h->artifWorn,0)) artifs--; //spellbook doesn't count neither
|
||||
int artifs = sel->h->artifWorn.size()+sel->h->artifacts.size();
|
||||
for(int i=13; i<=17; i++) //war machines and spellbook doesn't count
|
||||
if(vstd::contains(sel->h->artifWorn,i))
|
||||
artifs--;
|
||||
sprintf_s(descr,300,CGI->generaltexth->allTexts[215].c_str(),
|
||||
sel->h->name.c_str(),sel->h->level,sel->h->type->heroClass->name.c_str(),artifs);
|
||||
printAtMiddleWB(descr,pos.x+146,pos.y+389,GEOR13,40,zwykly,screen);
|
||||
@ -3984,4 +3989,4 @@ CTavernWindow::HeroPortrait::HeroPortrait(int &sel, int id, int x, int y, const
|
||||
void CTavernWindow::HeroPortrait::show(SDL_Surface * to)
|
||||
{
|
||||
blitAt(graphics->portraitLarge[h->subID],pos);
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ si32 CCreature::maxAmount(const std::vector<si32> &res) const //how many creatur
|
||||
void CCreatureHandler::loadCreatures()
|
||||
{
|
||||
notUsedMonsters += 122,124,126,128,145,146,147,148,149,160,161,162,163,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191;
|
||||
tlog5 << "\t\tReading ZCRTRAIT.TXT" << std::endl;
|
||||
std::string buf = bitmaph->getTextFile("ZCRTRAIT.TXT");
|
||||
int andame = buf.size();
|
||||
int i=0; //buf iterator
|
||||
@ -319,21 +320,11 @@ void CCreatureHandler::loadCreatures()
|
||||
if(ncre.nameSing!=std::string("") && ncre.namePl!=std::string(""))
|
||||
{
|
||||
ncre.idNumber = creatures.size();
|
||||
ncre.isDefinite = true;
|
||||
creatures.push_back(ncre);
|
||||
}
|
||||
}
|
||||
for(int bb=1; bb<8; ++bb)
|
||||
{
|
||||
CCreature ncre;
|
||||
ncre.isDefinite = false;
|
||||
ncre.indefLevel = bb;
|
||||
ncre.indefUpgraded = false;
|
||||
creatures.push_back(ncre);
|
||||
ncre.indefUpgraded = true;
|
||||
creatures.push_back(ncre);
|
||||
}
|
||||
|
||||
tlog5 << "\t\tReading config/crerefnam.txt" << std::endl;
|
||||
//loading reference names
|
||||
std::ifstream ifs("config/crerefnam.txt");
|
||||
int tempi;
|
||||
@ -350,6 +341,8 @@ void CCreatureHandler::loadCreatures()
|
||||
ifs.clear();
|
||||
for(int i=1;i<=10;i++)
|
||||
levelCreatures.insert(std::pair<int,std::vector<CCreature*> >(i,std::vector<CCreature*>()));
|
||||
|
||||
tlog5 << "\t\tReading config/monsters.txt" << std::endl;
|
||||
ifs.open("config/monsters.txt");
|
||||
{
|
||||
while(!ifs.eof())
|
||||
@ -366,6 +359,7 @@ void CCreatureHandler::loadCreatures()
|
||||
ifs.close();
|
||||
ifs.clear();
|
||||
|
||||
tlog5 << "\t\tReading config/cr_factions.txt" << std::endl;
|
||||
ifs.open("config/cr_factions.txt");
|
||||
while(!ifs.eof())
|
||||
{
|
||||
@ -376,6 +370,7 @@ void CCreatureHandler::loadCreatures()
|
||||
ifs.close();
|
||||
ifs.clear();
|
||||
|
||||
tlog5 << "\t\tReading config/cr_upgrade_list.txt" << std::endl;
|
||||
ifs.open("config/cr_upgrade_list.txt");
|
||||
while(!ifs.eof())
|
||||
{
|
||||
@ -387,6 +382,7 @@ void CCreatureHandler::loadCreatures()
|
||||
ifs.clear();
|
||||
|
||||
//loading unit animation def names
|
||||
tlog5 << "\t\tReading config/CREDEFS.TXT" << std::endl;
|
||||
std::ifstream inp("config/CREDEFS.TXT", std::ios::in | std::ios::binary); //this file is not in lod
|
||||
inp.seekg(0,std::ios::end); // na koniec
|
||||
int andame2 = inp.tellg(); // read length
|
||||
@ -395,11 +391,7 @@ void CCreatureHandler::loadCreatures()
|
||||
inp.read((char*)bufor, andame2); // read map file to buffer
|
||||
inp.close();
|
||||
buf = std::string(bufor);
|
||||
#ifndef __GNUC__
|
||||
delete [andame2] bufor;
|
||||
#else
|
||||
delete [] bufor;
|
||||
#endif
|
||||
|
||||
i = 0; //buf iterator
|
||||
hmcr = 0;
|
||||
@ -409,8 +401,10 @@ void CCreatureHandler::loadCreatures()
|
||||
break;
|
||||
}
|
||||
i+=2;
|
||||
for(int s=0; s<creatures.size()-16; ++s)
|
||||
tlog5 << "We have "<<creatures.size() << " creatures\n";
|
||||
for(int s=0; s<creatures.size(); ++s)
|
||||
{
|
||||
//tlog5 <<"\t\t\t" << s <<". Reading defname. \n";
|
||||
int befi=i;
|
||||
std::string rub;
|
||||
for(i; i<andame2; ++i)
|
||||
@ -430,10 +424,12 @@ void CCreatureHandler::loadCreatures()
|
||||
std::string defName = buf.substr(befi, i-befi);
|
||||
creatures[s].animDefName = defName;
|
||||
}
|
||||
tlog5 << "\t\tReading CRANIM.TXT.txt" << std::endl;
|
||||
loadAnimationInfo();
|
||||
|
||||
//loading id to projectile mapping
|
||||
|
||||
tlog5 << "\t\tReading config/cr_shots.txt" << std::endl;
|
||||
std::ifstream inp2("config" PATHSEPARATOR "cr_shots.txt", std::ios::in | std::ios::binary); //this file is not in lod
|
||||
char dump [200];
|
||||
inp2.getline(dump, 200);
|
||||
@ -474,8 +470,9 @@ void CCreatureHandler::loadAnimationInfo()
|
||||
break;
|
||||
}
|
||||
i+=2;
|
||||
for(int dd=0; dd<creatures.size()-16; ++dd)
|
||||
for(int dd=0; dd<creatures.size(); ++dd)
|
||||
{
|
||||
//tlog5 << "\t\t\tReading animation info for creature " << dd << std::endl;
|
||||
loadUnitAnimInfo(creatures[dd], buf, i);
|
||||
}
|
||||
return;
|
||||
|
@ -32,13 +32,6 @@ public:
|
||||
int troopCountLocationOffset, attackClimaxFrame;
|
||||
///end of anim info
|
||||
|
||||
//for some types of towns
|
||||
bool isDefinite; //if the creature type is wotn dependent, it should be true
|
||||
int indefLevel; //only if indefinite
|
||||
bool indefUpgraded; //onlu if inddefinite
|
||||
|
||||
//TODO - zdolnoœci (abilities) - na typie wyliczeniowym czy czymœ - albo lepiej secie czegoœ
|
||||
|
||||
bool isDoubleWide() const; //returns true if unit is double wide on battlefield
|
||||
bool isFlying() const; //returns true if it is a flying unit
|
||||
bool isShooting() const; //returns true if unit can shoot
|
||||
|
@ -143,12 +143,13 @@ struct FoWChange : public CPack<FoWChange> //112
|
||||
|
||||
struct SetAvailableHeroes : public CPack<SetAvailableHeroes> //113
|
||||
{
|
||||
SetAvailableHeroes(){type = 113;};
|
||||
SetAvailableHeroes(){type = 113;flags=0;};
|
||||
ui8 player;
|
||||
ui32 hid1, hid2;
|
||||
ui8 flags; //1 - reset army of hero1; 2 - reset army of hero 2
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & player & hid1 & hid2;
|
||||
h & player & hid1 & hid2 & flags;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -987,6 +987,11 @@ upgend:
|
||||
fc.tiles.insert(int3(i,j,k));
|
||||
sendAndApply(&fc);
|
||||
}
|
||||
else if(message == "vcmiglorfindel")
|
||||
{
|
||||
CGHeroInstance *hero = gs->getHero(gs->players[*players.begin()].currentSelection);
|
||||
changePrimSkill(hero->id,4,VLC->heroh->reqExp(hero->level+1) - VLC->heroh->reqExp(hero->level));
|
||||
}
|
||||
else
|
||||
cheated = false;
|
||||
if(cheated)
|
||||
@ -1019,12 +1024,26 @@ upgend:
|
||||
)
|
||||
break;
|
||||
CGHeroInstance *nh = gs->players[t->tempOwner].availableHeroes[hid];
|
||||
|
||||
HeroRecruited hr;
|
||||
hr.tid = tid;
|
||||
hr.hid = nh->subID;
|
||||
hr.player = t->tempOwner;
|
||||
hr.tile = t->pos - int3(1,0,0);
|
||||
sendAndApply(&hr);
|
||||
|
||||
SetAvailableHeroes sah;
|
||||
(hid ? sah.hid2 : sah.hid1) = gs->hpool.pickHeroFor(false,t->tempOwner,t->town)->subID;
|
||||
(hid ? sah.hid1 : sah.hid2) = gs->players[t->tempOwner].availableHeroes[!hid]->subID;
|
||||
sah.player = t->tempOwner;
|
||||
sah.flags = hid+1;
|
||||
sendAndApply(&sah);
|
||||
|
||||
SetResource sr;
|
||||
sr.player = t->tempOwner;
|
||||
sr.resid = 6;
|
||||
sr.val = gs->players[t->tempOwner].resources[6] - 2500;
|
||||
sendAndApply(&sr);
|
||||
break;
|
||||
}
|
||||
case 2001:
|
||||
@ -1075,8 +1094,9 @@ upgend:
|
||||
CStack *curStack = gs->curB->getStack(ba.stackNumber),
|
||||
*stackAtEnd = gs->curB->getStackT(ba.additionalInfo);
|
||||
|
||||
if((curStack->position != ba.destinationTile) || //we wasn't able to reach destination tile
|
||||
(BattleInfo::mutualPosition(ba.destinationTile,ba.additionalInfo)<0) ) //destination tile is not neighbouring with enemy stack
|
||||
if( curStack->position != ba.destinationTile //we wasn't able to reach destination tile
|
||||
|| BattleInfo::mutualPosition(ba.destinationTile,ba.additionalInfo) < 0 //destination tile is not neighbouring with enemy stack
|
||||
)
|
||||
return;
|
||||
|
||||
BattleAttack bat;
|
||||
@ -1105,25 +1125,33 @@ upgend:
|
||||
}
|
||||
case 7: //shoot
|
||||
{
|
||||
//TODO: check arrows count
|
||||
//TODO: check if stack isn't blocked by enemy
|
||||
|
||||
sendAndApply(&StartAction(ba)); //start shooting
|
||||
CStack *curStack = gs->curB->getStack(ba.stackNumber),
|
||||
*destStack= gs->curB->getStackT(ba.destinationTile);
|
||||
if(!curStack //our stack exists
|
||||
|| !destStack //there is a stack at destination tile
|
||||
|| !curStack->shots //stack has shots
|
||||
|| gs->curB->isStackBlocked(curStack->ID) //we are not blocked
|
||||
|| !vstd::contains(curStack->abilities,SHOOTER) //our stack is shooting unit
|
||||
)
|
||||
break;
|
||||
|
||||
sendAndApply(&StartAction(ba)); //start shooting
|
||||
|
||||
BattleAttack bat;
|
||||
prepareAttack(bat,curStack,destStack);
|
||||
bat.flags |= 1;
|
||||
sendAndApply(&bat);
|
||||
|
||||
if(vstd::contains(curStack->abilities,TWICE_ATTACK)
|
||||
&& curStack->alive())
|
||||
if(vstd::contains(curStack->abilities,TWICE_ATTACK) //if unit shots twice let's make another shot
|
||||
&& curStack->alive()
|
||||
&& destStack->alive()
|
||||
&& curStack->shots
|
||||
)
|
||||
{
|
||||
prepareAttack(bat,curStack,destStack);
|
||||
sendAndApply(&bat);
|
||||
}
|
||||
|
||||
sendAndApply(&bat);
|
||||
sendDataToClients(ui16(3008)); //end shooting
|
||||
break;
|
||||
}
|
||||
@ -1335,25 +1363,15 @@ void CGameHandler::newTurn()
|
||||
|
||||
for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
|
||||
{
|
||||
if(i->first == 255) continue;
|
||||
if(gs->getDate(1)==7) //first day of week - new heroes in tavern
|
||||
{
|
||||
SetAvailableHeroes sah;
|
||||
sah.player = i->first;
|
||||
int r;
|
||||
if(!gs->hpool.heroesPool.size()) return;
|
||||
for(int a=0;a<2;a++)
|
||||
{
|
||||
r = rand() % gs->hpool.heroesPool.size();
|
||||
std::map<ui32,CGHeroInstance *>::iterator ch = gs->hpool.heroesPool.begin();
|
||||
while(r--) ch++;
|
||||
if(a) sah.hid2 = ch->first;
|
||||
else sah.hid1 = ch->first;
|
||||
}
|
||||
//TODO: - will fail when there are not enough available heroes
|
||||
sah.hid1 = gs->hpool.pickHeroFor(true,i->first,&VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(i->first).castle])->subID;
|
||||
sah.hid2 = gs->hpool.pickHeroFor(false,i->first,&VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(i->first).castle],sah.hid1)->subID;
|
||||
sendAndApply(&sah);
|
||||
//TODO: guarantee that heroes are different
|
||||
//TODO: first hero should be from initial player town
|
||||
//TODO: use selectionProbability from CHeroClass
|
||||
//int town = gs->scenarioOps->getIthPlayersSettings(i->first).castle;
|
||||
}
|
||||
if(i->first>=PLAYER_LIMIT) continue;
|
||||
SetResources r;
|
||||
@ -1369,7 +1387,7 @@ void CGameHandler::newTurn()
|
||||
hth.mana = std::max(h->mana,std::min(h->mana+1+h->getSecSkillLevel(8), h->manaLimit())); //hero regains 1 mana point + mysticism lvel
|
||||
n.heroes.insert(hth);
|
||||
|
||||
switch(h->getSecSkillLevel(13)) //handle estates - give gols
|
||||
switch(h->getSecSkillLevel(13)) //handle estates - give gold
|
||||
{
|
||||
case 1: //basic
|
||||
r.res[6] += 125;
|
||||
|
Loading…
Reference in New Issue
Block a user