diff --git a/CAmbarCendamo.cpp b/CAmbarCendamo.cpp
index d50bf74b5..209c126b4 100644
--- a/CAmbarCendamo.cpp
+++ b/CAmbarCendamo.cpp
@@ -406,7 +406,7 @@ void CAmbarCendamo::deh3m()
THC std::cout<<"Wczytywanie defow: "<
objh->objInstances.size();
@@ -415,6 +415,11 @@ void CAmbarCendamo::deh3m()
nobj.z = bufor[i++];
nobj.defNumber = readNormalNr(i, 4); i+=4;
i+=5;
+ unsigned char buff [30];
+ for(int ccc=0; ccc<30; ++ccc)
+ {
+ buff[ccc] = bufor[i+ccc];
+ }
EDefType uu = getDefType(map.defy[nobj.defNumber]);
int j = map.defy[nobj.defNumber].bytes[16];
int p = 99;
@@ -442,6 +447,7 @@ void CAmbarCendamo::deh3m()
{
spec->guarders = readCreatureSet(i); i+=32;
}
+ i+=4;
}
else
{
@@ -990,6 +996,7 @@ void CAmbarCendamo::deh3m()
{
spec->r5type = bufor[i]; ++i;
spec->r5amount = readNormalNr(i, 3); i+=3;
+ i+=1;
break;
}
case 6:
@@ -1203,54 +1210,59 @@ void CAmbarCendamo::deh3m()
int numberOfEvent = readNormalNr(i); i+=4;
- CCastleEvent nce;
- int nameLen = readNormalNr(i); i+=4;
- for(int ll=0; llevents.push_back(nce);
}
/////// castle events have been read ///////////////////////////
- i+=4;
+ spec->alignment = bufor[i]; ++i;
+ i+=3;
nobj.info = spec;
break;
}
- case EDefType::MINE_DEF:
+ case EDefType::PLAYERONLY_DEF:
{
- CMineObjInfo * spec = new CMineObjInfo;
+ CPlayerOnlyObjInfo * spec = new CPlayerOnlyObjInfo;
spec->player = bufor[i]; ++i;
i+=3;
nobj.info = spec;
@@ -1263,6 +1275,350 @@ void CAmbarCendamo::deh3m()
nobj.info = spec;
break;
}
+ case EDefType::SPELLSCROLL_DEF:
+ {
+ CSpellScrollObjinfo * spec = new CSpellScrollObjinfo;
+ bool messg = bufor[i]; ++i;
+ if(messg)
+ {
+ int mLength = readNormalNr(i); i+=4;
+ for(int vv=0; vvmessage += bufor[i]; ++i;
+ }
+ spec->areGuarders = bufor[i]; ++i;
+ if(spec->areGuarders)
+ {
+ spec->guarders = readCreatureSet(i); i+=28;
+ }
+ i+=4;
+ }
+ spec->spell = &(CGameInfo::mainObj->spellh->spells[bufor[i]]); ++i;
+ i+=3;
+ nobj.info = spec;
+ break;
+ }
+ case EDefType::PANDORA_DEF:
+ {
+ CPandorasBoxObjInfo * spec = new CPandorasBoxObjInfo;
+ bool messg = bufor[i]; ++i;
+ if(messg)
+ {
+ int mLength = readNormalNr(i); i+=4;
+ for(int vv=0; vvmessage += bufor[i]; ++i;
+ }
+ spec->areGuarders = bufor[i]; ++i;
+ if(spec->areGuarders)
+ {
+ spec->guarders = readCreatureSet(i); i+=28;
+ }
+ i+=4;
+ }
+ ////// copied form event handling (seems to be similar)
+ spec->gainedExp = readNormalNr(i, 4); i+=4;
+ spec->manaDiff = readNormalNr(i, 4); i+=4;
+ spec->moraleDiff = readNormalNr(i, 1, true); ++i;
+ spec->luckDiff = readNormalNr(i, 1, true); ++i;
+ spec->wood = readNormalNr(i); i+=4;
+ spec->mercury = readNormalNr(i); i+=4;
+ spec->ore = readNormalNr(i); i+=4;
+ spec->sulfur = readNormalNr(i); i+=4;
+ spec->crystal = readNormalNr(i); i+=4;
+ spec->gems = readNormalNr(i); i+=4;
+ spec->gold = readNormalNr(i); i+=4;
+ spec->attack = readNormalNr(i, 1); ++i;
+ spec->defence = readNormalNr(i, 1); ++i;
+ spec->power = readNormalNr(i, 1); ++i;
+ spec->knowledge = readNormalNr(i, 1); ++i;
+ int gabn; //number of gained abilities
+ gabn = readNormalNr(i, 1); ++i;
+ for(int oo = 0; ooabilities.push_back(&((CGameInfo::mainObj->abilh)->abilities[readNormalNr(i, 1)])); ++i;
+ spec->abilityLevels.push_back(readNormalNr(i, 1)); ++i;
+ }
+ int gart = readNormalNr(i, 1); ++i; //number of gained artifacts
+ for(int oo = 0; ooartifacts.push_back(&(CGameInfo::mainObj->arth->artifacts[readNormalNr(i, 2)])); i+=2;
+ }
+ int gspel = readNormalNr(i, 1); ++i; //number of gained spells
+ for(int oo = 0; oospells.push_back(&(CGameInfo::mainObj->spellh->spells[readNormalNr(i, 1)])); ++i;
+ }
+ int gcre = readNormalNr(i, 1); ++i; //number of gained creatures
+ spec->creatures = readCreatureSet(i, gcre); i+=4*gcre;
+ i+=8;
+ nobj.info = spec;
+ ///////end of copied fragment
+ break;
+ }
+ case EDefType::GRAIL_DEF:
+ {
+ CGrailObjInfo * spec = new CGrailObjInfo;
+ spec->radius = readNormalNr(i); i+=4;
+ nobj.info = spec;
+ break;
+ }
+ case EDefType::CREGEN_DEF:
+ {
+ CCreGenObjInfo * spec = new CCreGenObjInfo;
+ spec->player = bufor[i]; ++i;
+ i+=3;
+ for(int ggg=0; ggg<4; ++ggg)
+ {
+ spec->bytes[ggg] = bufor[i]; ++i;
+ }
+ if((spec->bytes[0] == '\0') && (spec->bytes[1] == '\0') && (spec->bytes[2] == '\0') && (spec->bytes[3] == '\0'))
+ {
+ spec->asCastle = false;
+ spec->castles[0] = bufor[i]; ++i;
+ spec->castles[1] = bufor[i]; ++i;
+ }
+ else
+ {
+ spec->asCastle = true;
+ }
+ nobj.info = spec;
+ break;
+ }
+ case EDefType::CREGEN2_DEF:
+ {
+ CCreGen2ObjInfo * spec = new CCreGen2ObjInfo;
+ spec->player = bufor[i]; ++i;
+ i+=3;
+ for(int ggg=0; ggg<4; ++ggg)
+ {
+ spec->bytes[ggg] = bufor[i]; ++i;
+ }
+ if((spec->bytes[0] == '\0') && (spec->bytes[1] == '\0') && (spec->bytes[2] == '\0') && (spec->bytes[3] == '\0'))
+ {
+ spec->asCastle = false;
+ spec->castles[0] = bufor[i]; ++i;
+ spec->castles[1] = bufor[i]; ++i;
+ }
+ else
+ {
+ spec->asCastle = true;
+ }
+ spec->minLevel = bufor[i]; ++i;
+ spec->maxLevel = bufor[i]; ++i;
+ nobj.info = spec;
+ break;
+ }
+ case EDefType::CREGEN3_DEF:
+ {
+ CCreGen3ObjInfo * spec = new CCreGen3ObjInfo;
+ spec->player = bufor[i]; ++i;
+ i+=3;
+ spec->minLevel = bufor[i]; ++i;
+ spec->maxLevel = bufor[i]; ++i;
+ nobj.info = spec;
+ break;
+ }
+ case EDefType::BORDERGUARD_DEF:
+ {
+ CBorderGuardObjInfo * spec = new CBorderGuardObjInfo;
+ spec->missionType = bufor[i]; ++i;
+ switch(spec->missionType)
+ {
+ case 1:
+ {
+ spec->m1level = readNormalNr(i); i+=4;
+ int limit = readNormalNr(i); i+=4;
+ if(limit == ((int)0xffffffff))
+ {
+ spec->isDayLimit = false;
+ spec->lastDay = -1;
+ }
+ else
+ {
+ spec->isDayLimit = true;
+ spec->lastDay = limit;
+ }
+ break;
+ }
+ case 2:
+ {
+ spec->m2attack = bufor[i]; ++i;
+ spec->m2defence = bufor[i]; ++i;
+ spec->m2power = bufor[i]; ++i;
+ spec->m2knowledge = bufor[i]; ++i;
+ int limit = readNormalNr(i); i+=4;
+ if(limit == ((int)0xffffffff))
+ {
+ spec->isDayLimit = false;
+ spec->lastDay = -1;
+ }
+ else
+ {
+ spec->isDayLimit = true;
+ spec->lastDay = limit;
+ }
+ break;
+ }
+ case 3:
+ {
+ spec->m3bytes[0] = bufor[i]; ++i;
+ spec->m3bytes[1] = bufor[i]; ++i;
+ spec->m3bytes[2] = bufor[i]; ++i;
+ spec->m3bytes[3] = bufor[i]; ++i;
+ int limit = readNormalNr(i); i+=4;
+ if(limit == ((int)0xffffffff))
+ {
+ spec->isDayLimit = false;
+ spec->lastDay = -1;
+ }
+ else
+ {
+ spec->isDayLimit = true;
+ spec->lastDay = limit;
+ }
+ break;
+ }
+ case 4:
+ {
+ spec->m4bytes[0] = bufor[i]; ++i;
+ spec->m4bytes[1] = bufor[i]; ++i;
+ spec->m4bytes[2] = bufor[i]; ++i;
+ spec->m4bytes[3] = bufor[i]; ++i;
+ int limit = readNormalNr(i); i+=4;
+ if(limit == ((int)0xffffffff))
+ {
+ spec->isDayLimit = false;
+ spec->lastDay = -1;
+ }
+ else
+ {
+ spec->isDayLimit = true;
+ spec->lastDay = limit;
+ }
+ break;
+ }
+ case 5:
+ {
+ int artNumber = bufor[i]; ++i;
+ for(int yy=0; yym5arts.push_back(&(CGameInfo::mainObj->arth->artifacts[artid]));
+ }
+ int limit = readNormalNr(i); i+=4;
+ if(limit == ((int)0xffffffff))
+ {
+ spec->isDayLimit = false;
+ spec->lastDay = -1;
+ }
+ else
+ {
+ spec->isDayLimit = true;
+ spec->lastDay = limit;
+ }
+ break;
+ }
+ case 6:
+ {
+ int typeNumber = bufor[i]; ++i;
+ for(int hh=0; hhm6cre.push_back(&(CGameInfo::mainObj->creh->creatures[creType]));
+ spec->m6number.push_back(creNumb);
+ }
+ int limit = readNormalNr(i); i+=4;
+ if(limit == ((int)0xffffffff))
+ {
+ spec->isDayLimit = false;
+ spec->lastDay = -1;
+ }
+ else
+ {
+ spec->isDayLimit = true;
+ spec->lastDay = limit;
+ }
+ break;
+ }
+ case 7:
+ {
+ spec->m7wood = readNormalNr(i); i+=4;
+ spec->m7mercury = readNormalNr(i); i+=4;
+ spec->m7ore = readNormalNr(i); i+=4;
+ spec->m7sulfur = readNormalNr(i); i+=4;
+ spec->m7crystal = readNormalNr(i); i+=4;
+ spec->m7gems = readNormalNr(i); i+=4;
+ spec->m7gold = readNormalNr(i); i+=4;
+ int limit = readNormalNr(i); i+=4;
+ if(limit == ((int)0xffffffff))
+ {
+ spec->isDayLimit = false;
+ spec->lastDay = -1;
+ }
+ else
+ {
+ spec->isDayLimit = true;
+ spec->lastDay = limit;
+ }
+ break;
+ }
+ case 8:
+ {
+ int heroType = bufor[i]; ++i;
+ spec->m8hero = &(CGameInfo::mainObj->heroh->heroes[heroType]);
+ int limit = readNormalNr(i); i+=4;
+ if(limit == ((int)0xffffffff))
+ {
+ spec->isDayLimit = false;
+ spec->lastDay = -1;
+ }
+ else
+ {
+ spec->isDayLimit = true;
+ spec->lastDay = limit;
+ }
+ break;
+ }
+ case 9:
+ {
+ spec->m9player = bufor[i]; ++i;
+ int limit = readNormalNr(i); i+=4;
+ if(limit == ((int)0xffffffff))
+ {
+ spec->isDayLimit = false;
+ spec->lastDay = -1;
+ }
+ else
+ {
+ spec->isDayLimit = true;
+ spec->lastDay = limit;
+ }
+ break;
+ }
+ }//internal switch end (seer huts)
+
+ int len1 = readNormalNr(i); i+=4;
+ for(int ee=0; eefirstVisitText += bufor[i]; ++i;
+ }
+
+ int len2 = readNormalNr(i); i+=4;
+ for(int ee=0; eenextVisitText += bufor[i]; ++i;
+ }
+
+ int len3 = readNormalNr(i); i+=4;
+ for(int ee=0; eecompletedText += bufor[i]; ++i;
+ }
+ nobj.info = spec;
+ break;
+ }
} //end of main switch
CGameInfo::mainObj->objh->objInstances.push_back(nobj);
//TODO - dokończyć, dużo do zrobienia - trzeba patrzeć, co def niesie
@@ -1300,7 +1656,7 @@ void CAmbarCendamo::loadDefs()
loadedTypes.insert(map.terrain[i][j].tertype);
defs.push_back(sdh);
}
- if (loadedTypes.find(map.undergroungTerrain[i][j].tertype)==loadedTypes.end())
+ if (map.twoLevel && loadedTypes.find(map.undergroungTerrain[i][j].tertype)==loadedTypes.end())
{
CSemiDefHandler *sdh = new CSemiDefHandler();
sdh->openDef((sdh->nameFromType(map.undergroungTerrain[i][j].tertype)).c_str(),"H3sprite.lod");
@@ -1315,23 +1671,27 @@ EDefType CAmbarCendamo::getDefType(DefInfo &a)
{
switch(a.bytes[16])
{
- case 5:
+ case 5: case 65: case 66: case 67: case 68: case 69:
return EDefType::ARTIFACT_DEF; //handled
+ case 6:
+ return EDefType::PANDORA_DEF; //hanled
case 26:
return EDefType::EVENTOBJ_DEF; //handled
case 33:
return EDefType::GARRISON_DEF; //handled
- case 34:
+ case 34: case 70: //70 - random hero
return EDefType::HERO_DEF; //handled
- case 53: case 17: case 18: case 19: case 20: //cases 17 - 20 - tests
- return EDefType::MINE_DEF; //handled
- case 54: case 71: case 72: case 73: case 74: case 75:
+ case 36:
+ return EDefType::GRAIL_DEF; //hanled
+ case 53: case 17: case 18: case 19: case 20: case 42: case 87: //cases 17 - 20 and 42 - tests
+ return EDefType::PLAYERONLY_DEF; //handled
+ case 54: case 71: case 72: case 73: case 74: case 75: case 162: case 163: case 164:
return EDefType::CREATURES_DEF; //handled
case 59:
return EDefType::SIGN_DEF; //handled
case 77:
return EDefType::TOWN_DEF; //can be problematic, but handled
- case 79:
+ case 79: case 76:
return EDefType::RESOURCE_DEF; //handled
case 81:
return EDefType::SCHOLAR_DEF; //handled
@@ -1341,10 +1701,20 @@ EDefType CAmbarCendamo::getDefType(DefInfo &a)
return EDefType::SIGN_DEF; //handled
case 88: case 89: case 90:
return SHRINE_DEF; //handled
+ case 93:
+ return SPELLSCROLL_DEF; //handled
case 98:
return EDefType::TOWN_DEF; //handled
case 113:
return EDefType::WITCHHUT_DEF; //handled
+ case 215:
+ return EDefType::BORDERGUARD_DEF; //handled by analogy to seer huts ;]
+ case 216:
+ return EDefType::CREGEN2_DEF; //handled
+ case 217:
+ return EDefType::CREGEN_DEF; //handled
+ case 218:
+ return EDefType::CREGEN3_DEF; //handled
case 219:
return EDefType::GARRISON_DEF; //handled
default:
diff --git a/CAmbarCendamo.h b/CAmbarCendamo.h
index 5911d8a83..f1f810602 100644
--- a/CAmbarCendamo.h
+++ b/CAmbarCendamo.h
@@ -10,7 +10,7 @@
#include "CSemiDefHandler.h"
#include "CCreatureHandler.h"
-enum EDefType {TOWN_DEF, HERO_DEF, CREATURES_DEF, SEERHUT_DEF, RESOURCE_DEF, TERRAINOBJ_DEF, EVENTOBJ_DEF, SIGN_DEF, GARRISON_DEF, ARTIFACT_DEF, WITCHHUT_DEF, SCHOLAR_DEF, MINE_DEF, SHRINE_DEF};
+enum EDefType {TOWN_DEF, HERO_DEF, CREATURES_DEF, SEERHUT_DEF, RESOURCE_DEF, TERRAINOBJ_DEF, EVENTOBJ_DEF, SIGN_DEF, GARRISON_DEF, ARTIFACT_DEF, WITCHHUT_DEF, SCHOLAR_DEF, PLAYERONLY_DEF, SHRINE_DEF, SPELLSCROLL_DEF, PANDORA_DEF, GRAIL_DEF, CREGEN_DEF, CREGEN2_DEF, CREGEN3_DEF, BORDERGUARD_DEF};
class CAmbarCendamo
{
diff --git a/CCastleHandler.h b/CCastleHandler.h
index 6829465d4..dd026a9c6 100644
--- a/CCastleHandler.h
+++ b/CCastleHandler.h
@@ -44,6 +44,8 @@ public:
std::vector availableSpells;
std::vector events;
+
+ unsigned char alignment; //what the hell is that??
};
#endif //CCASTLEHANDLER_H
\ No newline at end of file
diff --git a/CMT.cpp b/CMT.cpp
index 506ec17fb..c6f8b3bcc 100644
--- a/CMT.cpp
+++ b/CMT.cpp
@@ -324,6 +324,8 @@ int _tmain(int argc, _TCHAR* argv[])
}
case (SDLK_u):
{
+ if(!ac->map.twoLevel)
+ break;
if (zz)
zz--;
else zz++;
diff --git a/CObjectHandler.h b/CObjectHandler.h
index 9b9430431..30c864ea9 100644
--- a/CObjectHandler.h
+++ b/CObjectHandler.h
@@ -178,7 +178,7 @@ public:
std::string message;
};
-class CMineObjInfo : public CSpecObjInfo
+class CPlayerOnlyObjInfo : public CSpecObjInfo
{
public:
unsigned char player; //FF - nobody, 0 - 7
@@ -190,6 +190,97 @@ public:
unsigned char spell; //number of spell or 255
};
+class CSpellScrollObjinfo : public CSpecObjInfo
+{
+public:
+ std::string message;
+ CSpell * spell;
+ bool areGuarders;
+ CCreatureSet guarders;
+};
+
+class CPandorasBoxObjInfo : public CSpecObjInfo
+{
+public:
+ std::string message;
+ bool areGuarders;
+ CCreatureSet guarders;
+
+ //gained things:
+ unsigned int gainedExp;
+ int manaDiff;
+ int moraleDiff;
+ int luckDiff;
+ int wood, mercury, ore, sulfur, crystal, gems, gold;
+ int attack, defence, power, knowledge;
+ std::vector abilities;
+ std::vector abilityLevels;
+ std::vector artifacts;
+ std::vector spells;
+ CCreatureSet creatures;
+};
+
+class CGrailObjInfo : public CSpecObjInfo
+{
+public:
+ int radius; //place grail at the distance lesser or equal radius from this place
+};
+
+class CCreGenObjInfo : public CSpecObjInfo
+{
+public:
+ unsigned char player; //owner
+ bool asCastle;
+ unsigned char bytes[4]; //castle identifier
+ unsigned char castles[2]; //allowed castles
+};
+
+class CCreGen2ObjInfo : public CSpecObjInfo
+{
+public:
+ unsigned char player; //owner
+ bool asCastle;
+ unsigned char bytes[4]; //castle identifier
+ unsigned char castles[2]; //allowed castles
+ unsigned char minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6>
+};
+
+class CCreGen3ObjInfo : public CSpecObjInfo
+{
+public:
+ unsigned char player; //owner
+ unsigned char minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6>
+};
+
+class CBorderGuardObjInfo : public CSpecObjInfo //copied form seer huts, seems to be similar
+{
+public:
+ char missionType; //type of mission: 0 - no mission; 1 - reach level; 2 - reach main statistics values; 3 - win with a certain hero; 4 - win with a certain creature; 5 - collect some atifacts; 6 - have certain troops in army; 7 - collect resources; 8 - be a certain hero; 9 - be a certain player
+ bool isDayLimit; //if true, there is a day limit
+ int lastDay; //after this day (first day is 0) mission cannot be completed
+ //for mission 1
+ int m1level;
+ //for mission 2
+ int m2attack, m2defence, m2power, m2knowledge;
+ //for mission 3
+ unsigned char m3bytes[4];
+ //for mission 4
+ unsigned char m4bytes[4];
+ //for mission 5
+ std::vector m5arts;
+ //for mission 6
+ std::vector m6cre;
+ std::vector m6number;
+ //for mission 7
+ int m7wood, m7mercury, m7ore, m7sulfur, m7crystal, m7gems, m7gold;
+ //for mission 8
+ CHero * m8hero;
+ //for mission 9
+ int m9player; //number; from 0 to 7
+
+ std::string firstVisitText, nextVisitText, completedText;
+};
+
class CObject //typical object that can be encountered on a map
{
public:
diff --git a/h3m.txt b/h3m.txt
index db241d322..a8b03c326 100644
Binary files a/h3m.txt and b/h3m.txt differ