1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +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:
mateuszb
2009-06-28 13:49:39 +00:00
parent 9093320da8
commit 85eb5c7eb9
9 changed files with 254 additions and 276 deletions

View File

@@ -2594,6 +2594,7 @@ void CBattleHex::clickRight(boost::logic::tribool down)
pom->luck = myst.Luck(); pom->luck = myst.Luck();
pom->morale = myst.Morale(); pom->morale = myst.Morale();
pom->speedBonus = myst.Speed() - myst.creature->speed; pom->speedBonus = myst.Speed() - myst.creature->speed;
pom->healthBonus = myst.MaxHealth() - myst.creature->hitPoints;
pom->shotsLeft = myst.shots; pom->shotsLeft = myst.shots;
for(int vb=0; vb<myst.effects.size(); ++vb) for(int vb=0; vb<myst.effects.size(); ++vb)

View File

@@ -1520,6 +1520,20 @@ void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
adventureInt->heroWindow->setHero(adventureInt->heroWindow->curHero); adventureInt->heroWindow->setHero(adventureInt->heroWindow->curHero);
adventureInt->heroWindow->activate(); 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() void CPlayerInterface::updateWater()

View File

@@ -2053,7 +2053,7 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState
//health //health
printAt(CGI->generaltexth->allTexts[388],155,124,GEOR13,zwykly,bitmap); 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); printToWR(pom,276,137,GEOR13,zwykly,bitmap);
//remaining health //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]; if(bg)
SDL_FreeSurface(bg);
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]);
SDL_Surface * bgtemp; //loaded as 8bpp surface SDL_Surface * bgtemp; //loaded as 8bpp surface
bgtemp = BitmapHandler::loadBitmap("TRADE2.BMP"); bgtemp = BitmapHandler::loadBitmap("TRADE2.BMP");
@@ -3797,14 +3790,6 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) //c-tor
{ {
//graphics //graphics
blitAt(skilldef->ourImages[g].bitmap, genRect(32, 32, 385, 19 + 36 * g), bg); 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"); 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); 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 //secondary skill's clickable areas
for(int g=0; g<heroInst[b]->secSkills.size(); ++g) 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); 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 //setting morale
morale[b] = new LRClickableAreaWTextComp(); morale[b] = new LRClickableAreaWTextComp();
morale[b]->pos = genRect(32, 32, pos.x + 177 + 490*b, pos.y + 45); 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(); std::vector<std::pair<int,std::string> > mrl = heroInst[b]->getCurrentMoraleModifiers();
int mrlv = heroInst[b]->getCurrentMorale(); int mrlv = heroInst[b]->getCurrentMorale();
@@ -3871,7 +3900,6 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) //c-tor
//setting luck //setting luck
luck[b] = new LRClickableAreaWTextComp(); luck[b] = new LRClickableAreaWTextComp();
luck[b]->pos = genRect(32, 32, pos.x + 213 + 490*b, pos.y + 45); 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(); mrl = heroInst[b]->getCurrentLuckModifiers();
mrlv = heroInst[b]->getCurrentLuck(); mrlv = heroInst[b]->getCurrentLuck();
@@ -3885,10 +3913,6 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) //c-tor
luck[b]->text += mrl[it].second; 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 //buttons
quit = new AdventureMapButton(CGI->generaltexth->tcommands[8], "", boost::bind(&CExchangeWindow::close, this), pos.x+732, pos.y+567, "IOKAY.DEF", SDLK_RETURN); 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"); 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 //garrison interface
garr = new CGarrisonInt(pos.x + 69, pos.y + 131, 4, Point(418,0), bg, Point(0,0), heroInst[0],heroInst[1], true); 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 CExchangeWindow::~CExchangeWindow() //d-tor

View File

