CUnitDefHandler::CUnitDefHandler(void) : noCost(false) { const LuaTable rootTable = game->defsParser->GetRoot().SubTable("UnitDefs"); if (!rootTable.IsValid()) { throw content_error("Error loading UnitDefs"); } vector<string> unitDefNames; rootTable.GetKeys(unitDefNames); unitDefs.reserve(unitDefNames.size() + 1); UnitDef* nullDef = new UnitDef(); unitDefs.push_back(nullDef); for (unsigned int a = 0; a < unitDefNames.size(); ++a) { const string unitName = unitDefNames[a]; LuaTable udTable = rootTable.SubTable(unitName); // parse the unitdef data (but don't load buildpics, etc...) PushNewUnitDef(unitName, udTable); } CleanBuildOptions(); FindStartUnits(); ProcessDecoys(); AssignTechLevels(); }
CDamageArrayHandler::CDamageArrayHandler(LuaParser* defsParser) { #define DEFAULT_ARMORDEF_NAME "default" try { const LuaTable rootTable = defsParser->GetRoot().SubTable("ArmorDefs"); if (!rootTable.IsValid()) throw content_error("Error loading ArmorDefs"); // GetKeys() sorts the keys, so can not simply push_back before call rootTable.GetKeys(armorDefKeys); armorDefKeys.insert(armorDefKeys.begin(), DEFAULT_ARMORDEF_NAME); armorDefNameIdxMap[DEFAULT_ARMORDEF_NAME] = 0; LOG("[%s] number of ArmorDefs: " _STPF_, __FUNCTION__, armorDefKeys.size()); // expects the following structure, subtables must be in array-format: // // {"tanks" = {[1] = "supertank", [2] = "megatank"}, "infantry" = {[1] = "dude"}, ...} // // the old (pre-95.0) <key, value> subtable definitions are no longer supported! // for (unsigned int armorDefIdx = 1; armorDefIdx < armorDefKeys.size(); armorDefIdx++) { const std::string armorDefName = StringToLower(armorDefKeys[armorDefIdx]); if (armorDefName == DEFAULT_ARMORDEF_NAME) { // ignore, no need to clear entire table LOG_L(L_WARNING, "[%s] ArmorDefs: tried to define the \"%s\" armor type!", __FUNCTION__, DEFAULT_ARMORDEF_NAME); continue; } armorDefNameIdxMap[armorDefName] = armorDefIdx; const LuaTable armorDefTable = rootTable.SubTable(armorDefKeys[armorDefIdx]); const unsigned int numArmorDefEntries = armorDefTable.GetLength(); for (unsigned int armorDefEntryIdx = 0; armorDefEntryIdx < numArmorDefEntries; armorDefEntryIdx++) { const std::string& unitDefName = StringToLower(armorDefTable.GetString(armorDefEntryIdx + 1, "")); const auto armorDefTableIt = armorDefNameIdxMap.find(unitDefName); if (armorDefTableIt == armorDefNameIdxMap.end()) { armorDefNameIdxMap[unitDefName] = armorDefIdx; continue; } LOG_L(L_WARNING, "[%s] UnitDef \"%s\" in ArmorDef \"%s\" already belongs to ArmorDef category %d!", __FUNCTION__, unitDefName.c_str(), armorDefName.c_str(), armorDefTableIt->second); } } } catch (const content_error&) { armorDefNameIdxMap.clear(); armorDefNameIdxMap[DEFAULT_ARMORDEF_NAME] = 0; armorDefKeys.clear(); armorDefKeys.push_back(DEFAULT_ARMORDEF_NAME); } }
CWeaponDefHandler::CWeaponDefHandler() { PrintLoadMsg("Loading weapon definitions"); const LuaTable rootTable = game->defsParser->GetRoot().SubTable("WeaponDefs"); if (!rootTable.IsValid()) { throw content_error("Error loading WeaponDefs"); } vector<string> weaponNames; rootTable.GetKeys(weaponNames); numWeaponDefs = weaponNames.size(); // FIXME: starting at 0, don't need the +1 ? weaponDefs = SAFE_NEW WeaponDef[numWeaponDefs + 1]; for (int wid = 0; wid < (int)weaponNames.size(); wid++) { WeaponDef& wd = weaponDefs[wid]; wd.id = wid; wd.name = weaponNames[wid]; weaponID[wd.name] = wid; const LuaTable wdTable = rootTable.SubTable(wd.name); ParseTAWeapon(wdTable, wd); } }
CFeatureHandler::CFeatureHandler() : nextFreeID(0) { PrintLoadMsg("Loading feature definitions"); drawQuadsX = gs->mapx/DRAW_QUAD_SIZE; drawQuadsY = gs->mapy/DRAW_QUAD_SIZE; drawQuads.resize(drawQuadsX * drawQuadsY); treeDrawer = CBaseTreeDrawer::GetTreeDrawer(); const LuaTable rootTable = game->defsParser->GetRoot().SubTable("FeatureDefs"); if (!rootTable.IsValid()) { throw content_error("Error loading FeatureDefs"); } //! featureDefIDs start with 1 featureDefsVector.push_back(NULL); //! get most of the feature defs (missing trees and geovent from the map) vector<string> keys; rootTable.GetKeys(keys); for (int i = 0; i < (int)keys.size(); i++) { const string& name = keys[i]; const LuaTable fdTable = rootTable.SubTable(name); CreateFeatureDef(fdTable, name); } }
CWeaponDefHandler::CWeaponDefHandler() { PrintLoadMsg("Loading weapon definitions"); const LuaTable rootTable = game->defsParser->GetRoot().SubTable("WeaponDefs"); if (!rootTable.IsValid()) { throw content_error("Error loading WeaponDefs"); } vector<string> weaponNames; rootTable.GetKeys(weaponNames); numWeaponDefs = weaponNames.size(); weaponDefs = new WeaponDef[numWeaponDefs]; for (int wid = 0; wid < numWeaponDefs; wid++) { WeaponDef& wd = weaponDefs[wid]; wd.id = wid; wd.name = weaponNames[wid]; weaponID[wd.name] = wid; const LuaTable wdTable = rootTable.SubTable(wd.name); ParseWeapon(wdTable, wd); } }
bool CSound::LoadSoundDefs(const std::string& filename) { //! can be called from LuaUnsyncedCtrl too boost::mutex::scoped_lock lck(soundMutex); LuaParser parser(filename, SPRING_VFS_MOD, SPRING_VFS_ZIP); parser.SetLowerKeys(false); parser.SetLowerCppKeys(false); parser.Execute(); if (!parser.IsValid()) { LogObject(LOG_SOUND) << "Could not load " << filename << ": " << parser.GetErrorLog(); return false; } else { const LuaTable soundRoot = parser.GetRoot(); const LuaTable soundItemTable = soundRoot.SubTable("SoundItems"); if (!soundItemTable.IsValid()) { LogObject(LOG_SOUND) << "CSound(): could not parse SoundItems table in " << filename; return false; } else { std::vector<std::string> keys; soundItemTable.GetKeys(keys); for (std::vector<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it) { const std::string name(*it); soundItemDef bufmap; const LuaTable buf(soundItemTable.SubTable(*it)); buf.GetMap(bufmap); bufmap["name"] = name; soundItemDefMap::const_iterator sit = soundItemDefs.find(name); if (sit != soundItemDefs.end()) LogObject(LOG_SOUND) << "CSound(): two SoundItems have the same name: " << name; soundItemDef::const_iterator inspec = bufmap.find("file"); if (inspec == bufmap.end()) // no file, drop LogObject(LOG_SOUND) << "CSound(): SoundItem has no file tag: " << name; else soundItemDefs[name] = bufmap; if (buf.KeyExists("preload")) { LogObject(LOG_SOUND) << "CSound(): preloading " << name; const size_t newid = sounds.size(); sounds.push_back(new SoundItem(GetWaveBuffer(bufmap["file"], true), bufmap)); soundMap[name] = newid; } } LogObject(LOG_SOUND) << "CSound(): Sucessfully parsed " << keys.size() << " SoundItems from " << filename; } } return true; }
void CSyncer::LoadUnits(bool checksum) { unitsLeft = 0; LuaParser luaParser("gamedata/defs.lua", SPRING_VFS_MOD_BASE, SPRING_VFS_ZIP); if (!luaParser.Execute()) { logOutput.Print("luaParser.Execute() failed"); return; } LuaTable rootTable = luaParser.GetRoot().SubTable("UnitDefs"); if (!rootTable.IsValid()) { logOutput.Print("root unitdef table invalid"); return; } vector<string> unitDefNames; rootTable.GetKeys(unitDefNames); const int count = (int)unitDefNames.size(); for (int i = 0; i < count; ++i) { const string& udName = unitDefNames[i]; LuaTable udTable = rootTable.SubTable(udName); Unit u; u.fullName = udTable.GetString("name", udName); if (checksum) { const string fileName = udTable.GetString("filename", ""); const string deadName = udTable.GetString("corpse", udName + "_dead"); const string modelName = udTable.GetString("objectname", udName); u.fbi = CalculateCRC(fileName); u.cob = CalculateCRC("scripts/" + udName + ".cob"); u.model = CalculateCRC("objects3d/" + modelName); // s3o ? u.model += CalculateCRC("objects3d/" + modelName + ".3do"); u.model += CalculateCRC("objects3d/" + deadName + ".3do"); } units[udName] = u; } // map the unitIds map<string, Unit>::iterator mit; for (mit = units.begin(); mit != units.end(); ++mit) { unitIds.push_back(mit->first); } unitsLeft = count; return; }
bool CSound::LoadSoundDefs(const std::string& fileName) { //! can be called from LuaUnsyncedCtrl too boost::recursive_mutex::scoped_lock lck(soundMutex); LuaParser parser(fileName, SPRING_VFS_MOD, SPRING_VFS_ZIP); parser.SetLowerKeys(false); parser.SetLowerCppKeys(false); parser.Execute(); if (!parser.IsValid()) { LOG_L(L_WARNING, "Could not load %s: %s", fileName.c_str(), parser.GetErrorLog().c_str()); return false; } else { const LuaTable soundRoot = parser.GetRoot(); const LuaTable soundItemTable = soundRoot.SubTable("SoundItems"); if (!soundItemTable.IsValid()) { LOG_L(L_WARNING, "CSound(): could not parse SoundItems table in %s", fileName.c_str()); return false; } else { std::vector<std::string> keys; soundItemTable.GetKeys(keys); for (std::vector<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it) { const std::string name(*it); soundItemDef bufmap; const LuaTable buf(soundItemTable.SubTable(*it)); buf.GetMap(bufmap); bufmap["name"] = name; soundItemDefMap::const_iterator sit = soundItemDefs.find(name); if (sit != soundItemDefs.end()) LOG_L(L_WARNING, "Sound %s gets overwritten by %s", name.c_str(), fileName.c_str()); soundItemDef::const_iterator inspec = bufmap.find("file"); if (inspec == bufmap.end()) { // no file, drop LOG_L(L_WARNING, "Sound %s is missing file tag (ignoring)", name.c_str()); } else { soundItemDefs[name] = bufmap; } if (buf.KeyExists("preload")) { MakeItemFromDef(bufmap); } } LOG(" parsed %i sounds from %s", (int)keys.size(), fileName.c_str()); } } return true; }
void CProjectileDrawer::ParseAtlasTextures( const bool blockTextures, const LuaTable& textureTable, std::set<std::string>& blockedTextures, CTextureAtlas* textureAtlas) { std::vector<std::string> subTables; std::map<std::string, std::string> texturesMap; std::map<std::string, std::string>::iterator texturesMapIt; textureTable.GetMap(texturesMap); textureTable.GetKeys(subTables); for (texturesMapIt = texturesMap.begin(); texturesMapIt != texturesMap.end(); ++texturesMapIt) { const std::string textureName = StringToLower(texturesMapIt->first); if (blockTextures) { // no textures added to this atlas are allowed // to be overwritten later by other textures of // the same name blockedTextures.insert(textureName); } if (blockTextures || (blockedTextures.find(textureName) == blockedTextures.end())) { textureAtlas->AddTexFromFile(texturesMapIt->first, "bitmaps/" + texturesMapIt->second); } } texturesMap.clear(); for (size_t i = 0; i < subTables.size(); i++) { const LuaTable& textureSubTable = textureTable.SubTable(subTables[i]); if (textureSubTable.IsValid()) { textureSubTable.GetMap(texturesMap); for (texturesMapIt = texturesMap.begin(); texturesMapIt != texturesMap.end(); ++texturesMapIt) { const std::string textureName = StringToLower(texturesMapIt->first); if (blockTextures) { blockedTextures.insert(textureName); } if (blockTextures || (blockedTextures.find(textureName) == blockedTextures.end())) { textureAtlas->AddTexFromFile(texturesMapIt->first, "bitmaps/" + texturesMapIt->second); } } texturesMap.clear(); } } }
void DefType::ReportUnknownTags(const std::string& instanceName, const LuaTable& luaTable, const std::string pre) { std::vector<std::string> keys; luaTable.GetKeys(keys); for (const std::string& tag: keys) { const DefTagMetaData* meta = GetMetaDataByExternalKey(pre + tag); if (meta != nullptr) continue; if (luaTable.GetType(tag) == LuaTable::TABLE) { ReportUnknownTags(instanceName, luaTable.SubTable(tag), pre + tag + "."); continue; } LOG_L(L_WARNING, "%s: Unknown tag \"%s%s\" in \"%s\"", name.c_str(), pre.c_str(), tag.c_str(), instanceName.c_str()); } }
CFeatureHandler::CFeatureHandler() { const LuaTable rootTable = game->defsParser->GetRoot().SubTable("FeatureDefs"); if (!rootTable.IsValid()) { throw content_error("Error loading FeatureDefs"); } // featureDefIDs start with 1 featureDefsVector.push_back(NULL); // get most of the feature defs (missing trees and geovent from the map) vector<string> keys; rootTable.GetKeys(keys); for (int i = 0; i < (int)keys.size(); i++) { const string& nameMixedCase = keys[i]; const string& nameLowerCase = StringToLower(nameMixedCase); const LuaTable& fdTable = rootTable.SubTable(nameMixedCase); AddFeatureDef(nameLowerCase, CreateFeatureDef(fdTable, nameLowerCase)); } }
/** Load the messages from gamedata/messages.lua into memory. */ void CMessages::Load() { LuaParser luaParser("gamedata/messages.lua", SPRING_VFS_MOD_BASE, SPRING_VFS_MOD_BASE); if (!luaParser.Execute()) { // Show parse errors in the infolog. logOutput.Print(string("ERROR: messages.lua: ") + luaParser.GetErrorLog()); return; } const LuaTable root = luaParser.GetRoot(); vector<string> labels; root.GetKeys(labels); for (size_t l = 0; l < labels.size(); l++) { const string label = StringToLower(labels[l]); const LuaTable msgTable = root.SubTable(label); if (!msgTable.IsValid()) { continue; } vector<string> msgs; for (int s = 1; true; s++) { const string msg = msgTable.GetString(s, ""); if (msg.empty()) { break; } msgs.push_back(msg); } if (!msgs.empty()) { tr[label] = msgs; } } loaded = true; }
void CCustomExplosionGenerator::Load(CExplosionGeneratorHandler* h, const string& tag) { static std::map<string, CEGData> cachedCEGs; std::map<string, CEGData>::iterator it = cachedCEGs.find(tag); if (it == cachedCEGs.end()) { CEGData cegData; const LuaTable& root = h->GetTable(); const LuaTable expTable = root.SubTable(tag); if (!expTable.IsValid()) { throw content_error("Explosion info for " + tag + " not found."); } vector<string> spawns; expTable.GetKeys(spawns); for (vector<string>::iterator si = spawns.begin(); si != spawns.end(); ++si) { ProjectileSpawnInfo psi; const string& spawnName = *si; const LuaTable spawnTable = expTable.SubTable(spawnName); if (!spawnTable.IsValid() || spawnName == "groundflash") { continue; } const string className = spawnTable.GetString("class", spawnName); unsigned int flags = 0; if (spawnTable.GetBool("ground", false)) { flags |= SPW_GROUND; } if (spawnTable.GetBool("water", false)) { flags |= SPW_WATER; } if (spawnTable.GetBool("air", false)) { flags |= SPW_AIR; } if (spawnTable.GetBool("underwater", false)) { flags |= SPW_UNDERWATER; } if (spawnTable.GetBool("unit", false)) { flags |= SPW_UNIT; } if (spawnTable.GetBool("nounit", false)) { flags |= SPW_NO_UNIT; } psi.projectileClass = h->projectileClasses.GetClass(className); psi.flags = flags; psi.count = spawnTable.GetInt("count", 1); string code; map<string, string> props; map<string, string>::const_iterator propIt; spawnTable.SubTable("properties").GetMap(props); for (propIt = props.begin(); propIt != props.end(); ++propIt) { creg::Class::Member* m = psi.projectileClass->FindMember(propIt->first.c_str()); if (m && (m->flags & creg::CM_Config)) { ParseExplosionCode(&psi, m->offset, m->type, propIt->second, code); } } code += (char)OP_END; psi.code.resize(code.size()); copy(code.begin(), code.end(), psi.code.begin()); cegData.projectileSpawn.push_back(psi); } const LuaTable gndTable = expTable.SubTable("groundflash"); const int ttl = gndTable.GetInt("ttl", 0); if (ttl > 0) { cegData.groundFlash.circleAlpha = gndTable.GetFloat("circleAlpha", 0.0f); cegData.groundFlash.flashSize = gndTable.GetFloat("flashSize", 0.0f); cegData.groundFlash.flashAlpha = gndTable.GetFloat("flashAlpha", 0.0f); cegData.groundFlash.circleGrowth = gndTable.GetFloat("circleGrowth", 0.0f); cegData.groundFlash.color = gndTable.GetFloat3("color", float3(1.0f, 1.0f, 0.8f)); unsigned int flags = SPW_GROUND; if (gndTable.GetBool("ground", false)) { flags |= SPW_GROUND; } if (gndTable.GetBool("water", false)) { flags |= SPW_WATER; } if (gndTable.GetBool("air", false)) { flags |= SPW_AIR; } if (gndTable.GetBool("underwater", false)) { flags |= SPW_UNDERWATER; } if (gndTable.GetBool("unit", false)) { flags |= SPW_UNIT; } if (gndTable.GetBool("nounit", false)) { flags |= SPW_NO_UNIT; } cegData.groundFlash.flags = flags; cegData.groundFlash.ttl = ttl; } cegData.useDefaultExplosions = expTable.GetBool("useDefaultExplosions", false); cachedCEGs[tag] = cegData; currentCEG = &cachedCEGs[tag]; } else { currentCEG = &(it->second); } }
void CCustomExplosionGenerator::Load(CExplosionGeneratorHandler* h, const string& tag) { typedef std::map<string, CEGData> CEGMap; typedef std::map<string, CEGData>::iterator CEGMapIt; CEGMapIt it = cachedCEGs.find(tag); if (it == cachedCEGs.end()) { CEGData cegData; const LuaTable& root = h->GetTable(); const LuaTable expTable = root.SubTable(tag); if (!expTable.IsValid()) { throw content_error("Explosion info for " + tag + " not found."); } vector<string> spawns; expTable.GetKeys(spawns); for (vector<string>::iterator si = spawns.begin(); si != spawns.end(); ++si) { ProjectileSpawnInfo psi; const string& spawnName = *si; const LuaTable spawnTable = expTable.SubTable(spawnName); if (!spawnTable.IsValid() || spawnName == "groundflash") { continue; } const string className = spawnTable.GetString("class", spawnName); psi.projectileClass = h->projectileClasses.GetClass(className); psi.flags = GetFlagsFromTable(spawnTable); psi.count = spawnTable.GetInt("count", 1); if (psi.projectileClass->binder->flags & creg::CF_Synced) { psi.flags |= SPW_SYNCED; } string code; map<string, string> props; map<string, string>::const_iterator propIt; spawnTable.SubTable("properties").GetMap(props); for (propIt = props.begin(); propIt != props.end(); ++propIt) { creg::Class::Member* m = psi.projectileClass->FindMember(propIt->first.c_str()); if (m && (m->flags & creg::CM_Config)) { ParseExplosionCode(&psi, m->offset, m->type, propIt->second, code); } } code += (char)OP_END; psi.code.resize(code.size()); copy(code.begin(), code.end(), psi.code.begin()); cegData.projectileSpawn.push_back(psi); } const LuaTable gndTable = expTable.SubTable("groundflash"); const int ttl = gndTable.GetInt("ttl", 0); if (ttl > 0) { cegData.groundFlash.circleAlpha = gndTable.GetFloat("circleAlpha", 0.0f); cegData.groundFlash.flashSize = gndTable.GetFloat("flashSize", 0.0f); cegData.groundFlash.flashAlpha = gndTable.GetFloat("flashAlpha", 0.0f); cegData.groundFlash.circleGrowth = gndTable.GetFloat("circleGrowth", 0.0f); cegData.groundFlash.color = gndTable.GetFloat3("color", float3(1.0f, 1.0f, 0.8f)); cegData.groundFlash.flags = SPW_GROUND | GetFlagsFromTable(gndTable); cegData.groundFlash.ttl = ttl; } cegData.useDefaultExplosions = expTable.GetBool("useDefaultExplosions", false); it = cachedCEGs.insert(std::make_pair(tag, cegData)).first; } currentCEG = it; }
bool CSound::LoadSoundDefsImpl(const std::string& fileName) { //! can be called from LuaUnsyncedCtrl too boost::recursive_mutex::scoped_lock lck(soundMutex); LuaParser parser(fileName, SPRING_VFS_MOD, SPRING_VFS_ZIP); parser.Execute(); if (!parser.IsValid()) { LOG_L(L_WARNING, "Could not load %s: %s", fileName.c_str(), parser.GetErrorLog().c_str()); return false; } else { const LuaTable soundRoot = parser.GetRoot(); const LuaTable soundItemTable = soundRoot.SubTable("SoundItems"); if (!soundItemTable.IsValid()) { LOG_L(L_WARNING, "CSound(): could not parse SoundItems table in %s", fileName.c_str()); return false; } else { std::vector<std::string> keys; soundItemTable.GetKeys(keys); for (std::vector<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it) { std::string name(*it); soundItemDef bufmap; const LuaTable buf(soundItemTable.SubTable(name)); buf.GetMap(bufmap); bufmap["name"] = name; soundItemDefMap::const_iterator sit = soundItemDefs.find(name); if (name == "default") { defaultItem = bufmap; defaultItem.erase("name"); //must be empty for default item defaultItem.erase("file"); continue; } if (sit != soundItemDefs.end()) LOG_L(L_WARNING, "Sound %s gets overwritten by %s", name.c_str(), fileName.c_str()); if (!buf.KeyExists("file")) { // no file, drop LOG_L(L_WARNING, "Sound %s is missing file tag (ignoring)", name.c_str()); continue; } else { soundItemDefs[name] = bufmap; } if (buf.KeyExists("preload")) { MakeItemFromDef(bufmap); } } LOG(" parsed %i sounds from %s", (int)keys.size(), fileName.c_str()); } } //FIXME why do sounds w/o an own soundItemDef create (!=pointer) a new one from the defaultItem? for (soundItemDefMap::iterator it = soundItemDefs.begin(); it != soundItemDefs.end(); ++it) { soundItemDef& snddef = it->second; if (snddef.find("name") == snddef.end()) { // uses defaultItem! update it! const std::string file = snddef["file"]; snddef = defaultItem; snddef["file"] = file; } } return true; }
CProjectileDrawer::CProjectileDrawer(): CEventClient("[CProjectileDrawer]", 123456, false) { eventHandler.AddClient(this); loadscreen->SetLoadMessage("Creating Projectile Textures"); textureAtlas = new CTextureAtlas(2048, 2048); // used to block resources_map.tdf from loading textures std::set<std::string> blockMapTexNames; LuaParser resourcesParser("gamedata/resources.lua", SPRING_VFS_MOD_BASE, SPRING_VFS_ZIP); resourcesParser.Execute(); const LuaTable rootTable = resourcesParser.GetRoot(); const LuaTable gfxTable = rootTable.SubTable("graphics"); const LuaTable ptTable = gfxTable.SubTable("projectileTextures"); // add all textures in projectiletextures section std::map<std::string, std::string> ptex; ptTable.GetMap(ptex); for (std::map<std::string, std::string>::iterator pi = ptex.begin(); pi != ptex.end(); ++pi) { textureAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); blockMapTexNames.insert(StringToLower(pi->first)); } ptex.clear(); // add all texture from sections within projectiletextures section std::vector<std::string> seclist; ptTable.GetKeys(seclist); for (size_t i = 0; i < seclist.size(); i++) { const LuaTable ptSubTable = ptTable.SubTable(seclist[i]); if (ptSubTable.IsValid()) { ptSubTable.GetMap(ptex); for (std::map<std::string, std::string>::iterator pi = ptex.begin(); pi != ptex.end(); ++pi) { textureAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); blockMapTexNames.insert(StringToLower(pi->first)); } ptex.clear(); } } // get the smoke textures, hold the count in 'smokeCount' const LuaTable smokeTable = gfxTable.SubTable("smoke"); int smokeCount; if (smokeTable.IsValid()) { for (smokeCount = 0; true; smokeCount++) { const std::string tex = smokeTable.GetString(smokeCount + 1, ""); if (tex.empty()) { break; } const std::string texName = "bitmaps/" + tex; const std::string smokeName = "ismoke" + IntToString(smokeCount, "%02i"); textureAtlas->AddTexFromFile(smokeName, texName); blockMapTexNames.insert(StringToLower(smokeName)); } } else { // setup the defaults for (smokeCount = 0; smokeCount < 12; smokeCount++) { const std::string smokeNum = IntToString(smokeCount, "%02i"); const std::string smokeName = "ismoke" + smokeNum; const std::string texName = "bitmaps/smoke/smoke" + smokeNum + ".tga"; textureAtlas->AddTexFromFile(smokeName, texName); blockMapTexNames.insert(StringToLower(smokeName)); } } if (smokeCount <= 0) { throw content_error("missing smoke textures"); } char tex[128][128][4]; for (int y = 0; y < 128; y++) { // shield for (int x = 0; x < 128; x++) { tex[y][x][0] = 70; tex[y][x][1] = 70; tex[y][x][2] = 70; tex[y][x][3] = 70; } } textureAtlas->AddTexFromMem("perlintex", 128, 128, CTextureAtlas::RGBA32, tex); blockMapTexNames.insert("perlintex"); blockMapTexNames.insert("flare"); blockMapTexNames.insert("explo"); blockMapTexNames.insert("explofade"); blockMapTexNames.insert("heatcloud"); blockMapTexNames.insert("laserend"); blockMapTexNames.insert("laserfalloff"); blockMapTexNames.insert("randdots"); blockMapTexNames.insert("smoketrail"); blockMapTexNames.insert("wake"); blockMapTexNames.insert("perlintex"); blockMapTexNames.insert("flame"); blockMapTexNames.insert("sbtrailtexture"); blockMapTexNames.insert("missiletrailtexture"); blockMapTexNames.insert("muzzleflametexture"); blockMapTexNames.insert("repulsetexture"); blockMapTexNames.insert("dguntexture"); blockMapTexNames.insert("flareprojectiletexture"); blockMapTexNames.insert("sbflaretexture"); blockMapTexNames.insert("missileflaretexture"); blockMapTexNames.insert("beamlaserflaretexture"); blockMapTexNames.insert("bubbletexture"); blockMapTexNames.insert("geosquaretexture"); blockMapTexNames.insert("gfxtexture"); blockMapTexNames.insert("projectiletexture"); blockMapTexNames.insert("repulsegfxtexture"); blockMapTexNames.insert("sphereparttexture"); blockMapTexNames.insert("torpedotexture"); blockMapTexNames.insert("wrecktexture"); blockMapTexNames.insert("plasmatexture"); // allow map specified atlas textures for gaia unit projectiles LuaParser mapResParser("gamedata/resources_map.lua", SPRING_VFS_MOD_BASE, SPRING_VFS_ZIP); if (mapResParser.Execute()) { const LuaTable mapRoot = mapResParser.GetRoot(); const LuaTable mapTable = mapRoot.SubTable("projectileTextures"); // add all textures in projectiletextures section std::map<std::string, std::string>::iterator pi; mapTable.GetMap(ptex); for (pi = ptex.begin(); pi != ptex.end(); ++pi) { if (blockMapTexNames.find(StringToLower(pi->first)) == blockMapTexNames.end()) { textureAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); } } ptex.clear(); // add all texture from sections within projectiletextures section mapTable.GetKeys(seclist); for (size_t i = 0; i < seclist.size(); i++) { const LuaTable mapSubTable = mapTable.SubTable(seclist[i]); if (mapSubTable.IsValid()) { mapSubTable.GetMap(ptex); for (pi = ptex.begin(); pi != ptex.end(); ++pi) { if (blockMapTexNames.find(StringToLower(pi->first)) == blockMapTexNames.end()) { textureAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); } } ptex.clear(); } } } if (!textureAtlas->Finalize()) { LOG_L(L_ERROR, "Could not finalize projectile texture atlas. Use less/smaller textures."); } flaretex = textureAtlas->GetTexturePtr("flare"); explotex = textureAtlas->GetTexturePtr("explo"); explofadetex = textureAtlas->GetTexturePtr("explofade"); heatcloudtex = textureAtlas->GetTexturePtr("heatcloud"); laserendtex = textureAtlas->GetTexturePtr("laserend"); laserfallofftex = textureAtlas->GetTexturePtr("laserfalloff"); randdotstex = textureAtlas->GetTexturePtr("randdots"); smoketrailtex = textureAtlas->GetTexturePtr("smoketrail"); waketex = textureAtlas->GetTexturePtr("wake"); perlintex = textureAtlas->GetTexturePtr("perlintex"); flametex = textureAtlas->GetTexturePtr("flame"); for (int i = 0; i < smokeCount; i++) { const std::string smokeName = "ismoke" + IntToString(i, "%02i"); smoketex.push_back(textureAtlas->GetTexturePtr(smokeName)); } #define GETTEX(t, b) (textureAtlas->GetTexturePtrWithBackup((t), (b))) sbtrailtex = GETTEX("sbtrailtexture", "smoketrail" ); missiletrailtex = GETTEX("missiletrailtexture", "smoketrail" ); muzzleflametex = GETTEX("muzzleflametexture", "explo" ); repulsetex = GETTEX("repulsetexture", "explo" ); dguntex = GETTEX("dguntexture", "flare" ); flareprojectiletex = GETTEX("flareprojectiletexture", "flare" ); sbflaretex = GETTEX("sbflaretexture", "flare" ); missileflaretex = GETTEX("missileflaretexture", "flare" ); beamlaserflaretex = GETTEX("beamlaserflaretexture", "flare" ); bubbletex = GETTEX("bubbletexture", "circularthingy"); geosquaretex = GETTEX("geosquaretexture", "circularthingy"); gfxtex = GETTEX("gfxtexture", "circularthingy"); projectiletex = GETTEX("projectiletexture", "circularthingy"); repulsegfxtex = GETTEX("repulsegfxtexture", "circularthingy"); sphereparttex = GETTEX("sphereparttexture", "circularthingy"); torpedotex = GETTEX("torpedotexture", "circularthingy"); wrecktex = GETTEX("wrecktexture", "circularthingy"); plasmatex = GETTEX("plasmatexture", "circularthingy"); #undef GETTEX groundFXAtlas = new CTextureAtlas(2048, 2048); // add all textures in groundfx section const LuaTable groundfxTable = gfxTable.SubTable("groundfx"); groundfxTable.GetMap(ptex); for (std::map<std::string, std::string>::iterator pi = ptex.begin(); pi != ptex.end(); ++pi) { groundFXAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); } ptex.clear(); // add all textures from sections within groundfx section groundfxTable.GetKeys(seclist); for (size_t i = 0; i < seclist.size(); i++) { const LuaTable gfxSubTable = groundfxTable.SubTable(seclist[i]); if (gfxSubTable.IsValid()) { gfxSubTable.GetMap(ptex); for (std::map<std::string, std::string>::iterator pi = ptex.begin(); pi != ptex.end(); ++pi) { groundFXAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); } ptex.clear(); } } if (!groundFXAtlas->Finalize()) { LOG_L(L_ERROR, "Could not finalize groundFX texture atlas. Use less/smaller textures."); } groundflashtex = groundFXAtlas->GetTexturePtr("groundflash"); groundringtex = groundFXAtlas->GetTexturePtr("groundring"); seismictex = groundFXAtlas->GetTexturePtr("seismic"); for (int a = 0; a < 4; ++a) { perlinBlend[a]=0; } unsigned char tempmem[4 * 16 * 16]; for (int a = 0; a < 4 * 16 * 16; ++a) { tempmem[a] = 0; } for (int a = 0; a < 8; ++a) { glGenTextures(1, &perlinTex[a]); glBindTexture(GL_TEXTURE_2D, perlinTex[a]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16,16, 0, GL_RGBA, GL_UNSIGNED_BYTE, tempmem); } drawPerlinTex = false; if (perlinFB.IsValid()) { // we never refresh the full texture (just the perlin part). So we need to reload it then. perlinFB.reloadOnAltTab = true; perlinFB.Bind(); perlinFB.AttachTexture(textureAtlas->gltex); drawPerlinTex = perlinFB.CheckStatus("PERLIN"); perlinFB.Unbind(); } modelRenderers.resize(MODELTYPE_OTHER, NULL); for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) { modelRenderers[modelType] = IWorldObjectModelRenderer::GetInstance(modelType); } }
/* * CArchiveScanner::ArchiveData */ CArchiveScanner::ArchiveData::ArchiveData(const LuaTable& archiveTable) { if (!archiveTable.IsValid()) { return; } std::vector<std::string> keys; if (!archiveTable.GetKeys(keys)) { return; } std::vector<std::string>::const_iterator key; for (key = keys.begin(); key != keys.end(); ++key) { const std::string& keyLower = StringToLower(*key); if (!ArchiveData::IsReservedKey(keyLower)) { if (keyLower == "modtype") { SetInfoItemValueInteger(*key, archiveTable.GetInt(*key, 0)); continue; } const int luaType = archiveTable.GetType(*key); switch (luaType) { case LuaTable::STRING: { SetInfoItemValueString(*key, archiveTable.GetString(*key, "")); } break; case LuaTable::NUMBER: { SetInfoItemValueFloat(*key, archiveTable.GetFloat(*key, 0.0f)); } break; case LuaTable::BOOLEAN: { SetInfoItemValueBool(*key, archiveTable.GetBool(*key, false)); } break; default: { // just ignore unsupported types (most likely to be lua-tables) //throw content_error("Lua-type " + IntToString(luaType) + " not supported in archive-info, but it is used on key \"" + *key + "\""); } break; } } } const LuaTable _dependencies = archiveTable.SubTable("depend"); for (int dep = 1; _dependencies.KeyExists(dep); ++dep) { dependencies.push_back(_dependencies.GetString(dep, "")); } const LuaTable _replaces = archiveTable.SubTable("replace"); for (int rep = 1; _replaces.KeyExists(rep); ++rep) { replaces.push_back(_replaces.GetString(rep, "")); } //! FIXME //! XXX HACK needed until lobbies, lobbyserver and unitsync are sorted out //! so they can uniquely identify different versions of the same mod. //! (at time of this writing they use name only) //! NOTE when changing this, this function is used both by the code that //! reads ArchiveCache.lua and the code that reads modinfo.lua from the mod. //! so make sure it doesn't keep adding stuff to the name everytime //! Spring/unitsync is loaded. const std::string& name = GetName(); const std::string& version = GetVersion(); if ((name.find(version) == std::string::npos) && !version.empty()) { SetInfoItemValueString("name", name + " " + version); } }
CUnitDefHandler::CUnitDefHandler(void) : noCost(false) { weaponDefHandler = new CWeaponDefHandler(); PrintLoadMsg("Loading unit definitions"); const LuaTable rootTable = game->defsParser->GetRoot().SubTable("UnitDefs"); if (!rootTable.IsValid()) { throw content_error("Error loading UnitDefs"); } vector<string> unitDefNames; rootTable.GetKeys(unitDefNames); numUnitDefs = unitDefNames.size(); /* // ?? "restricted" does not automatically mean "cannot be built // at all, so we don't need the unitdef for this unit" -- Kloot numUnitDefs -= gameSetup->restrictedUnits.size(); */ // This could be wasteful if there is a lot of restricted units, but that is not that likely unitDefs = new UnitDef[numUnitDefs + 1]; // start at unitdef id 1 unsigned int id = 1; for (unsigned int a = 0; a < unitDefNames.size(); ++a) { const string unitName = unitDefNames[a]; /* // Restrictions may tell us not to use this unit at all // FIXME: causes mod errors when a unit is restricted to // 0, since GetUnitByName() will return NULL if its UnitDef // has not been loaded -- Kloot const std::map<std::string, int>& resUnits = gameSetup->restrictedUnits; if ((resUnits.find(unitName) != resUnits.end()) && (resUnits.find(unitName)->second == 0)) { continue; } */ // Seems ok, load it unitDefs[id].valid = false; unitDefs[id].name = unitName; unitDefs[id].id = id; unitDefs[id].buildangle = 0; unitDefs[id].buildPic = NULL; unitDefs[id].decoyDef = NULL; unitDefs[id].techLevel = -1; unitDefs[id].collisionVolume = NULL; unitID[unitName] = id; for (int ym = 0; ym < 4; ym++) { unitDefs[id].yardmaps[ym] = 0; } // parse the unitdef data (but don't load buildpics, etc...) LuaTable udTable = rootTable.SubTable(unitName); ParseUnitDef(udTable, unitName, id); // Increase index for next unit id++; } // set the real number of unitdefs numUnitDefs = (id - 1); CleanBuildOptions(); FindStartUnits(); ProcessDecoys(); AssignTechLevels(); }
/* * CArchiveScanner::ArchiveData */ CArchiveScanner::ArchiveData::ArchiveData(const LuaTable& archiveTable, bool fromCache) { if (!archiveTable.IsValid()) return; std::vector<std::string> keys; if (!archiveTable.GetKeys(keys)) return; for (std::string& key: keys) { const std::string& keyLower = StringToLower(key); if (ArchiveData::IsReservedKey(keyLower)) continue; if (keyLower == "modtype") { SetInfoItemValueInteger(key, archiveTable.GetInt(key, 0)); continue; } switch (archiveTable.GetType(key)) { case LuaTable::STRING: { SetInfoItemValueString(key, archiveTable.GetString(key, "")); } break; case LuaTable::NUMBER: { SetInfoItemValueFloat(key, archiveTable.GetFloat(key, 0.0f)); } break; case LuaTable::BOOLEAN: { SetInfoItemValueBool(key, archiveTable.GetBool(key, false)); } break; default: { // just ignore unsupported types (most likely to be lua-tables) //throw content_error("Lua-type " + IntToString(luaType) + " not supported in archive-info, but it is used on key \"" + *key + "\""); } break; } } const LuaTable& _dependencies = archiveTable.SubTable("depend"); const LuaTable& _replaces = archiveTable.SubTable("replace"); for (int dep = 1; _dependencies.KeyExists(dep); ++dep) { dependencies.push_back(_dependencies.GetString(dep, "")); } for (int rep = 1; _replaces.KeyExists(rep); ++rep) { replaces.push_back(_replaces.GetString(rep, "")); } // FIXME // XXX HACK needed until lobbies, lobbyserver and unitsync are sorted out // so they can uniquely identify different versions of the same mod. // (at time of this writing they use name only) // NOTE when changing this, this function is used both by the code that // reads ArchiveCache.lua and the code that reads modinfo.lua from the mod. // so make sure it doesn't keep adding stuff to the name everytime // Spring/unitsync is loaded. const std::string& name = GetNameVersioned(); const std::string& version = GetVersion(); if (!version.empty()) { if (name.find(version) == std::string::npos) { SetInfoItemValueString("name", name + " " + version); } else if (!fromCache) { LOG_L(L_WARNING, "[%s] version \"%s\" included in name \"%s\"", __func__, version.c_str(), name.c_str()); } } if (GetName().empty()) SetInfoItemValueString("name_pure", name); }
CProjectileHandler::CProjectileHandler() { PrintLoadMsg("Creating projectile texture"); maxParticles = configHandler->Get("MaxParticles", 4000); maxNanoParticles = configHandler->Get("MaxNanoParticles", 10000); currentParticles = 0; currentNanoParticles = 0; particleSaturation = 0.0f; nanoParticleSaturation = 0.0f; numPerlinProjectiles = 0; // preload some IDs // (note that 0 is reserved for unsynced projectiles) for (int i = 1; i <= 12345; i++) { freeIDs.push_back(i); } maxUsedID = freeIDs.size(); textureAtlas = new CTextureAtlas(2048, 2048); // used to block resources_map.tdf from loading textures set<string> blockMapTexNames; LuaParser resourcesParser("gamedata/resources.lua", SPRING_VFS_MOD_BASE, SPRING_VFS_ZIP); if (!resourcesParser.Execute()) { logOutput.Print(resourcesParser.GetErrorLog()); } const LuaTable rootTable = resourcesParser.GetRoot(); const LuaTable gfxTable = rootTable.SubTable("graphics"); const LuaTable ptTable = gfxTable.SubTable("projectileTextures"); // add all textures in projectiletextures section map<string, string> ptex; ptTable.GetMap(ptex); for (map<string, string>::iterator pi=ptex.begin(); pi!=ptex.end(); ++pi) { textureAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); blockMapTexNames.insert(StringToLower(pi->first)); } // add all texture from sections within projectiletextures section vector<string> seclist; ptTable.GetKeys(seclist); for (size_t i = 0; i < seclist.size(); i++) { const LuaTable ptSubTable = ptTable.SubTable(seclist[i]); if (ptSubTable.IsValid()) { map<string, string> ptex2; ptSubTable.GetMap(ptex2); for (map<string, string>::iterator pi = ptex2.begin(); pi != ptex2.end(); ++pi) { textureAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); blockMapTexNames.insert(StringToLower(pi->first)); } } } // get the smoke textures, hold the count in 'smokeCount' const LuaTable smokeTable = gfxTable.SubTable("smoke"); int smokeCount; if (smokeTable.IsValid()) { for (smokeCount = 0; true; smokeCount++) { const string tex = smokeTable.GetString(smokeCount + 1, ""); if (tex.empty()) { break; } const string texName = "bitmaps/" + tex; const string smokeName = "ismoke" + IntToString(smokeCount, "%02i"); textureAtlas->AddTexFromFile(smokeName, texName); blockMapTexNames.insert(StringToLower(smokeName)); } } else { // setup the defaults for (smokeCount = 0; smokeCount < 12; smokeCount++) { const string smokeNum = IntToString(smokeCount, "%02i"); const string smokeName = "ismoke" + smokeNum; const string texName = "bitmaps/smoke/smoke" + smokeNum + ".tga"; textureAtlas->AddTexFromFile(smokeName, texName); blockMapTexNames.insert(StringToLower(smokeName)); } } if (smokeCount <= 0) { throw content_error("missing smoke textures"); } char tex[128][128][4]; for (int y = 0; y < 128; y++) { // shield for (int x = 0; x < 128; x++) { tex[y][x][0] = 70; tex[y][x][1] = 70; tex[y][x][2] = 70; tex[y][x][3] = 70; } } textureAtlas->AddTexFromMem("perlintex", 128, 128, CTextureAtlas::RGBA32, tex); blockMapTexNames.insert("perlintex"); blockMapTexNames.insert("flare"); blockMapTexNames.insert("explo"); blockMapTexNames.insert("explofade"); blockMapTexNames.insert("heatcloud"); blockMapTexNames.insert("laserend"); blockMapTexNames.insert("laserfalloff"); blockMapTexNames.insert("randdots"); blockMapTexNames.insert("smoketrail"); blockMapTexNames.insert("wake"); blockMapTexNames.insert("perlintex"); blockMapTexNames.insert("flame"); blockMapTexNames.insert("sbtrailtexture"); blockMapTexNames.insert("missiletrailtexture"); blockMapTexNames.insert("muzzleflametexture"); blockMapTexNames.insert("repulsetexture"); blockMapTexNames.insert("dguntexture"); blockMapTexNames.insert("flareprojectiletexture"); blockMapTexNames.insert("sbflaretexture"); blockMapTexNames.insert("missileflaretexture"); blockMapTexNames.insert("beamlaserflaretexture"); blockMapTexNames.insert("bubbletexture"); blockMapTexNames.insert("geosquaretexture"); blockMapTexNames.insert("gfxtexture"); blockMapTexNames.insert("projectiletexture"); blockMapTexNames.insert("repulsegfxtexture"); blockMapTexNames.insert("sphereparttexture"); blockMapTexNames.insert("torpedotexture"); blockMapTexNames.insert("wrecktexture"); blockMapTexNames.insert("plasmatexture"); // allow map specified atlas textures for gaia unit projectiles LuaParser mapResParser("gamedata/resources_map.lua", SPRING_VFS_MOD_BASE, SPRING_VFS_ZIP); if (mapResParser.IsValid()) { const LuaTable mapRoot = mapResParser.GetRoot(); const LuaTable mapTable = mapRoot.SubTable("projectileTextures"); //add all textures in projectiletextures section map<string, string> mptex; mapTable.GetMap(mptex); map<string, string>::iterator pi; for (pi = mptex.begin(); pi != mptex.end(); ++pi) { if (blockMapTexNames.find(StringToLower(pi->first)) == blockMapTexNames.end()) { textureAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); } } //add all texture from sections within projectiletextures section mapTable.GetKeys(seclist); for (size_t i = 0; i < seclist.size(); i++) { const LuaTable mapSubTable = mapTable.SubTable(seclist[i]); if (mapSubTable.IsValid()) { map<string, string> ptex2; mapSubTable.GetMap(ptex2); for (map<string, string>::iterator pi = ptex2.begin(); pi != ptex2.end(); ++pi) { if (blockMapTexNames.find(StringToLower(pi->first)) == blockMapTexNames.end()) { textureAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); } } } } } if (!textureAtlas->Finalize()) { logOutput.Print("Could not finalize projectile texture atlas. Use less/smaller textures."); } flaretex = textureAtlas->GetTexture("flare"); explotex = textureAtlas->GetTexture("explo"); explofadetex = textureAtlas->GetTexture("explofade"); heatcloudtex = textureAtlas->GetTexture("heatcloud"); laserendtex = textureAtlas->GetTexture("laserend"); laserfallofftex = textureAtlas->GetTexture("laserfalloff"); randdotstex = textureAtlas->GetTexture("randdots"); smoketrailtex = textureAtlas->GetTexture("smoketrail"); waketex = textureAtlas->GetTexture("wake"); perlintex = textureAtlas->GetTexture("perlintex"); flametex = textureAtlas->GetTexture("flame"); for (int i = 0; i < smokeCount; i++) { const string smokeName = "ismoke" + IntToString(i, "%02i"); smoketex.push_back(textureAtlas->GetTexture(smokeName)); } #define GETTEX(t, b) textureAtlas->GetTextureWithBackup((t), (b)) sbtrailtex = GETTEX("sbtrailtexture", "smoketrail" ); missiletrailtex = GETTEX("missiletrailtexture", "smoketrail" ); muzzleflametex = GETTEX("muzzleflametexture", "explo" ); repulsetex = GETTEX("repulsetexture", "explo" ); dguntex = GETTEX("dguntexture", "flare" ); flareprojectiletex = GETTEX("flareprojectiletexture", "flare" ); sbflaretex = GETTEX("sbflaretexture", "flare" ); missileflaretex = GETTEX("missileflaretexture", "flare" ); beamlaserflaretex = GETTEX("beamlaserflaretexture", "flare" ); bubbletex = GETTEX("bubbletexture", "circularthingy"); geosquaretex = GETTEX("geosquaretexture", "circularthingy"); gfxtex = GETTEX("gfxtexture", "circularthingy"); projectiletex = GETTEX("projectiletexture", "circularthingy"); repulsegfxtex = GETTEX("repulsegfxtexture", "circularthingy"); sphereparttex = GETTEX("sphereparttexture", "circularthingy"); torpedotex = GETTEX("torpedotexture", "circularthingy"); wrecktex = GETTEX("wrecktexture", "circularthingy"); plasmatex = GETTEX("plasmatexture", "circularthingy"); #undef GETTEX groundFXAtlas = new CTextureAtlas(2048, 2048); //add all textures in groundfx section const LuaTable groundfxTable = gfxTable.SubTable("groundfx"); groundfxTable.GetMap(ptex); for (map<string, string>::iterator pi = ptex.begin(); pi != ptex.end(); ++pi) { groundFXAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); } //add all texture from sections within groundfx section groundfxTable.GetKeys(seclist); for (size_t i = 0; i < seclist.size(); i++) { const LuaTable gfxSubTable = groundfxTable.SubTable(seclist[i]); if (gfxSubTable.IsValid()) { map<string, string> ptex2; gfxSubTable.GetMap(ptex2); for (map<string, string>::iterator pi = ptex2.begin(); pi != ptex2.end(); ++pi) { groundFXAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second); } } } if (!groundFXAtlas->Finalize()) { logOutput.Print("Could not finalize groundFX texture atlas. Use less/smaller textures."); } groundflashtex = groundFXAtlas->GetTexture("groundflash"); groundringtex = groundFXAtlas->GetTexture("groundring"); seismictex = groundFXAtlas->GetTexture("seismic"); if (shadowHandler->canUseShadows) { projectileShadowVP = LoadVertexProgram("projectileshadow.vp"); } for (int a = 0; a < 4; ++a) { perlinBlend[a]=0; } unsigned char tempmem[4*16*16]; for (int a = 0; a < 4 * 16 * 16; ++a) { tempmem[a] = 0; } for (int a = 0; a < 8; ++a) { glGenTextures(1, &perlinTex[a]); glBindTexture(GL_TEXTURE_2D, perlinTex[a]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16,16, 0, GL_RGBA, GL_UNSIGNED_BYTE, tempmem); } drawPerlinTex=false; if (perlinFB.IsValid()) { //we never refresh the full texture (just the perlin part). So we need to reload it then. perlinFB.reloadOnAltTab = true; perlinFB.Bind(); perlinFB.AttachTexture(textureAtlas->gltex); drawPerlinTex=perlinFB.CheckStatus("PERLIN"); perlinFB.Unbind(); } }