#define VCMI_DLL #include "../stdafx.h" #include "CCreatureHandler.h" #include "CLodHandler.h" #include #include #include #include #include #include #include #include #include "../lib/VCMI_Lib.h" #include "../lib/CGameState.h" using namespace boost::assign; extern CLodHandler * bitmaph; /* * CCreatureHandler.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ static std::vector getMindSpells() { std::vector ret; ret.push_back(50); //sorrow ret.push_back(59); //berserk ret.push_back(60); //hypnotize ret.push_back(61); //forgetfulness ret.push_back(62); //blind return ret; } CCreatureHandler::CCreatureHandler() { VLC->creh = this; // Set the faction alignments to the defaults: // Good: Castle, Rampart, Tower // Evil: Inferno, Necropolis, Dungeon // Neutral: Stronghold, Fortess, Conflux factionAlignments += 1, 1, 1, -1, -1, -1, 0, 0, 0; doubledCreatures += 4, 14, 20, 28, 42, 44, 60, 70, 72, 85, 86, 100, 104; //according to Strategija } int CCreature::getQuantityID(const int & quantity) { if (quantity<5) return 0; if (quantity<10) return 1; if (quantity<20) return 2; if (quantity<50) return 3; if (quantity<100) return 4; if (quantity<250) return 5; if (quantity<500) return 5; if (quantity<1000) return 6; if (quantity<4000) return 7; return 8; } bool CCreature::isDoubleWide() const { return doubleWide; } bool CCreature::isFlying() const { return vstd::contains(bonuses, Bonus::FLYING); } bool CCreature::isShooting() const { return vstd::contains(bonuses, Bonus::SHOOTER); } bool CCreature::isUndead() const { return vstd::contains(bonuses, Bonus::UNDEAD); } /** * Determines if the creature is of a good alignment. * @return true if the creture is good, false otherwise. */ bool CCreature::isGood () const { return VLC->creh->isGood(faction); } /** * Determines if the creature is of an evil alignment. * @return true if the creature is evil, false otherwise. */ bool CCreature::isEvil () const { return VLC->creh->isEvil(faction); } si32 CCreature::maxAmount(const std::vector &res) const //how many creatures can be bought { int ret = 2147483645; int resAmnt = std::min(res.size(),cost.size()); for(int i=0;icreh->globalEffects); } bool CCreature::isMyUpgrade(const CCreature *anotherCre) const { //TODO upgrade of upgrade? return vstd::contains(upgrades, anotherCre->idNumber); } int readNumber(int & befi, int & i, int andame, std::string & buf) //helper function for void CCreatureHandler::loadCreatures() and loadUnitAnimInfo() { befi=i; for(i; igetTextFile("ZCRTRAIT.TXT"); int andame = buf.size(); int i=0; //buf iterator int hmcr=0; for(i; i mindSpells = getMindSpells(); for(int g=0; g> command; switch(command) { case '+': //add new ability { int creatureID; Bonus nsf; si32 buf; std::string type; reader >> creatureID; reader >> type; std::map::const_iterator it = bonusNameMap.find(type); CCreature *cre = creatures[creatureID]; if (it == bonusNameMap.end()) { if(type == "DOUBLE_WIDE") cre->doubleWide = true; else if(type == "ENEMY_MORALE_DECREASING") { cre->addBonus(-1, Bonus::MORALE);; cre->bonuses.back().effectRange = Bonus::ONLY_ENEMY_ARMY; } else if(type == "ENEMY_LUCK_DECREASING") { cre->addBonus(-1, Bonus::LUCK);; cre->bonuses.back().effectRange = Bonus::ONLY_ENEMY_ARMY; } else tlog1 << "Error: invalid type " << type << " in cr_abils.txt" << std::endl; break; } nsf.type = it->second; reader >> buf; nsf.val = buf; reader >> buf; nsf.subtype = buf; reader >> buf; nsf.additionalInfo = buf; nsf.source = Bonus::CREATURE_ABILITY; nsf.id = cre->idNumber; nsf.duration = Bonus::ONE_BATTLE; nsf.turnsRemain = 0; cre->bonuses += nsf; break; } case '-': //remove ability { int creatureID; std::string type; reader >> creatureID; reader >> type; std::map::const_iterator it = bonusNameMap.find(type); if (it == bonusNameMap.end()) { if(type == "DOUBLE_WIDE") creatures[creatureID]->doubleWide = false; else tlog1 << "Error: invalid type " << type << " in cr_abils.txt" << std::endl; break; } int typeNo = it->second; Bonus::BonusType ecf = static_cast(typeNo); creatures[creatureID]->bonuses -= ecf; break; } case '0': //end reading { contReading = false; break; } default: //invalid command { tlog1 << "Parse error in file config/cr_abils.txt" << std::endl; break; } } } abils.close(); tlog5 << "\t\tReading config/crerefnam.txt" << std::endl; //loading reference names std::ifstream ifs(DATA_DIR "/config/crerefnam.txt"); int tempi; std::string temps; for (;;) { ifs >> tempi >> temps; if (tempi>=creatures.size()) break; boost::assign::insert(nameToID)(temps,tempi); creatures[tempi]->nameRef=temps; } ifs.close(); ifs.clear(); for(int i=1;i<=10;i++) levelCreatures.insert(std::pair >(i,std::vector())); tlog5 << "\t\tReading config/monsters.txt" << std::endl; ifs.open(DATA_DIR "/config/monsters.txt"); { while(!ifs.eof()) { int id, lvl; ifs >> id >> lvl; if(lvl>0) { creatures[id]->level = lvl; levelCreatures[lvl].push_back(creatures[id]); } } } ifs.close(); ifs.clear(); tlog5 << "\t\tReading config/cr_factions.txt" << std::endl; ifs.open(DATA_DIR "/config/cr_factions.txt"); while(!ifs.eof()) { int id, fact; ifs >> id >> fact; creatures[id]->faction = fact; } ifs.close(); ifs.clear(); tlog5 << "\t\tReading config/cr_upgrade_list.txt" << std::endl; ifs.open(DATA_DIR "/config/cr_upgrade_list.txt"); while(!ifs.eof()) { int id, up; ifs >> id >> up; creatures[id]->upgrades.insert(up); } ifs.close(); ifs.clear(); //loading unit animation def names tlog5 << "\t\tReading config/CREDEFS.TXT" << std::endl; std::ifstream inp(DATA_DIR "/config/CREDEFS.TXT", std::ios::in | std::ios::binary); //this file is not in lod inp.seekg(0,std::ios::end); // na koniec int andame2 = inp.tellg(); // read length inp.seekg(0,std::ios::beg); // wracamy na poczatek char * bufor = new char[andame2+1]; // allocate memory inp.read((char*)bufor, andame2); // read map file to buffer inp.close(); bufor[andame2] = 0; buf = std::string(bufor); delete [] bufor; i = 0; //buf iterator hmcr = 0; for(i; ianimDefName = defName; } tlog5 << "\t\tReading CRANIM.TXT.txt" << std::endl; loadAnimationInfo(); //loading id to projectile mapping tlog5 << "\t\tReading config/cr_shots.txt" << std::endl; std::ifstream inp2(DATA_DIR "/config/cr_shots.txt", std::ios::in | std::ios::binary); //this file is not in lod char dump [200]; inp2.getline(dump, 200); while(true) { int id; std::string name; bool spin; inp2>>id; if(id == -1) break; inp2>>name; idToProjectile[id] = name; inp2>>spin; idToProjectileSpin[id] = spin; } inp2.close(); //reading factionToTurretCreature tlog5 << "\t\tReading config/cr_to_turret.txt" << std::endl; std::ifstream inp3(DATA_DIR "/config/cr_to_turret.txt", std::ios::in | std::ios::binary); //this file is not in lod std::string dump2; inp3 >> dump2 >> dump2; for(int g=0; g> factionToTurretCreature[g]; } inp3.close(); } void CCreatureHandler::loadAnimationInfo() { std::string buf = bitmaph->getTextFile("CRANIM.TXT"); int andame = buf.size(); int i=0; //buf iterator int hmcr=0; for(i; i &randGen) const { int r = 0; do { if(randGen) r = randGen(); else r = rand(); r %= 197; } while (vstd::contains(VLC->creh->notUsedMonsters,r)); return r; }