TypeFlags.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2003-2006 The Pentagram Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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         // TODO: detect U8/crusader format somehow?!
00054         // (Or probably pass it as parameter)
00055         // The 'parsing' below is only for U8
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                         // might have to split up remorse/regret at some point
00115 
00116                         // unchecked
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                         // unchecked
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                         // (copied from old/viewer/ShapeManager.h)
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                 // Workaround for incorrectly set solid flags on some "moss
00160                 // curtains" in the catacombs. See also docs/u8bugs.txt
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 // load weapon info from the 'weapons' config root
00173 void TypeFlags::loadWeaponInfo()
00174 {
00175         ConfigFileManager* config = ConfigFileManager::get_instance();
00176 
00177         // load weapons
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         // load armour
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         // load monsters
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 }

Generated on Fri Jul 27 22:27:46 2007 for pentagram by  doxygen 1.4.7