1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

* partial implementation of SRSL parser (although it's enough for almost all Heroes III spells)

* config/spell_info.txt is now less unholy (its size is no more 666 bytes) :)
This commit is contained in:
mateuszb 2009-04-14 14:48:57 +00:00
parent d2e1c8d782
commit ece364f735
3 changed files with 247 additions and 73 deletions

View File

@ -1,73 +1,73 @@
//additional spell info, not included in original heroes III files
//[spellID - -1 is the end of data in file] [-1 -> spell is negative for influenced creatures; 0 - spell is indifferent for them; 1 - spell is poitive for them]
0 0
1 0
2 0
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
13 0
14 0
15 -1
16 -1
17 -1
18 -1
19 -1
20 -1
21 -1
22 -1
23 -1
24 -1
25 -1
26 -1
27 1
28 1
29 1
30 1
31 1
32 1
33 1
34 1
35 1
36 1
37 1
38 1
39 1
40 1
41 1
42 -1
43 1
44 1
45 -1
46 1
47 -1
48 1
49 1
50 -1
51 1
52 -1
53 1
54 -1
55 1
56 1
57 -1
58 1
59 -1
60 -1
61 -1
62 -1
63 1
64 0
65 1
66 0
67 0
68 0
69 0
//[spellID - -1 is the end of data in file] [-1 -> spell is negative for influenced creatures; 0 - spell is indifferent for them; 1 - spell is poitive for them] [spell range description in SRSL, none magic] [basic] [advanced] [expert]
0 0 X X X X
1 0 X X X X
2 0 X X X X
3 0 X X X X
4 0 X X X X
5 0 X X X X
6 0 X X X X
7 0 X X X X
8 0 X X X X
9 0 X X X X
10 0 X X X X
11 0 X X X X
12 0 0 0 0 0
13 0 0 0 0 0
14 0 X X X X
15 -1 0 0 0 0
16 -1 0 0 0 0
17 -1 0 0 0 0
18 -1 0 0 0 0
19 -1 0 0 0 0
20 -1 1 1 1 1
21 -1 0,1 0,1 0,1 0,1
22 -1 0-2 0-2 0-2 0-2
23 -1 0,1 0,1 0,1 0,1
24 -1 X X X X
25 -1 X X X X
26 -1 X X X X
27 1 0 0 0 X
28 1 0 0 0 X
29 1 0 0 0 X
30 1 0 0 0 X
31 1 0 0 0 X
32 1 0 0 0 X
33 1 0 0 0 X
34 1 0 0 0 X
35 1 0 0 0 X
36 1 0 0 0 0
37 1 0 0 0 0
38 1 0 0 0 0
39 1 0 0 0 0
40 1 0 0 0 0
41 1 0 0 0 X
42 -1 0 0 0 X
43 1 0 0 0 X
44 1 0 0 0 X
45 -1 0 0 0 X
46 1 0 0 0 X
47 -1 0 0 0 X
48 1 0 0 0 X
49 1 0 0 0 X
50 -1 0 0 0 X
51 1 0 0 0 X
52 -1 0 0 0 X
53 1 0 0 0 X
54 -1 0 0 0 X
55 1 0 0 0 0
56 1 0 0 0 0
57 -1 0 0 0 0
58 1 0 0 0 X
59 -1 0 0 0-1 0-2
60 -1 0 0 0 0
61 -1 0 0 0 X
62 -1 0 0 0 0
63 1 0 0 0 0
64 0 X X X X
65 1 0 0 0 0
66 0 X X X X
67 0 X X X X
68 0 X X X X
69 0 X X X X
-1

View File

