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