mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* artifact manipulation in exchange window works (without switching artifacts between different heroes)
* support for 3 new artifacts: - Ring of Vitality - Ring of Life - Vial of Lifeblood * restructures creature ability preparing (creature abilities are now loaded from cr_abils.txt file). It needs further work - all changes in abilities should be moved from CCreatureHandler.cpp to cr_abils.txt as it's done in this commit (I hope it's clear how it should be done as there is an example)
This commit is contained in:
parent
9093320da8
commit
85eb5c7eb9
@ -2594,6 +2594,7 @@ void CBattleHex::clickRight(boost::logic::tribool down)
|
||||
pom->luck = myst.Luck();
|
||||
pom->morale = myst.Morale();
|
||||
pom->speedBonus = myst.Speed() - myst.creature->speed;
|
||||
pom->healthBonus = myst.MaxHealth() - myst.creature->hitPoints;
|
||||
|
||||
pom->shotsLeft = myst.shots;
|
||||
for(int vb=0; vb<myst.effects.size(); ++vb)
|
||||
|
@ -1520,6 +1520,20 @@ void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
|
||||
adventureInt->heroWindow->setHero(adventureInt->heroWindow->curHero);
|
||||
adventureInt->heroWindow->activate();
|
||||
}
|
||||
CExchangeWindow* cew = dynamic_cast<CExchangeWindow*>(listInt.front());
|
||||
if(cew) //exchange window is open
|
||||
{
|
||||
cew->deactivate();
|
||||
for(int g=0; g<ARRAY_COUNT(cew->heroInst); ++g)
|
||||
{
|
||||
if(cew->heroInst[g] == hero)
|
||||
{
|
||||
cew->artifs[g]->setHero(hero);
|
||||
}
|
||||
}
|
||||
cew->prepareBackground();
|
||||
cew->activate();
|
||||
}
|
||||
}
|
||||
|
||||
void CPlayerInterface::updateWater()
|
||||
|
@ -2053,7 +2053,7 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState
|
||||
|
||||
//health
|
||||
printAt(CGI->generaltexth->allTexts[388],155,124,GEOR13,zwykly,bitmap);
|
||||
SDL_itoa(c->hitPoints,pom,10);
|
||||
SDL_itoa(c->hitPoints + State->healthBonus,pom,10);
|
||||
printToWR(pom,276,137,GEOR13,zwykly,bitmap);
|
||||
|
||||
//remaining health
|
||||
@ -3766,17 +3766,10 @@ void CExchangeWindow::questlog(int whichHero)
|
||||
{
|
||||
}
|
||||
|
||||
CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) //c-tor
|
||||
void CExchangeWindow::prepareBackground()
|
||||
{
|
||||
char bufor[400];
|
||||
|
||||
heroInst[0] = LOCPLINT->cb->getHeroInfo(hero1, 2);
|
||||
heroInst[1] = LOCPLINT->cb->getHeroInfo(hero2, 2);
|
||||
|
||||
artifs[0] = new CArtifactsOfHero(genRect(600, 800, -334, 150));
|
||||
artifs[0]->setHero(heroInst[0]);
|
||||
artifs[1] = new CArtifactsOfHero(genRect(600, 800, 96, 150));
|
||||
artifs[1]->setHero(heroInst[1]);
|
||||
if(bg)
|
||||
SDL_FreeSurface(bg);
|
||||
|
||||
SDL_Surface * bgtemp; //loaded as 8bpp surface
|
||||
bgtemp = BitmapHandler::loadBitmap("TRADE2.BMP");
|
||||
@ -3797,14 +3790,6 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) //c-tor
|
||||
{
|
||||
//graphics
|
||||
blitAt(skilldef->ourImages[g].bitmap, genRect(32, 32, 385, 19 + 36 * g), bg);
|
||||
|
||||
//primary skill's clickable areas
|
||||
primSkillAreas.push_back(new LRClickableAreaWTextComp());
|
||||
primSkillAreas[g]->pos = genRect(32, 32, pos.x+385, pos.y + 19 + 36 * g);
|
||||
primSkillAreas[g]->text = CGI->generaltexth->arraytxt[2+g];
|
||||
primSkillAreas[g]->type = g;
|
||||
primSkillAreas[g]->bonus = -1;
|
||||
primSkillAreas[g]->baseType = 0;
|
||||
}
|
||||
|
||||
CDefHandler * un32 = CDefHandler::giveDef("UN32.DEF");
|
||||
@ -3825,6 +3810,62 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) //c-tor
|
||||
blitAt(graphics->abils32->ourImages[heroInst[b]->secSkills[m].first * 3 + heroInst[b]->secSkills[m].second + 2].bitmap, genRect(32, 32, pos.x + 32 + 36 * m + 454 * b, pos.y + 88), bg);
|
||||
}
|
||||
|
||||
//hero's specialty
|
||||
blitAt(un32->ourImages[heroInst[b]->subID].bitmap, 67 + 490*b, 45, bg);
|
||||
|
||||
//experience
|
||||
blitAt(skilldef->ourImages[4].bitmap, 103 + 490*b, 45, bg);
|
||||
printAtMiddle( makeNumberShort(heroInst[b]->exp), 119 + 490*b, 71, GEOR13, zwykly, bg );
|
||||
|
||||
//mana points
|
||||
blitAt(skilldef->ourImages[5].bitmap, 139 + 490*b, 45, bg);
|
||||
printAtMiddle( makeNumberShort(heroInst[b]->mana), 155 + 490*b, 71, GEOR13, zwykly, bg );
|
||||
|
||||
//setting morale
|
||||
blitAt(graphics->morale30->ourImages[heroInst[b]->getCurrentMorale()+3].bitmap, 177 + 490*b, 45, bg);
|
||||
|
||||
//setting luck
|
||||
blitAt(graphics->luck30->ourImages[heroInst[b]->getCurrentLuck()+3].bitmap, 213 + 490*b, 45, bg);
|
||||
}
|
||||
|
||||
//printing portraits
|
||||
blitAt(graphics->portraitLarge[heroInst[0]->portrait], 257, 13, bg);
|
||||
blitAt(graphics->portraitLarge[heroInst[1]->portrait], 485, 13, bg);
|
||||
|
||||
delete un32;
|
||||
delete skilldef;
|
||||
}
|
||||
|
||||
CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) : bg(NULL)
|
||||
{
|
||||
char bufor[400];
|
||||
|
||||
heroInst[0] = LOCPLINT->cb->getHeroInfo(hero1, 2);
|
||||
heroInst[1] = LOCPLINT->cb->getHeroInfo(hero2, 2);
|
||||
|
||||
artifs[0] = new CArtifactsOfHero(genRect(600, 800, -334, 150));
|
||||
artifs[0]->setHero(heroInst[0]);
|
||||
artifs[1] = new CArtifactsOfHero(genRect(600, 800, 96, 150));
|
||||
artifs[1]->setHero(heroInst[1]);
|
||||
|
||||
prepareBackground();
|
||||
|
||||
|
||||
//primary skills
|
||||
for(int g=0; g<4; ++g)
|
||||
{
|
||||
//primary skill's clickable areas
|
||||
primSkillAreas.push_back(new LRClickableAreaWTextComp());
|
||||
primSkillAreas[g]->pos = genRect(32, 32, pos.x+385, pos.y + 19 + 36 * g);
|
||||
primSkillAreas[g]->text = CGI->generaltexth->arraytxt[2+g];
|
||||
primSkillAreas[g]->type = g;
|
||||
primSkillAreas[g]->bonus = -1;
|
||||
primSkillAreas[g]->baseType = 0;
|
||||
}
|
||||
|
||||
//heroes related thing
|
||||
for(int b=0; b<ARRAY_COUNT(heroInst); b++)
|
||||
{
|
||||
//secondary skill's clickable areas
|
||||
for(int g=0; g<heroInst[b]->secSkills.size(); ++g)
|
||||
{
|
||||
@ -3841,21 +3882,9 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) //c-tor
|
||||
secSkillAreas[b][g]->hoverText = std::string(bufor);
|
||||
}
|
||||
|
||||
//hero's specialty
|
||||
blitAt(un32->ourImages[heroInst[b]->subID].bitmap, 67 + 490*b, 45, bg);
|
||||
|
||||
//experience
|
||||
blitAt(skilldef->ourImages[4].bitmap, 103 + 490*b, 45, bg);
|
||||
printAtMiddle( makeNumberShort(heroInst[b]->exp), 119 + 490*b, 71, GEOR13, zwykly, bg );
|
||||
|
||||
//mana points
|
||||
blitAt(skilldef->ourImages[5].bitmap, 139 + 490*b, 45, bg);
|
||||
printAtMiddle( makeNumberShort(heroInst[b]->mana), 155 + 490*b, 71, GEOR13, zwykly, bg );
|
||||
|
||||
//setting morale
|
||||
morale[b] = new LRClickableAreaWTextComp();
|
||||
morale[b]->pos = genRect(32, 32, pos.x + 177 + 490*b, pos.y + 45);
|
||||
blitAt(graphics->morale30->ourImages[heroInst[b]->getCurrentMorale()+3].bitmap, 177 + 490*b, 45, bg);
|
||||
|
||||
std::vector<std::pair<int,std::string> > mrl = heroInst[b]->getCurrentMoraleModifiers();
|
||||
int mrlv = heroInst[b]->getCurrentMorale();
|
||||
@ -3871,7 +3900,6 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) //c-tor
|
||||
//setting luck
|
||||
luck[b] = new LRClickableAreaWTextComp();
|
||||
luck[b]->pos = genRect(32, 32, pos.x + 213 + 490*b, pos.y + 45);
|
||||
blitAt(graphics->luck30->ourImages[heroInst[b]->getCurrentLuck()+3].bitmap, 213 + 490*b, 45, bg);
|
||||
|
||||
mrl = heroInst[b]->getCurrentLuckModifiers();
|
||||
mrlv = heroInst[b]->getCurrentLuck();
|
||||
@ -3885,10 +3913,6 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) //c-tor
|
||||
luck[b]->text += mrl[it].second;
|
||||
}
|
||||
|
||||
//printing portraits
|
||||
blitAt(graphics->portraitLarge[heroInst[0]->portrait], 257, 13, bg);
|
||||
blitAt(graphics->portraitLarge[heroInst[1]->portrait], 485, 13, bg);
|
||||
|
||||
//buttons
|
||||
quit = new AdventureMapButton(CGI->generaltexth->tcommands[8], "", boost::bind(&CExchangeWindow::close, this), pos.x+732, pos.y+567, "IOKAY.DEF", SDLK_RETURN);
|
||||
questlogButton[0] = new AdventureMapButton(CGI->generaltexth->heroscrn[0], std::string(), boost::bind(&CExchangeWindow::questlog,this, 0), pos.x+10, pos.y+44, "hsbtns4.def");
|
||||
@ -3899,9 +3923,6 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) //c-tor
|
||||
|
||||
//garrison interface
|
||||
garr = new CGarrisonInt(pos.x + 69, pos.y + 131, 4, Point(418,0), bg, Point(0,0), heroInst[0],heroInst[1], true);
|
||||
|
||||
delete un32;
|
||||
delete skilldef;
|
||||
}
|
||||
|
||||
CExchangeWindow::~CExchangeWindow() //d-tor
|
||||
|
@ -678,15 +678,15 @@ class CExchangeWindow : public CIntObject, public CWindowWithGarrison
|
||||
SDL_Surface *bg; //background
|
||||
AdventureMapButton * quit, * questlogButton[2];
|
||||
|
||||
const CGHeroInstance * heroInst[2];
|
||||
CArtifactsOfHero * artifs[2];
|
||||
|
||||
std::vector<LRClickableAreaWTextComp *> secSkillAreas[2], primSkillAreas;
|
||||
|
||||
LRClickableAreaWTextComp *morale[2], *luck[2];
|
||||
|
||||
public:
|
||||
|
||||
const CGHeroInstance * heroInst[2];
|
||||
CArtifactsOfHero * artifs[2];
|
||||
|
||||
void close();
|
||||
void activate();
|
||||
void deactivate();
|
||||
@ -694,6 +694,8 @@ public:
|
||||
|
||||
void questlog(int whichHero); //questlog button callback; whichHero: 0 - left, 1 - right
|
||||
|
||||
void prepareBackground(); //prepares or redraws bg
|
||||
|
||||
CExchangeWindow(si32 hero1, si32 hero2); //c-tor
|
||||
~CExchangeWindow(); //d-tor
|
||||
};
|
||||
|
13
config/cr_abils.txt
Normal file
13
config/cr_abils.txt
Normal file
@ -0,0 +1,13 @@
|
||||
//creatures' abilities description
|
||||
//first line: use abilities from ZCRTRAIT.TXT [0 - no, 1 - yes]
|
||||
//next lines: + [CREATURE_ID] [ABILITY_ID] [value] [subtype] [additional info] [comment to the end of line] /*adding ability*/
|
||||
// or: - [CREATURE_ID] [ABILITY_ID] /*removing ability*/
|
||||
// or: 0 /*end of ability descriptions*/
|
||||
1
|
||||
+ 115 1 0 0 0 //water elemental should be treated as double-wide
|
||||
+ 123 1 0 0 0 //ice elemental should be treated as double-wide
|
||||
+ 140 1 0 0 0 //boar should be treated as double-wide
|
||||
+ 142 1 0 0 0 //nomads should be treated as double-wide
|
||||
- 46 2 //hell hound doesn't fly
|
||||
- 47 2 //cerberus doesn't fly
|
||||
0
|
@ -90,10 +90,40 @@ si32 CCreature::maxAmount(const std::vector<si32> &res) const //how many creatur
|
||||
return ret;
|
||||
}
|
||||
|
||||
int readNumber(int & befi, int & i, int andame, std::string & buf) //helper function for void CCreatureHandler::loadCreatures()
|
||||
{
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
std::string tmp = buf.substr(befi, i-befi);
|
||||
int ret = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
tlog5 << "\t\tReading config/cr_abils.txt and ZCRTRAIT.TXT" << std::endl;
|
||||
|
||||
bool useCreAbilsFromZCRTRAIT = true;
|
||||
|
||||
////////////reading cr_abils.txt ///////////////////
|
||||
std::ifstream abils("config" PATHSEPARATOR "cr_abils.txt", std::ios::in | std::ios::binary); //this file is not in lod
|
||||
const int MAX_LINE_SIZE = 1000;
|
||||
char abilLine[MAX_LINE_SIZE+1];
|
||||
for(int i=0; i<5; ++i) //removing 5 comment lines
|
||||
{
|
||||
abils.getline(abilLine, MAX_LINE_SIZE);
|
||||
}
|
||||
//reading first line (determining if we should use creature abilities from ZCRTRAIT.TXT)
|
||||
abils.getline(abilLine, MAX_LINE_SIZE);
|
||||
useCreAbilsFromZCRTRAIT = atoi(abilLine);
|
||||
|
||||
////////////reading ZCRTRAIT.TXT ///////////////////
|
||||
std::string buf = bitmaph->getTextFile("ZCRTRAIT.TXT");
|
||||
int andame = buf.size();
|
||||
int i=0; //buf iterator
|
||||
@ -141,194 +171,24 @@ void CCreatureHandler::loadCreatures()
|
||||
ncre.namePl = buf.substr(befi, i-befi);
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
for(int v=0; v<7; ++v)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
ncre.cost[v] = readNumber(befi, i, andame, buf);
|
||||
}
|
||||
ncre.cost[0] = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.cost[1] = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.cost[2] = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.cost[3] = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.cost[4] = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.cost[5] = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.cost[6] = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.fightValue = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.AIValue = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.growth = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.hordeGrowth = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.hitPoints = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.speed = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.attack = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.defence = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.damageMin = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.damageMax = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.shots = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.spells = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.ammMin = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
{
|
||||
if(buf[i]=='\t')
|
||||
break;
|
||||
}
|
||||
ncre.ammMax = atoi(buf.substr(befi, i-befi).c_str());
|
||||
++i;
|
||||
ncre.fightValue = readNumber(befi, i, andame, buf);
|
||||
ncre.AIValue = readNumber(befi, i, andame, buf);
|
||||
ncre.growth = readNumber(befi, i, andame, buf);
|
||||
ncre.hordeGrowth = readNumber(befi, i, andame, buf);
|
||||
ncre.hitPoints = readNumber(befi, i, andame, buf);
|
||||
ncre.speed = readNumber(befi, i, andame, buf);
|
||||
ncre.attack = readNumber(befi, i, andame, buf);
|
||||
ncre.defence = readNumber(befi, i, andame, buf);
|
||||
ncre.damageMin = readNumber(befi, i, andame, buf);
|
||||
ncre.damageMax = readNumber(befi, i, andame, buf);
|
||||
ncre.shots = readNumber(befi, i, andame, buf);
|
||||
ncre.spells = readNumber(befi, i, andame, buf);
|
||||
ncre.ammMin = readNumber(befi, i, andame, buf);
|
||||
ncre.ammMax = readNumber(befi, i, andame, buf);
|
||||
|
||||
befi=i;
|
||||
for(i; i<andame; ++i)
|
||||
@ -347,52 +207,55 @@ void CCreatureHandler::loadCreatures()
|
||||
}
|
||||
ncre.abilityRefs = buf.substr(befi, i-befi);
|
||||
i+=2;
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "DOUBLE_WIDE"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::DOUBLE_WIDE, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "FLYING_ARMY"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::FLYING, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "SHOOTING_ARMY"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::SHOOTER, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "SIEGE_WEAPON"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::SIEGE_WEAPON, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_two_attacks"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::ADDITIONAL_ATTACK, 1));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_free_attack"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::BLOCKS_RETAILATION, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "IS_UNDEAD"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::UNDEAD, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_no_melee_penalty"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::NO_MELEE_PENALTY, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_jousting"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::JOUSTING, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_raises_morale"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::RAISING_MORALE, 1));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_lowers_morale"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::ENEMY_MORALE_DECREASING, 1));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "KING_1"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::KING1, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "KING_2"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::KING2, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "KING_3"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::KING3, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_no_wall_penalty"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::NO_WALL_PENALTY, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "CATAPULT"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::CATAPULT, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "MULTI_HEADED"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::ATTACKS_ALL_ADAJCENT, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "IMMUNE_TO_MIND_SPELLS"))
|
||||
{
|
||||
std::vector<int> mindSpells = getMindSpells();
|
||||
for(int g=0; g<mindSpells.size(); ++g)
|
||||
if(useCreAbilsFromZCRTRAIT)
|
||||
{ //adding abilities from ZCRTRAIT.TXT
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "DOUBLE_WIDE"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::DOUBLE_WIDE, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "FLYING_ARMY"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::FLYING, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "SHOOTING_ARMY"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::SHOOTER, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "SIEGE_WEAPON"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::SIEGE_WEAPON, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_two_attacks"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::ADDITIONAL_ATTACK, 1));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_free_attack"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::BLOCKS_RETAILATION, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "IS_UNDEAD"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::UNDEAD, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_no_melee_penalty"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::NO_MELEE_PENALTY, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_jousting"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::JOUSTING, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_raises_morale"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::RAISING_MORALE, 1));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_lowers_morale"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::ENEMY_MORALE_DECREASING, 1));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "KING_1"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::KING1, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "KING_2"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::KING2, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "KING_3"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::KING3, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_no_wall_penalty"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::NO_WALL_PENALTY, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "CATAPULT"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::CATAPULT, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "MULTI_HEADED"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::ATTACKS_ALL_ADAJCENT, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "IMMUNE_TO_MIND_SPELLS"))
|
||||
{
|
||||
creatures[40].abilities += makeCreatureAbility(StackFeature::SPELL_IMMUNITY, 0, mindSpells[g]); //giants are immune to mind spells
|
||||
std::vector<int> mindSpells = getMindSpells();
|
||||
for(int g=0; g<mindSpells.size(); ++g)
|
||||
{
|
||||
creatures[40].abilities += makeCreatureAbility(StackFeature::SPELL_IMMUNITY, 0, mindSpells[g]); //giants are immune to mind spells
|
||||
}
|
||||
}
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "IMMUNE_TO_FIRE_SPELLS"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::FIRE_IMMUNITY, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "HAS_EXTENDED_ATTACK"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::TWO_HEX_ATTACK_BREATH, 0));
|
||||
}
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "IMMUNE_TO_FIRE_SPELLS"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::FIRE_IMMUNITY, 0));
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "HAS_EXTENDED_ATTACK"))
|
||||
ncre.abilities.push_back(makeCreatureAbility(StackFeature::TWO_HEX_ATTACK_BREATH, 0));
|
||||
|
||||
if(ncre.nameSing!=std::string("") && ncre.namePl!=std::string(""))
|
||||
{
|
||||
@ -401,6 +264,59 @@ void CCreatureHandler::loadCreatures()
|
||||
}
|
||||
}
|
||||
|
||||
////second part of reading cr_abils.txt////
|
||||
bool contReading = true;
|
||||
while(contReading) //main reading loop
|
||||
{
|
||||
abils.getline(abilLine, MAX_LINE_SIZE);
|
||||
std::istringstream reader(abilLine);
|
||||
char command;
|
||||
reader >> command;
|
||||
switch(command)
|
||||
{
|
||||
case '+': //add new ability
|
||||
{
|
||||
int creatureID;
|
||||
StackFeature nsf;
|
||||
si32 buf;
|
||||
reader >> creatureID;
|
||||
reader >> buf; nsf.type = buf; //it reads ui8 as byte, in file it has different format
|
||||
reader >> buf; nsf.value = buf;
|
||||
reader >> buf; nsf.subtype = buf;
|
||||
reader >> buf; nsf.additionalInfo = buf;
|
||||
nsf.source = StackFeature::CREATURE_ABILITY;
|
||||
nsf.duration = StackFeature::WHOLE_BATTLE;
|
||||
nsf.turnsRemain = 0;
|
||||
|
||||
creatures[creatureID].abilities += nsf;
|
||||
break;
|
||||
}
|
||||
case '-': //remove ability
|
||||
{
|
||||
int creatureID;
|
||||
ui32 type;
|
||||
reader >> creatureID;
|
||||
reader >> type;
|
||||
StackFeature::ECombatFeatures ecf = static_cast<StackFeature::ECombatFeatures>(type);
|
||||
|
||||
creatures[creatureID].abilities -= ecf;
|
||||
break;
|
||||
}
|
||||
case '0': //end reading
|
||||
{
|
||||
contReading = false;
|
||||
break;
|
||||
}
|
||||
default: //invalid command
|
||||
{
|
||||
tlog1 << "Parse error in file config/cr_abils.txt" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abils.close();
|
||||
|
||||
tlog5 << "\t\tReading config/crerefnam.txt" << std::endl;
|
||||
//loading reference names
|
||||
std::ifstream ifs("config/crerefnam.txt");
|
||||
@ -528,13 +444,14 @@ void CCreatureHandler::loadCreatures()
|
||||
inp2.close();
|
||||
|
||||
//TODO: create a tidy configuration file to control fixing unit abilities
|
||||
creatures[115].abilities.push_back(makeCreatureAbility(StackFeature::DOUBLE_WIDE, 0));//water elemental should be treated as double-wide
|
||||
/* creatures[115].abilities.push_back(makeCreatureAbility(StackFeature::DOUBLE_WIDE, 0));//water elemental should be treated as double-wide
|
||||
creatures[123].abilities.push_back(makeCreatureAbility(StackFeature::DOUBLE_WIDE, 0));//ice elemental should be treated as double-wide
|
||||
creatures[140].abilities.push_back(makeCreatureAbility(StackFeature::DOUBLE_WIDE, 0));//boar should be treated as double-wide
|
||||
creatures[142].abilities.push_back(makeCreatureAbility(StackFeature::DOUBLE_WIDE, 0));//nomads should be treated as double-wide
|
||||
|
||||
creatures[46].abilities -= StackFeature::FLYING; //hell hound
|
||||
creatures[47].abilities -= StackFeature::FLYING; //cerberus
|
||||
*/
|
||||
creatures[52].abilities += makeCreatureAbility(StackFeature::FLYING, 0); //Efreeti
|
||||
creatures[53].abilities += makeCreatureAbility(StackFeature::FLYING, 0); //Efreet Sultan
|
||||
|
||||
|
@ -597,6 +597,11 @@ si32 CStack::Defense(bool withFrenzy /*= true*/) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
ui16 CStack::MaxHealth() const
|
||||
{
|
||||
return creature->hitPoints + valOfFeatures(StackFeature::HP_BONUS);
|
||||
}
|
||||
|
||||
bool CStack::willMove()
|
||||
{
|
||||
return !vstd::contains(state, DEFENDING)
|
||||
|
@ -183,6 +183,7 @@ public:
|
||||
si8 Luck() const; //get luck of stack with all modificators
|
||||
si32 Attack() const; //get attack of stack with all modificators
|
||||
si32 Defense(bool withFrenzy = true) const; //get defense of stack with all modificators
|
||||
ui16 MaxHealth() const; //get max HP of stack with all modifiers
|
||||
template <typename Handler> void save(Handler &h, const int version)
|
||||
{
|
||||
h & creature->idNumber;
|
||||
|
@ -437,13 +437,13 @@ askInterfaceForMove:
|
||||
}
|
||||
void CGameHandler::prepareAttacked(BattleStackAttacked &bsa, CStack *def)
|
||||
{
|
||||
bsa.killedAmount = bsa.damageAmount / def->creature->hitPoints;
|
||||
unsigned damageFirst = bsa.damageAmount % def->creature->hitPoints;
|
||||
bsa.killedAmount = bsa.damageAmount / def->MaxHealth();
|
||||
unsigned damageFirst = bsa.damageAmount % def->MaxHealth();
|
||||
|
||||
if( def->firstHPleft <= damageFirst )
|
||||
{
|
||||
bsa.killedAmount++;
|
||||
bsa.newHP = def->firstHPleft + def->creature->hitPoints - damageFirst;
|
||||
bsa.newHP = def->firstHPleft + def->MaxHealth() - damageFirst;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -849,6 +849,8 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
|
||||
stacks.back()->luck = hero1->getCurrentLuck(i->first,false);
|
||||
stacks.back()->features.push_back(makeFeature(StackFeature::ATTACK_BONUS, StackFeature::WHOLE_BATTLE, 0, hero1->getPrimSkillLevel(0), StackFeature::BONUS_FROM_HERO));
|
||||
stacks.back()->features.push_back(makeFeature(StackFeature::DEFENCE_BONUS, StackFeature::WHOLE_BATTLE, 0, hero1->getPrimSkillLevel(1), StackFeature::BONUS_FROM_HERO));
|
||||
stacks.back()->features.push_back(makeFeature(StackFeature::HP_BONUS, StackFeature::WHOLE_BATTLE, 0, hero1->valOfBonuses(HeroBonus::STACK_HEALTH), StackFeature::BONUS_FROM_HERO));
|
||||
stacks.back()->firstHPleft = stacks.back()->MaxHealth();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -900,6 +902,8 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
|
||||
stacks.back()->luck = hero2->getCurrentLuck(i->first,false);
|
||||
stacks.back()->features.push_back(makeFeature(StackFeature::ATTACK_BONUS, StackFeature::WHOLE_BATTLE, 0, hero2->getPrimSkillLevel(0), StackFeature::BONUS_FROM_HERO));
|
||||
stacks.back()->features.push_back(makeFeature(StackFeature::DEFENCE_BONUS, StackFeature::WHOLE_BATTLE, 0, hero2->getPrimSkillLevel(1), StackFeature::BONUS_FROM_HERO));
|
||||
stacks.back()->features.push_back(makeFeature(StackFeature::HP_BONUS, StackFeature::WHOLE_BATTLE, 0, hero2->valOfBonuses(HeroBonus::STACK_HEALTH), StackFeature::BONUS_FROM_HERO));
|
||||
stacks.back()->firstHPleft = stacks.back()->MaxHealth();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user