@ -4,7 +4,175 @@
#include "CLodHandler.h"
#include "../lib/VCMI_Lib.h"
#include <boost/algorithm/string/replace.hpp>
#include <cctype>
extern CLodHandler *bitmaph;
namespace SRSLPraserHelpers
{
int XYToHex(int x, int y)
{
return x + 17 * y;
}
int XYToHex(std::pair<int, int> xy)
{
return XYToHex(xy.first, xy.second);
}
int hexToY(int battleFieldPosition)
{
return battleFieldPosition/17;
}
int hexToX(int battleFieldPosition)
{
int pos = battleFieldPosition - hexToY(battleFieldPosition) * 17;
return pos;
}
std::pair<int, int> hexToPair(int battleFieldPosition)
{
return std::make_pair(hexToX(battleFieldPosition), hexToY(battleFieldPosition));
}
//moves hex by one hex in given direction
//0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left
std::pair<int, int> gotoDir(int x, int y, int direction)
{
switch(direction)
{
case 0: //top left
return std::make_pair(y%2 ? x-1 : x, y-1);
case 1: //top right
return std::make_pair(y%2 ? x : x+1, y-1);
case 2: //right
return std::make_pair(x+1, y);
case 3: //right bottom
return std::make_pair(y%2 ? x : x+1, y+1);
case 4: //left bottom
return std::make_pair(y%2 ? x-1 : x, y+1);
case 5: //left
return std::make_pair(x-1, y);
}
}
std::pair<int, int> gotoDir(std::pair<int, int> xy, int direction)
{
return gotoDir(xy.first, xy.second, direction);
}
bool isGoodHex(std::pair<int, int> xy)
{
return xy.first >=0 && xy.first < 17 && xy.second >= 0 && xy.second < 11;
}
//helper fonction for std::set<ui16> CSpell::rangeInHexes(unsigned int centralHex, ui8 schoolLvl ) const
std::set<ui16> getInRange(unsigned int center, int low, int high)
{
std::set<ui16> ret;
if(low == 0)
{
ret.insert(center);
}
std::pair<int, int> mainPointForLayer[6]; //A, B, C, D, E, F points
for(int b=0; b<6; ++b)
mainPointForLayer[b] = hexToPair(center);
for(int it=1; it<=high; ++it) //it - distance to the center
{
for(int b=0; b<6; ++b)
mainPointForLayer[b] = gotoDir(mainPointForLayer[b], b);
if(it>=low)
{
std::pair<int, int> curHex;
//adding lines (A-b, B-c, C-d, etc)
for(int v=0; v<6; ++v)
{
curHex = mainPointForLayer[v];
for(int h=0; h<it; ++h)
{
if(isGoodHex(curHex))
ret.insert(XYToHex(curHex));
curHex = gotoDir(curHex, (v+2)%6);
}
}
} //if(it>=low)
}
return ret;
}
}
using namespace SRSLPraserHelpers;
std::set<ui16> CSpell::rangeInHexes(unsigned int centralHex, ui8 schoolLvl ) const
{
std::set<ui16> ret;
std::string rng = range[schoolLvl] + ','; //copy + artificial comma for easier handling
if(rng.size() >= 1 && rng[0] != 'X') //there is at lest one hex in range
{
std::string number1, number2;
int beg, end;
bool readingFirst = true;
for(int it=0; it<rng.size(); ++it)
{
if( std::isdigit(rng[it]) ) //reading numer
{
if(readingFirst)
number1 += rng[it];
else
number2 += rng[it];
}
else if(rng[it] == ',') //comma
{
//calculating variables
if(readingFirst)
{
beg = atoi(number1.c_str());
number1 = "";
}
else
{
end = atoi(number2.c_str());
number2 = "";
}
//obtaining new hexes
std::set<ui16> curLayer;
if(readingFirst)
{
curLayer = getInRange(centralHex, beg, beg);
}
else
{
curLayer = getInRange(centralHex, beg, end);
readingFirst = true;
}
//adding abtained hexes
for(std::set<ui16>::iterator it = curLayer.begin(); it != curLayer.end(); ++it)
{
ret.insert(*it);
}
}
else if(rng[it] == '-') //dash
{
beg = atoi(number1.c_str());
number1 = "";
readingFirst = false;
}
}
}
return ret;
}
void CSpellHandler::loadSpells()
{
std::string buf = bitmaph->getTextFile("SPTRAITS.TXT"), pom;
@ -90,7 +258,7 @@ void CSpellHandler::loadSpells()
{
//reading header
std::string dump;
for(int i=0; i<42; ++i) ast>>dump;
for(int i=0; i<52; ++i) ast>>dump;
//reading exact info
int spellID;
ast>>spellID;
@ -99,6 +267,9 @@ void CSpellHandler::loadSpells()
int buf;
ast>>buf;
spells[spellID].positiveness = buf;
spells[spellID].range.resize(4);
for(int g=0; g<4; ++g)
ast>>spells[spellID].range[g];
ast>>spellID;
}
}

View File

@ -3,6 +3,7 @@
#include <string>
#include <vector>
#include <set>
class CSpell
{
@ -25,12 +26,14 @@ public:
bool combatSpell; //is this spell combat (true) or adventure (false)
bool creatureAbility; //if true, only creatures can use this spell
si8 positiveness; //1 if spell is positive for influenced stacks, 0 if it is indifferent, -1 if it's negative
std::vector<std::string> range; //description of spell's range in SRSL by magic school level
std::set<ui16> rangeInHexes(unsigned int centralHex, ui8 schoolLvl ) const; //convert range to specific hexes
template <typename Handler> void serialize(Handler &h, const int version)
{
h & id & name & abbName & descriptions & level & earth & water & fire & air & power & costs
& powers & probabilities & AIVals & attributes & combatSpell & creatureAbility & positiveness;
& powers & probabilities & AIVals & attributes & combatSpell & creatureAbility & positiveness & range;
}
};