@@ -678,15 +678,15 @@ class CExchangeWindow : public CIntObject, public CWindowWithGarrison
SDL_Surface *bg; //background SDL_Surface *bg; //background
AdventureMapButton * quit, * questlogButton[2]; AdventureMapButton * quit, * questlogButton[2];
const CGHeroInstance * heroInst[2];
CArtifactsOfHero * artifs[2];
std::vector<LRClickableAreaWTextComp *> secSkillAreas[2], primSkillAreas; std::vector<LRClickableAreaWTextComp *> secSkillAreas[2], primSkillAreas;
LRClickableAreaWTextComp *morale[2], *luck[2]; LRClickableAreaWTextComp *morale[2], *luck[2];
public: public:
const CGHeroInstance * heroInst[2];
CArtifactsOfHero * artifs[2];
void close(); void close();
void activate(); void activate();
void deactivate(); void deactivate();
@@ -694,6 +694,8 @@ public:
void questlog(int whichHero); //questlog button callback; whichHero: 0 - left, 1 - right 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(si32 hero1, si32 hero2); //c-tor
~CExchangeWindow(); //d-tor ~CExchangeWindow(); //d-tor
}; };

13
config/cr_abils.txt Normal file
View 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

View File

@@ -90,10 +90,40 @@ si32 CCreature::maxAmount(const std::vector<si32> &res) const //how many creatur
return ret; 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() 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; 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"); std::string buf = bitmaph->getTextFile("ZCRTRAIT.TXT");
int andame = buf.size(); int andame = buf.size();
int i=0; //buf iterator int i=0; //buf iterator
@@ -141,194 +171,24 @@ void CCreatureHandler::loadCreatures()
ncre.namePl = buf.substr(befi, i-befi); ncre.namePl = buf.substr(befi, i-befi);
++i; ++i;
befi=i; for(int v=0; v<7; ++v)
for(i; i<andame; ++i)
{ {
if(buf[i]=='\t') ncre.cost[v] = readNumber(befi, i, andame, buf);
break;
} }
ncre.cost[0] = atoi(buf.substr(befi, i-befi).c_str()); ncre.fightValue = readNumber(befi, i, andame, buf);
++i; ncre.AIValue = readNumber(befi, i, andame, buf);
ncre.growth = readNumber(befi, i, andame, buf);
befi=i; ncre.hordeGrowth = readNumber(befi, i, andame, buf);
for(i; i<andame; ++i) ncre.hitPoints = readNumber(befi, i, andame, buf);
{ ncre.speed = readNumber(befi, i, andame, buf);
if(buf[i]=='\t') ncre.attack = readNumber(befi, i, andame, buf);
break; ncre.defence = readNumber(befi, i, andame, buf);
} ncre.damageMin = readNumber(befi, i, andame, buf);
ncre.cost[1] = atoi(buf.substr(befi, i-befi).c_str()); ncre.damageMax = readNumber(befi, i, andame, buf);
++i; ncre.shots = readNumber(befi, i, andame, buf);
ncre.spells = readNumber(befi, i, andame, buf);
befi=i; ncre.ammMin = readNumber(befi, i, andame, buf);
for(i; i<andame; ++i) ncre.ammMax = readNumber(befi, i, andame, buf);
{
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;
befi=i; befi=i;
for(i; i<andame; ++i) for(i; i<andame; ++i)
@@ -347,6 +207,8 @@ void CCreatureHandler::loadCreatures()
} }
ncre.abilityRefs = buf.substr(befi, i-befi); ncre.abilityRefs = buf.substr(befi, i-befi);
i+=2; i+=2;
if(useCreAbilsFromZCRTRAIT)
{ //adding abilities from ZCRTRAIT.TXT
if(boost::algorithm::find_first(ncre.abilityRefs, "DOUBLE_WIDE")) if(boost::algorithm::find_first(ncre.abilityRefs, "DOUBLE_WIDE"))
ncre.abilities.push_back(makeCreatureAbility(StackFeature::DOUBLE_WIDE, 0)); ncre.abilities.push_back(makeCreatureAbility(StackFeature::DOUBLE_WIDE, 0));
if(boost::algorithm::find_first(ncre.abilityRefs, "FLYING_ARMY")) if(boost::algorithm::find_first(ncre.abilityRefs, "FLYING_ARMY"))
@@ -393,6 +255,7 @@ void CCreatureHandler::loadCreatures()
ncre.abilities.push_back(makeCreatureAbility(StackFeature::FIRE_IMMUNITY, 0)); ncre.abilities.push_back(makeCreatureAbility(StackFeature::FIRE_IMMUNITY, 0));
if(boost::algorithm::find_first(ncre.abilityRefs, "HAS_EXTENDED_ATTACK")) if(boost::algorithm::find_first(ncre.abilityRefs, "HAS_EXTENDED_ATTACK"))
ncre.abilities.push_back(makeCreatureAbility(StackFeature::TWO_HEX_ATTACK_BREATH, 0)); ncre.abilities.push_back(makeCreatureAbility(StackFeature::TWO_HEX_ATTACK_BREATH, 0));
}
if(ncre.nameSing!=std::string("") && ncre.namePl!=std::string("")) 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; tlog5 << "\t\tReading config/crerefnam.txt" << std::endl;
//loading reference names //loading reference names
std::ifstream ifs("config/crerefnam.txt"); std::ifstream ifs("config/crerefnam.txt");
@@ -528,13 +444,14 @@ void CCreatureHandler::loadCreatures()
inp2.close(); inp2.close();
//TODO: create a tidy configuration file to control fixing unit abilities //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[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[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[142].abilities.push_back(makeCreatureAbility(StackFeature::DOUBLE_WIDE, 0));//nomads should be treated as double-wide
creatures[46].abilities -= StackFeature::FLYING; //hell hound creatures[46].abilities -= StackFeature::FLYING; //hell hound
creatures[47].abilities -= StackFeature::FLYING; //cerberus creatures[47].abilities -= StackFeature::FLYING; //cerberus
*/
creatures[52].abilities += makeCreatureAbility(StackFeature::FLYING, 0); //Efreeti creatures[52].abilities += makeCreatureAbility(StackFeature::FLYING, 0); //Efreeti
creatures[53].abilities += makeCreatureAbility(StackFeature::FLYING, 0); //Efreet Sultan creatures[53].abilities += makeCreatureAbility(StackFeature::FLYING, 0); //Efreet Sultan

