mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-03 13:01:33 +02:00
* added support for archery, offence and armorer secondary abilities
* hero's primary skills account for damage dealt by creatures in battle * magical hero are given spellbook at the beginning * added initial secondary skills for heroes * minor fixes and improvements
This commit is contained in:
parent
917be0693d
commit
538ffb1579
@ -56,13 +56,18 @@ CGObjectInstance * createObject(int id, int subid, int3 pos, int owner)
|
||||
nobj->defInfo->blockMap[5] = 253;
|
||||
nobj->defInfo->visitMap[5] = 2;
|
||||
nobj->artifWorn[16] = 3;
|
||||
if(nobj->type->heroType % 2 == 1) //it's a magical hero
|
||||
{
|
||||
nobj->artifWorn[17] = 0; //give him spellbook
|
||||
}
|
||||
nobj->portrait = subid;
|
||||
nobj->primSkills.resize(4);
|
||||
nobj->primSkills[0] = nobj->type->heroClass->initialAttack;
|
||||
nobj->primSkills[1] = nobj->type->heroClass->initialDefence;
|
||||
nobj->primSkills[2] = nobj->type->heroClass->initialPower;
|
||||
nobj->primSkills[3] = nobj->type->heroClass->initialKnowledge;
|
||||
nobj->mana = 10 * nobj->primSkills[3];
|
||||
nobj->secSkills = nobj->type->secSkillsInit; //copying initial secondary skills
|
||||
nobj->mana = 10 * nobj->getPrimSkillLevel(3);
|
||||
return nobj;
|
||||
}
|
||||
case 98: //town
|
||||
@ -1000,7 +1005,10 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
vhi->exp=40+ran()%50;
|
||||
vhi->level = 1;
|
||||
}
|
||||
if (vhi->level>1) ;//TODO dodac um dr, ale potrzebne los
|
||||
if(vhi->secSkills.size() == 1 && vhi->secSkills[0] == std::make_pair(-1, -1)) //set secondary skills to default
|
||||
{
|
||||
vhi->secSkills = vhi->type->secSkillsInit;
|
||||
}
|
||||
if ((!vhi->primSkills.size()) || (vhi->primSkills[0]<0))
|
||||
{
|
||||
if (vhi->primSkills.size()<PRIMARY_SKILLS)
|
||||
@ -1010,7 +1018,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
vhi->primSkills[2] = vhi->type->heroClass->initialPower;
|
||||
vhi->primSkills[3] = vhi->type->heroClass->initialKnowledge;
|
||||
}
|
||||
vhi->mana = vhi->primSkills[3]*10;
|
||||
vhi->mana = vhi->getPrimSkillLevel(3)*10;
|
||||
if (!vhi->name.length())
|
||||
{
|
||||
vhi->name = vhi->type->name;
|
||||
@ -1023,6 +1031,10 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
vhi->portrait = vhi->type->ID;
|
||||
|
||||
vhi->artifWorn[16] = 3;
|
||||
if(vhi->type->heroType % 2 == 1) //it's a magical hero
|
||||
{
|
||||
vhi->artifWorn[17] = 0; //give him spellbook
|
||||
}
|
||||
|
||||
//initial army
|
||||
if (!vhi->army.slots.size()) //standard army
|
||||
@ -1050,6 +1062,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
vhi->army.slots[x-pom2].second = (ran()%pom)+vhi->type->lowStack[x];
|
||||
else
|
||||
vhi->army.slots[x-pom2].second = +vhi->type->lowStack[x];
|
||||
vhi->army.formation = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1347,9 +1360,9 @@ std::set<int3> CGameState::tilesToReveal(int3 pos, int radious, int player)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender)
|
||||
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)
|
||||
{
|
||||
int attackDefenseBonus = attacker->creature->attack - defender->creature->defence;
|
||||
int attackDefenseBonus = attacker->creature->attack + (attackerHero ? attackerHero->getPrimSkillLevel(0) : 0) - (defender->creature->defence + (defendingHero ? defendingHero->getPrimSkillLevel(1) : 0));
|
||||
int damageBase = 0;
|
||||
if(attacker->creature->damageMax == attacker->creature->damageMin) //constant damage
|
||||
{
|
||||
@ -1360,7 +1373,7 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender)
|
||||
damageBase = rand()%(attacker->creature->damageMax - attacker->creature->damageMin) + attacker->creature->damageMin + 1;
|
||||
}
|
||||
|
||||
float dmgBonusMultiplier = 1.0;
|
||||
float dmgBonusMultiplier = 1.0f;
|
||||
if(attackDefenseBonus < 0) //decreasing dmg
|
||||
{
|
||||
if(0.02f * (-attackDefenseBonus) > 0.3f)
|
||||
@ -1383,6 +1396,55 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender)
|
||||
dmgBonusMultiplier += 0.05f * attackDefenseBonus;
|
||||
}
|
||||
}
|
||||
//handling secondary abilities
|
||||
if(attackerHero)
|
||||
{
|
||||
if(shooting)
|
||||
{
|
||||
switch(attackerHero->getSecSkillLevel(1)) //archery
|
||||
{
|
||||
case 1: //basic
|
||||
dmgBonusMultiplier *= 1.1f;
|
||||
break;
|
||||
case 2: //advanced
|
||||
dmgBonusMultiplier *= 1.25f;
|
||||
break;
|
||||
case 3: //expert
|
||||
dmgBonusMultiplier *= 1.5f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(attackerHero->getSecSkillLevel(22)) //offence
|
||||
{
|
||||
case 1: //basic
|
||||
dmgBonusMultiplier *= 1.1f;
|
||||
break;
|
||||
case 2: //advanced
|
||||
dmgBonusMultiplier *= 1.2f;
|
||||
break;
|
||||
case 3: //expert
|
||||
dmgBonusMultiplier *= 1.3f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(defendingHero)
|
||||
{
|
||||
switch(defendingHero->getSecSkillLevel(23)) //armourer
|
||||
{
|
||||
case 1: //basic
|
||||
dmgBonusMultiplier *= 0.95f;
|
||||
break;
|
||||
case 2: //advanced
|
||||
dmgBonusMultiplier *= 0.9f;
|
||||
break;
|
||||
case 3: //expert
|
||||
dmgBonusMultiplier *= 0.85f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (float)damageBase * (float)attacker->amount * dmgBonusMultiplier;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ struct DLL_EXPORT BattleInfo
|
||||
|
||||
static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
|
||||
static std::vector<int> neighbouringTiles(int hex);
|
||||
static int calculateDmg(const CStack* attacker, const CStack* defender); //TODO: add additional conditions and require necessary data
|
||||
static int calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting); //TODO: add additional conditions and require necessary data
|
||||
void calculateCasualties(std::set<std::pair<ui32,si32> > *casualties);
|
||||
};
|
||||
|
||||
|
@ -220,7 +220,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
|
||||
|
||||
for(int g=0; g<primSkillAreas.size(); ++g)
|
||||
{
|
||||
primSkillAreas[g]->bonus = hero->primSkills[g];
|
||||
primSkillAreas[g]->bonus = hero->getPrimSkillLevel(g);
|
||||
}
|
||||
for(int g=0; g<hero->secSkills.size(); ++g)
|
||||
{
|
||||
@ -236,7 +236,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
|
||||
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);
|
||||
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->primSkills[3]*10);
|
||||
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);
|
||||
spellPointsArea->text = std::string(bufor);
|
||||
|
||||
for(int g=0; g<artWorn.size(); ++g)
|
||||
@ -551,19 +551,19 @@ void CHeroWindow::redrawCurBack()
|
||||
|
||||
//printing primary skills' amounts
|
||||
std::stringstream primarySkill1;
|
||||
primarySkill1<<curHero->primSkills[0];
|
||||
primarySkill1<<curHero->getPrimSkillLevel(0);
|
||||
CSDL_Ext::printAtMiddle(primarySkill1.str(), 53, 165, TNRB16, zwykly, curBack);
|
||||
|
||||
std::stringstream primarySkill2;
|
||||
primarySkill2<<curHero->primSkills[1];
|
||||
primarySkill2<<curHero->getPrimSkillLevel(1);
|
||||
CSDL_Ext::printAtMiddle(primarySkill2.str(), 123, 165, TNRB16, zwykly, curBack);
|
||||
|
||||
std::stringstream primarySkill3;
|
||||
primarySkill3<<curHero->primSkills[2];
|
||||
primarySkill3<<curHero->getPrimSkillLevel(2);
|
||||
CSDL_Ext::printAtMiddle(primarySkill3.str(), 193, 165, TNRB16, zwykly, curBack);
|
||||
|
||||
std::stringstream primarySkill4;
|
||||
primarySkill4<<curHero->primSkills[3];
|
||||
primarySkill4<<curHero->getPrimSkillLevel(3);
|
||||
CSDL_Ext::printAtMiddle(primarySkill4.str(), 263, 165, TNRB16, zwykly, curBack);
|
||||
|
||||
blitAt(graphics->luck42->ourImages[curHero->getCurrentLuck()+3].bitmap, 239, 182, curBack);
|
||||
@ -650,7 +650,7 @@ void CHeroWindow::redrawCurBack()
|
||||
CSDL_Ext::printAt(expstr.str(), 69, 247, GEOR16, zwykly, curBack);
|
||||
CSDL_Ext::printAt(CGI->generaltexth->jktexts[7].substr(1, CGI->generaltexth->jktexts[7].size()-2), 212, 231, GEOR13, tytulowy, curBack);
|
||||
std::stringstream manastr;
|
||||
manastr<<curHero->mana<<'/'<<curHero->primSkills[3]*10;
|
||||
manastr<<curHero->mana<<'/'<<curHero->getPrimSkillLevel(3)*10;
|
||||
CSDL_Ext::printAt(manastr.str(), 212, 247, GEOR16, zwykly, curBack);
|
||||
}
|
||||
|
||||
|
@ -134,8 +134,8 @@ void CGarrisonSlot::clickRight (tribool down)
|
||||
pom = new StackState();
|
||||
const CGHeroInstance *h = static_cast<const CGHeroInstance *>(getObj());
|
||||
pom->currentHealth = 0;
|
||||
pom->attackBonus = h->primSkills[0];
|
||||
pom->defenseBonus = h->primSkills[1];
|
||||
pom->attackBonus = h->getPrimSkillLevel(0);
|
||||
pom->defenseBonus = h->getPrimSkillLevel(1);
|
||||
pom->luck = h->getCurrentLuck();
|
||||
pom->morale = h->getCurrentMorale();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ SDL_Surface * Graphics::drawPrimarySkill(const CGHeroInstance *curh, SDL_Surface
|
||||
char * buf = new char[10];
|
||||
for (int i=from;i<to;i++)
|
||||
{
|
||||
SDL_itoa(curh->primSkills[i],buf,10);
|
||||
SDL_itoa(curh->getPrimSkillLevel(i),buf,10);
|
||||
printAtMiddle(buf,84+28*i,68,GEOR13,zwykly,ret);
|
||||
}
|
||||
delete[] buf;
|
||||
|
158
config/heroes_sec_skills.txt
Normal file
158
config/heroes_sec_skills.txt
Normal file
@ -0,0 +1,158 @@
|
||||
//heroes'_inintial_set_of_secondary_abilities_format:_heroID_numberOfInitialSecSkills_(Skill_ID,_skill_lvl_for_every_spell)
|
||||
0 2 6 1 1 1
|
||||
1 2 6 1 1 1
|
||||
2 2 6 1 23 1
|
||||
3 2 6 1 5 1
|
||||
4 2 6 1 13 1
|
||||
5 2 6 1 22 1
|
||||
6 2 6 1 19 1
|
||||
7 2 6 1 19 1
|
||||
8 2 7 1 27 1
|
||||
9 2 7 1 4 1
|
||||
10 2 7 1 13 1
|
||||
11 1 7 2
|
||||
12 2 7 1 8 1
|
||||
13 2 7 1 11 1
|
||||
14 2 7 1 21 1
|
||||
15 2 7 1 24 1
|
||||
16 2 6 1 23 1
|
||||
17 2 9 1 26 1
|
||||
18 1 1 2
|
||||
19 2 4 1 6 1
|
||||
20 1 26 2
|
||||
21 2 1 1 22 1
|
||||
22 2 0 1 26 1
|
||||
23 2 1 1 2 1
|
||||
24 2 7 1 18 1
|
||||
25 2 7 2 10 1
|
||||
26 2 7 1 24 1
|
||||
27 2 7 1 27 1
|
||||
28 2 7 1 11 1
|
||||
29 2 7 1 9 1
|
||||
30 2 7 1 25 1
|
||||
31 2 7 1 3 1
|
||||
32 2 3 1 8 1
|
||||
33 1 18 2
|
||||
34 2 8 1 25 1
|
||||
35 2 18 1 23 1
|
||||
36 2 8 1 19 1
|
||||
37 2 18 1 26 1
|
||||
38 2 8 1 22 1
|
||||
39 2 18 1 24 1
|
||||
40 1 7 2
|
||||
41 2 7 1 8 1
|
||||
42 2 7 1 11 1
|
||||
43 2 7 1 24 1
|
||||
44 2 7 1 10 1
|
||||
45 2 7 1 25 1
|
||||
46 2 7 1 4 1
|
||||
47 2 7 1 18 1
|
||||
48 1 3 2
|
||||
49 2 7 1 18 1
|
||||
50 1 23 2
|
||||
51 2 19 1 26 1
|
||||
52 2 18 1 22 1
|
||||
53 2 1 1 3 1
|
||||
54 2 1 1 2 1
|
||||
55 1 22 2
|
||||
56 2 7 1 24 1
|
||||
57 2 7 1 18 1
|
||||
58 2 7 1 8 1
|
||||
59 2 7 1 10 1
|
||||
60 2 7 1 21 1
|
||||
61 2 7 1 11 1
|
||||
62 2 7 1 25 1
|
||||
63 2 7 1 6 1
|
||||
64 2 12 1 26 1
|
||||
65 2 12 1 20 1
|
||||
66 2 12 1 21 1
|
||||
67 2 12 1 19 1
|
||||
68 2 12 1 22 1
|
||||
69 1 12 2
|
||||
70 2 12 1 22 1
|
||||
71 2 12 1 23 1
|
||||
72 2 12 1 18 1
|
||||
73 2 12 1 7 1
|
||||
74 2 12 1 25 1
|
||||
75 2 12 1 11 1
|
||||
76 2 12 1 8 1
|
||||
77 2 12 1 21 1
|
||||
78 1 12 2
|
||||
79 2 12 1 24 1
|
||||
80 2 3 1 6 1
|
||||
81 2 20 1 22 1
|
||||
82 2 19 1 22 1
|
||||
83 2 6 1 26 1
|
||||
84 1 22 2
|
||||
85 2 2 1 19 1
|
||||
86 2 6 1 18 1
|
||||
87 2 19 1 22 1
|
||||
88 2 7 1 18 1
|
||||
89 2 7 1 8 1
|
||||
90 2 7 1 25 1
|
||||
91 1 7 2
|
||||
92 2 7 1 11 1
|
||||
93 2 7 1 3 2
|
||||
94 2 7 1 24 1
|
||||
95 2 7 1 21 1
|
||||
96 2 22 1 10 1
|
||||
97 2 22 1 20 1
|
||||
98 2 22 1 1 1
|
||||
99 2 22 1 3 1
|
||||
100 2 22 1 0 1
|
||||
101 2 22 1 26 1
|
||||
102 1 22 2
|
||||
103 2 22 1 19 1
|
||||
104 2 7 1 25 1
|
||||
105 2 7 1 6 1
|
||||
106 2 7 1 2 1
|
||||
107 2 7 1 19 1
|
||||
108 2 7 1 20 1
|
||||
109 2 7 1 22 1
|
||||
110 2 7 1 11 1
|
||||
111 2 7 1 26 1
|
||||
112 2 23 1 26 1
|
||||
113 2 23 1 6 1
|
||||
114 2 23 1 1 1
|
||||
115 1 23 2
|
||||
116 2 23 1 22 1
|
||||
117 2 23 1 0 1
|
||||
118 2 23 1 20 1
|
||||
119 2 23 1 3 1
|
||||
120 1 7 2
|
||||
121 2 7 1 8 1
|
||||
122 2 7 1 5 1
|
||||
123 2 7 1 27 1
|
||||
124 2 7 1 21 1
|
||||
125 2 7 1 25 1
|
||||
126 2 7 1 24 1
|
||||
127 2 7 1 11 1
|
||||
128 2 20 1 22 1
|
||||
129 2 13 1 19 1
|
||||
130 2 20 1 22 1
|
||||
131 1 19 2
|
||||
132 2 2 1 22 1
|
||||
133 2 13 1 19 1
|
||||
134 1 22 2
|
||||
135 2 19 1 21 1
|
||||
136 2 7 1 14 1
|
||||
137 2 7 1 15 1
|
||||
138 2 7 1 16 1
|
||||
139 2 7 1 17 1
|
||||
140 2 7 1 14 1
|
||||
141 2 7 1 15 1
|
||||
142 2 7 1 16 1
|
||||
143 2 7 1 17 1
|
||||
144 1 6 2
|
||||
145 2 7 1 14 3
|
||||
146 2 6 1 22 1
|
||||
147 1 7 2
|
||||
148 2 1 1 6 1
|
||||
149 1 22 2
|
||||
150 1 12 2
|
||||
151 2 13 1 19 1
|
||||
152 2 6 1 23 1
|
||||
153 2 13 1 19 1
|
||||
154 2 19 1 22 1
|
||||
155 2 6 1 19 1
|
||||
-1
|
@ -14,17 +14,17 @@ CHeroClass::CHeroClass()
|
||||
CHeroClass::~CHeroClass()
|
||||
{
|
||||
}
|
||||
int CHeroClass::chooseSecSkill(std::set<int> possibles) //picks secondary skill out from given possibilities
|
||||
int CHeroClass::chooseSecSkill(const std::set<int> & possibles) const //picks secondary skill out from given possibilities
|
||||
{
|
||||
if(possibles.size()==1)
|
||||
return *possibles.begin();
|
||||
int totalProb = 0;
|
||||
for(std::set<int>::iterator i=possibles.begin(); i!=possibles.end(); i++)
|
||||
for(std::set<int>::const_iterator i=possibles.begin(); i!=possibles.end(); i++)
|
||||
{
|
||||
totalProb += proSec[*i];
|
||||
}
|
||||
int ran = rand()%totalProb;
|
||||
for(std::set<int>::iterator i=possibles.begin(); i!=possibles.end(); i++)
|
||||
for(std::set<int>::const_iterator i=possibles.begin(); i!=possibles.end(); i++)
|
||||
{
|
||||
ran -= proSec[*i];
|
||||
if(ran<0)
|
||||
@ -111,6 +111,35 @@ void CHeroHandler::loadHeroes()
|
||||
nher->ID = heroes.size();
|
||||
heroes.push_back(nher);
|
||||
}
|
||||
//loading initial secondary skills
|
||||
std::ifstream inp;
|
||||
inp.open("config" PATHSEPARATOR "heroes_sec_skills.txt", std::ios_base::in|std::ios_base::binary);
|
||||
if(!inp.is_open())
|
||||
{
|
||||
tlog1<<"missing file: config/heroes_sec_skills.txt"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
inp>>dump;
|
||||
int hid; //ID of currently read hero
|
||||
int secQ; //number of secondary abilities
|
||||
while(true)
|
||||
{
|
||||
inp>>hid;
|
||||
if(hid == -1)
|
||||
break;
|
||||
inp>>secQ;
|
||||
for(int g=0; g<secQ; ++g)
|
||||
{
|
||||
int a, b;
|
||||
inp>>a; inp>>b;
|
||||
heroes[hid]->secSkillsInit.push_back(std::make_pair(a, b));
|
||||
}
|
||||
}
|
||||
inp.close();
|
||||
}
|
||||
//initial skills loaded
|
||||
|
||||
loadSpecialAbilities();
|
||||
loadBiographies();
|
||||
loadHeroClasses();
|
||||
|
@ -20,6 +20,7 @@ public:
|
||||
bool isAllowed; //true if we can play with this hero (depends on map)
|
||||
CHeroClass * heroClass;
|
||||
EHeroClasses heroType; //hero class
|
||||
std::vector<std::pair<int,int> > secSkillsInit; //initial secondaryskills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
|
||||
//bool operator<(CHero& drugi){if (ID < drugi.ID) return true; else return false;}
|
||||
};
|
||||
|
||||
@ -35,7 +36,7 @@ public:
|
||||
int selectionProbability[9]; //probability of selection in towns
|
||||
std::vector<int> terrCosts; //default costs of going through terrains: dirt, sand, grass, snow, swamp, rough, subterrain, lava, water, rock; -1 means terrain is imapassable
|
||||
CDefHandler * moveAnim; //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
||||
int chooseSecSkill(std::set<int> possibles); //picks secondary skill out from given possibilities
|
||||
int chooseSecSkill(const std::set<int> & possibles) const; //picks secondary skill out from given possibilities
|
||||
CHeroClass();
|
||||
~CHeroClass();
|
||||
};
|
||||
|
@ -275,6 +275,10 @@ int CGHeroInstance::getCurrentMorale() const
|
||||
//TODO: write it
|
||||
return 0;
|
||||
}
|
||||
int CGHeroInstance::getPrimSkillLevel(int id) const
|
||||
{
|
||||
return primSkills[id];
|
||||
}
|
||||
int CGHeroInstance::getSecSkillLevel(const int & ID) const
|
||||
{
|
||||
for(int i=0;i<secSkills.size();i++)
|
||||
|
@ -92,7 +92,7 @@ public:
|
||||
int portrait; //may be custom
|
||||
int mana; // remaining spell points
|
||||
std::vector<int> primSkills; //0-attack, 1-defence, 2-spell power, 3-knowledge
|
||||
std::vector<std::pair<int,int> > secSkills; //first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
|
||||
std::vector<std::pair<int,int> > secSkills; //first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert); if hero has ability (-1, -1) it meansthat it should have default secondary abilities
|
||||
int movement; //remaining movement points
|
||||
int identifier; //from the map file
|
||||
bool sex;
|
||||
@ -125,6 +125,7 @@ public:
|
||||
bool canWalkOnSea() const;
|
||||
int getCurrentLuck() const;
|
||||
int getCurrentMorale() const;
|
||||
int getPrimSkillLevel(int id) const;
|
||||
int getSecSkillLevel(const int & ID) const; //0 - no skill
|
||||
ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact
|
||||
void setArtAtPos(ui16 pos, int art);
|
||||
|
4
map.cpp
4
map.cpp
@ -1052,6 +1052,10 @@ void Mapa::loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i )
|
||||
nhi->secSkills[yy].second = readNormalNr(bufor,i, 1); ++i;
|
||||
}
|
||||
}
|
||||
else //set default secondary skils
|
||||
{
|
||||
nhi->secSkills.push_back(std::make_pair(-1, -1));
|
||||
}
|
||||
if(readChar(bufor,i))//true if hero has nonstandard garrison
|
||||
nhi->army = readCreatureSet(bufor,i,7,(version>RoE));
|
||||
nhi->army.formation =bufor[i]; ++i; //formation
|
||||
|
@ -349,11 +349,11 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
|
||||
delete battleResult.data;
|
||||
|
||||
}
|
||||
void prepareAttack(BattleAttack &bat, CStack *att, CStack *def)
|
||||
void CGameHandler::prepareAttack(BattleAttack &bat, CStack *att, CStack *def, bool shooting)
|
||||
{
|
||||
bat.stackAttacking = att->ID;
|
||||
bat.bsa.stackAttacked = def->ID;
|
||||
bat.bsa.damageAmount = BattleInfo::calculateDmg(att, def);//counting dealt damage
|
||||
bat.bsa.damageAmount = BattleInfo::calculateDmg(att, def, gs->getHero(att->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), gs->getHero(def->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), shooting);//counting dealt damage
|
||||
|
||||
//applying damages
|
||||
bat.bsa.killedAmount = bat.bsa.damageAmount / def->creature->hitPoints;
|
||||
@ -948,14 +948,14 @@ upgend:
|
||||
return;
|
||||
|
||||
BattleAttack bat;
|
||||
prepareAttack(bat,curStack,stackAtEnd);
|
||||
prepareAttack(bat,curStack,stackAtEnd,false);
|
||||
sendAndApply(&bat);
|
||||
//counterattack
|
||||
if(!vstd::contains(curStack->abilities,NO_ENEMY_RETALIATION)
|
||||
&& stackAtEnd->alive()
|
||||
&& stackAtEnd->counterAttacks ) //TODO: support for multiple retaliatons per turn
|
||||
{
|
||||
prepareAttack(bat,stackAtEnd,curStack);
|
||||
prepareAttack(bat,stackAtEnd,curStack,false);
|
||||
bat.flags |= 2;
|
||||
sendAndApply(&bat);
|
||||
}
|
||||
@ -965,7 +965,7 @@ upgend:
|
||||
&& stackAtEnd->alive() )
|
||||
{
|
||||
bat.flags = 0;
|
||||
prepareAttack(bat,curStack,stackAtEnd);
|
||||
prepareAttack(bat,curStack,stackAtEnd,false);
|
||||
sendAndApply(&bat);
|
||||
}
|
||||
sendDataToClients(ui16(3008)); //end movement and attack
|
||||
@ -981,13 +981,13 @@ upgend:
|
||||
*destStack= gs->curB->getStackT(ba.destinationTile);
|
||||
|
||||
BattleAttack bat;
|
||||
prepareAttack(bat,curStack,destStack);
|
||||
prepareAttack(bat,curStack,destStack,true);
|
||||
bat.flags |= 1;
|
||||
|
||||
if(vstd::contains(curStack->abilities,TWICE_ATTACK)
|
||||
&& curStack->alive())
|
||||
{
|
||||
prepareAttack(bat,curStack,destStack);
|
||||
prepareAttack(bat,curStack,destStack,true);
|
||||
sendAndApply(&bat);
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ struct StartInfo;
|
||||
class CCPPObjectScript;
|
||||
class CScriptCallback;
|
||||
struct BattleResult;
|
||||
struct BattleAttack;
|
||||
template <typename T> struct CPack;
|
||||
template <typename T> struct Query;
|
||||
class CGHeroInstance;
|
||||
@ -56,6 +57,7 @@ class CGameHandler
|
||||
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
|
||||
void moveStack(int stack, int dest);
|
||||
void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
|
||||
void prepareAttack(BattleAttack &bat, CStack *att, CStack *def, bool shooting); //if last parameter is true, attack is by shooting, if false it's a melee attack
|
||||
|
||||
void checkForBattleEnd( std::vector<CStack*> &stacks );
|
||||
void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 );
|
||||
|
Loading…
x
Reference in New Issue
Block a user