00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include "TypeFlags.h"
00022 #include "IDataSource.h"
00023 #include "ConfigFileManager.h"
00024 #include "CoreApp.h"
00025 #include "GameData.h"
00026 #include "MainShapeArchive.h"
00027 #include "Shape.h"
00028 #include "TreasureLoader.h"
00029 #include "GameInfo.h"
00030
00031 TypeFlags::TypeFlags()
00032 {
00033
00034 }
00035
00036
00037 TypeFlags::~TypeFlags()
00038 {
00039
00040 }
00041
00042 ShapeInfo* TypeFlags::getShapeInfo(uint32 shapenum)
00043 {
00044 if (shapenum < shapeInfo.size())
00045 return &(shapeInfo[shapenum]);
00046 else
00047 return 0;
00048 }
00049
00050
00051 void TypeFlags::load(IDataSource *ds)
00052 {
00053
00054
00055
00056
00057 unsigned int blocksize = 8;
00058 if (GAME_IS_CRUSADER) {
00059 blocksize = 9;
00060 }
00061
00062 uint32 size = ds->getSize();
00063 uint32 count = size / blocksize;
00064
00065 shapeInfo.clear();
00066 shapeInfo.resize(count);
00067
00068 for (uint32 i = 0; i < count; ++i)
00069 {
00070 uint8 data[9];
00071 ds->read(data, blocksize);
00072
00073 ShapeInfo si;
00074 si.flags = 0;
00075
00076 if (GAME_IS_U8) {
00077
00078 if (data[0] & 0x01) si.flags |= ShapeInfo::SI_FIXED;
00079 if (data[0] & 0x02) si.flags |= ShapeInfo::SI_SOLID;
00080 if (data[0] & 0x04) si.flags |= ShapeInfo::SI_SEA;
00081 if (data[0] & 0x08) si.flags |= ShapeInfo::SI_LAND;
00082 if (data[0] & 0x10) si.flags |= ShapeInfo::SI_OCCL;
00083 if (data[0] & 0x20) si.flags |= ShapeInfo::SI_BAG;
00084 if (data[0] & 0x40) si.flags |= ShapeInfo::SI_DAMAGING;
00085 if (data[0] & 0x80) si.flags |= ShapeInfo::SI_NOISY;
00086
00087 if (data[1] & 0x01) si.flags |= ShapeInfo::SI_DRAW;
00088 if (data[1] & 0x02) si.flags |= ShapeInfo::SI_IGNORE;
00089 if (data[1] & 0x04) si.flags |= ShapeInfo::SI_ROOF;
00090 if (data[1] & 0x08) si.flags |= ShapeInfo::SI_TRANSL;
00091 si.family = data[1] >> 4;
00092
00093 si.equiptype = data[2] & 0x0F;
00094 si.x = data[2] >> 4;
00095
00096 si.y = data[3] & 0x0F;
00097 si.z = data[3] >> 4;
00098
00099 si.animtype = data[4] & 0x0F;
00100 si.animdata = data[4] >> 4;
00101
00102 si.unknown = data[5] & 0x0F;
00103 if (data[5] & 0x10) si.flags |= ShapeInfo::SI_EDITOR;
00104 if (data[5] & 0x20) si.flags |= ShapeInfo::SI_EXPLODE;
00105 if (data[5] & 0x40) si.flags |= ShapeInfo::SI_UNKNOWN46;
00106 if (data[5] & 0x80) si.flags |= ShapeInfo::SI_UNKNOWN47;
00107
00108 si.weight = data[6];
00109
00110 si.volume = data[7];
00111
00112 } else if (GAME_IS_CRUSADER) {
00113
00114
00115
00116
00117 if (data[0] & 0x01) si.flags |= ShapeInfo::SI_FIXED;
00118 if (data[0] & 0x02) si.flags |= ShapeInfo::SI_SOLID;
00119 if (data[0] & 0x04) si.flags |= ShapeInfo::SI_SEA;
00120 if (data[0] & 0x08) si.flags |= ShapeInfo::SI_LAND;
00121 if (data[0] & 0x10) si.flags |= ShapeInfo::SI_OCCL;
00122 if (data[0] & 0x20) si.flags |= ShapeInfo::SI_BAG;
00123 if (data[0] & 0x40) si.flags |= ShapeInfo::SI_DAMAGING;
00124 if (data[0] & 0x80) si.flags |= ShapeInfo::SI_NOISY;
00125
00126
00127 if (data[1] & 0x01) si.flags |= ShapeInfo::SI_DRAW;
00128 if (data[1] & 0x02) si.flags |= ShapeInfo::SI_IGNORE;
00129 if (data[1] & 0x04) si.flags |= ShapeInfo::SI_ROOF;
00130 if (data[1] & 0x08) si.flags |= ShapeInfo::SI_TRANSL;
00131 si.family = data[1] >> 4;
00132 si.family += (data[2] & 1) << 4;
00133
00134
00135 si.x = ((data[3]<<3) | (data[2]>>5)) & 0x1F;
00136 si.y = (data[3] >> 2) & 0x1F;
00137 si.z = ((data[4]<<1) | (data[3]>>7)) & 0x1F;
00138
00139 if (data[6] & 0x01) si.flags |= ShapeInfo::SI_EDITOR;
00140 if (data[6] & 0x02) si.flags |= ShapeInfo::SI_CRUSUNK61;
00141 if (data[6] & 0x04) si.flags |= ShapeInfo::SI_CRUSUNK62;
00142 if (data[6] & 0x08) si.flags |= ShapeInfo::SI_CRUSUNK63;
00143 if (data[6] & 0x10) si.flags |= ShapeInfo::SI_CRUSUNK64;
00144 if (data[6] & 0x20) si.flags |= ShapeInfo::SI_CRUS_NPC;
00145 if (data[6] & 0x40) si.flags |= ShapeInfo::SI_CRUSUNK66;
00146 if (data[6] & 0x80) si.flags |= ShapeInfo::SI_CRUSUNK67;
00147
00148 si.animtype = 0;
00149
00150 }
00151
00152 si.weaponinfo = 0;
00153 si.armourinfo = 0;
00154
00155 shapeInfo[i] = si;
00156 }
00157
00158 if (GAME_IS_U8) {
00159
00160
00161 for(uint32 i = 459; i <= 464; ++i) {
00162 shapeInfo[i].flags &= ~ShapeInfo::SI_SOLID;
00163 }
00164 }
00165
00166 loadWeaponInfo();
00167 loadArmourInfo();
00168 loadMonsterInfo();
00169 }
00170
00171
00172
00173 void TypeFlags::loadWeaponInfo()
00174 {
00175 ConfigFileManager* config = ConfigFileManager::get_instance();
00176
00177
00178 std::vector<Pentagram::istring> weaponkeys;
00179 weaponkeys = config->listSections("weapons", true);
00180 for (std::vector<Pentagram::istring>::iterator iter = weaponkeys.begin();
00181 iter != weaponkeys.end(); ++iter)
00182 {
00183 Pentagram::istring k = *iter;
00184 WeaponInfo* wi = new WeaponInfo;
00185
00186 int val;
00187
00188 config->get(k + "/shape", val);
00189 wi->shape = static_cast<uint32>(val);
00190
00191 config->get(k + "/overlay", val);
00192 wi->overlay_type = static_cast<uint8>(val);
00193
00194 config->get(k + "/overlay_shape", val);
00195 wi->overlay_shape = static_cast<uint32>(val);
00196
00197 config->get(k + "/damage_mod", val);
00198 wi->damage_modifier = static_cast<uint8>(val);
00199
00200 config->get(k + "/base_damage", val);
00201 wi->base_damage = static_cast<uint8>(val);
00202
00203 config->get(k + "/attack_dex", val);
00204 wi->dex_attack_bonus = static_cast<uint8>(val);
00205
00206 config->get(k + "/defend_dex", val);
00207 wi->dex_defend_bonus = static_cast<uint8>(val);
00208
00209 config->get(k + "/armour", val);
00210 wi->armour_bonus = static_cast<uint8>(val);
00211
00212 config->get(k + "/damage_type", val);
00213 wi->damage_type = static_cast<uint16>(val);
00214
00215 if (config->get(k + "/treasure_chance", val))
00216 wi->treasure_chance = static_cast<uint16>(val);
00217 else
00218 wi->treasure_chance = 0;
00219
00220 assert(wi->shape < shapeInfo.size());
00221 shapeInfo[wi->shape].weaponinfo = wi;
00222 }
00223 }
00224
00225
00226 void TypeFlags::loadArmourInfo()
00227 {
00228 ConfigFileManager* config = ConfigFileManager::get_instance();
00229 MainShapeArchive* msf = GameData::get_instance()->getMainShapes();
00230
00231
00232 std::vector<Pentagram::istring> armourkeys;
00233 armourkeys = config->listSections("armour", true);
00234 for (std::vector<Pentagram::istring>::iterator iter = armourkeys.begin();
00235 iter != armourkeys.end(); ++iter)
00236 {
00237 Pentagram::istring k = *iter;
00238 ArmourInfo ai;
00239
00240 int val;
00241
00242 config->get(k + "/shape", val);
00243 ai.shape = static_cast<uint32>(val);
00244
00245 assert(ai.shape < shapeInfo.size());
00246 assert(msf->getShape(ai.shape));
00247 unsigned int framecount = msf->getShape(ai.shape)->frameCount();
00248 ArmourInfo* aia = shapeInfo[ai.shape].armourinfo;
00249 if (!aia) {
00250 aia = new ArmourInfo[framecount];
00251 shapeInfo[ai.shape].armourinfo = aia;
00252 for (unsigned int i = 0; i < framecount; ++i) {
00253 aia[i].shape = 0;
00254 aia[i].frame = 0;
00255 aia[i].armour_class = 0;
00256 aia[i].defense_type = 0;
00257 aia[i].kick_attack_bonus = 0;
00258 }
00259 }
00260
00261 config->get(k + "/frame", val);
00262 ai.frame = static_cast<uint32>(val);
00263
00264 assert(ai.frame < framecount);
00265
00266 config->get(k + "/armour", val);
00267 ai.armour_class = static_cast<uint16>(val);
00268
00269 if (config->get(k + "/type", val))
00270 ai.defense_type = static_cast<uint16>(val);
00271 else
00272 ai.defense_type = 0;
00273
00274 if (config->get(k + "/kick_bonus", val))
00275 ai.kick_attack_bonus = static_cast<uint16>(val);
00276 else
00277 ai.kick_attack_bonus = 0;
00278
00279 aia[ai.frame] = ai;
00280 }
00281 }
00282
00283 void TypeFlags::loadMonsterInfo()
00284 {
00285 ConfigFileManager* config = ConfigFileManager::get_instance();
00286
00287 TreasureLoader treasureLoader;
00288 treasureLoader.loadDefaults();
00289
00290
00291 std::vector<Pentagram::istring> monsterkeys;
00292 monsterkeys = config->listSections("monsters", true);
00293 for (std::vector<Pentagram::istring>::iterator iter = monsterkeys.begin();
00294 iter != monsterkeys.end(); ++iter)
00295 {
00296 Pentagram::istring k = *iter;
00297 MonsterInfo* mi = new MonsterInfo;
00298
00299 int val;
00300
00301 config->get(k + "/shape", val);
00302 mi->shape = static_cast<uint32>(val);
00303
00304 config->get(k + "/hp_min", val);
00305 mi->min_hp = static_cast<uint16>(val);
00306
00307 config->get(k + "/hp_max", val);
00308 mi->max_hp = static_cast<uint16>(val);
00309
00310 config->get(k + "/dex_min", val);
00311 mi->min_dex = static_cast<uint16>(val);
00312
00313 config->get(k + "/dex_max", val);
00314 mi->max_dex = static_cast<uint16>(val);
00315
00316 config->get(k + "/damage_min", val);
00317 mi->min_dmg = static_cast<uint16>(val);
00318
00319 config->get(k + "/damage_max", val);
00320 mi->max_dmg = static_cast<uint16>(val);
00321
00322 config->get(k + "/armour", val);
00323 mi->armour_class = static_cast<uint16>(val);
00324
00325 config->get(k + "/alignment", val);
00326 mi->alignment = static_cast<uint8>(val);
00327
00328 config->get(k + "/unk", val);
00329 mi->unk = (val != 0);
00330
00331 config->get(k + "/damage_type", val);
00332 mi->damage_type = static_cast<uint16>(val);
00333
00334 config->get(k + "/defense_type", val);
00335 mi->defense_type = static_cast<uint16>(val);
00336
00337 if (config->get(k + "/resurrection", val))
00338 mi->resurrection = (val != 0);
00339 else
00340 mi->resurrection = false;
00341
00342 if (config->get(k + "/ranged", val))
00343 mi->ranged = (val != 0);
00344 else
00345 mi->ranged = false;
00346
00347 if (config->get(k + "/shifter", val))
00348 mi->shifter = (val != 0);
00349 else
00350 mi->shifter = false;
00351
00352 if (config->get(k + "/explode", val))
00353 mi->explode = val;
00354 else
00355 mi->explode = 0;
00356
00357 std::string treasure;
00358 if (config->get(k + "/treasure", treasure)) {
00359 bool ok = treasureLoader.parse(treasure, mi->treasure);
00360 if (!ok) {
00361 perr << "failed to parse treasure info for monster '" << k
00362 << "'" << std::endl;
00363 mi->treasure.clear();
00364 }
00365 } else {
00366 mi->treasure.clear();
00367 }
00368
00369 assert(mi->shape < shapeInfo.size());
00370 shapeInfo[mi->shape].monsterinfo = mi;
00371 }
00372 }