View File

@@ -597,6 +597,11 @@ si32 CStack::Defense(bool withFrenzy /*= true*/) const
return ret; return ret;
} }
ui16 CStack::MaxHealth() const
{
return creature->hitPoints + valOfFeatures(StackFeature::HP_BONUS);
}
bool CStack::willMove() bool CStack::willMove()
{ {
return !vstd::contains(state, DEFENDING) return !vstd::contains(state, DEFENDING)

View File

@@ -183,6 +183,7 @@ public:
si8 Luck() const; //get luck of stack with all modificators si8 Luck() const; //get luck of stack with all modificators
si32 Attack() const; //get attack 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 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) template <typename Handler> void save(Handler &h, const int version)
{ {
h & creature->idNumber; h & creature->idNumber;

View File

@@ -437,13 +437,13 @@ askInterfaceForMove:
} }
void CGameHandler::prepareAttacked(BattleStackAttacked &bsa, CStack *def) void CGameHandler::prepareAttacked(BattleStackAttacked &bsa, CStack *def)
{ {
bsa.killedAmount = bsa.damageAmount / def->creature->hitPoints; bsa.killedAmount = bsa.damageAmount / def->MaxHealth();
unsigned damageFirst = bsa.damageAmount % def->creature->hitPoints; unsigned damageFirst = bsa.damageAmount % def->MaxHealth();
if( def->firstHPleft <= damageFirst ) if( def->firstHPleft <= damageFirst )
{ {
bsa.killedAmount++; bsa.killedAmount++;
bsa.newHP = def->firstHPleft + def->creature->hitPoints - damageFirst; bsa.newHP = def->firstHPleft + def->MaxHealth() - damageFirst;
} }
else else
{ {
@@ -849,6 +849,8 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
stacks.back()->luck = hero1->getCurrentLuck(i->first,false); 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::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::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 else
{ {
@@ -900,6 +902,8 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
stacks.back()->luck = hero2->getCurrentLuck(i->first,false); 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::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::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 else
{ {