void CEconomyTracker::UnitCreated(int unitID) { if (trackerOff) { return; } const int frame = ai->cb->GetCurrentFrame(); const UnitDef* unitDef = ai->cb->GetUnitDef(unitID); const bool iscommander = CUNIT::IsCommander(unitDef); if (unitDef == NULL || iscommander || unitDef->canDGun) { // ignore the commander return; } EconomyUnitTracker* economyUnitTracker = new EconomyUnitTracker; economyUnitTracker->clear(); economyUnitTracker->economyUnitId = unitID; economyUnitTracker->createFrame = -frame; economyUnitTracker->alive = true; economyUnitTracker->category = GCAT(unitID); economyUnitTracker->unitDef = unitDef; SetUnitDefDataInTracker(economyUnitTracker); underConstructionEconomyUnitTrackers.push_back(economyUnitTracker); // find it (slow++) int catIdx = int(CAT_COMM); bool found = false; for (; catIdx < int(CAT_LAST); catIdx++ ) { std::list<BuildTask>::iterator i; for (i = ai->uh->BuildTasks[catIdx].begin(); i != ai->uh->BuildTasks[catIdx].end(); i++) { BuildTask bt = *i; if (bt.id == unitID) { // add this new unit to the list BuildingTracker tracker; tracker.clear(); tracker.economyUnitTracker = economyUnitTracker; tracker.buildTask = true; tracker.category = UnitCategory(catIdx); tracker.unitUnderConstruction = unitID; allTheBuildingTrackers[catIdx].push_front(tracker); found = true; break; } } } if (!found) { // it is made by a factory float3 unitPos = ai->cb->GetUnitPos(unitID); UnitCategory category = GCAT(unitID); for (std::list<Factory>::iterator i = ai->uh->Factories.begin(); i != ai->uh->Factories.end(); i++) { Factory factory = *i; int factoryId = factory.id; // bad, no easy way to get the factory of the unit float3 factoryPos = ai->cb->GetUnitPos(factoryId); float distance = factoryPos.distance2D(unitPos); if (distance < 100.0f) { BuildingTracker tracker; tracker.clear(); tracker.economyUnitTracker = economyUnitTracker; tracker.category = category; tracker.unitUnderConstruction = unitID; tracker.factory = factoryId; allTheBuildingTrackers[category].push_front(tracker); found = true; break; } } } // unit constructor not found?! // assert(found); }
void CUnitTable::ReadModConfig() { ai->GetLogger()->Log("[CUnitTable::ReadModConfig()]"); std::string cfgFileName = GetModCfgName(); std::fstream cfgFile; std::stringstream msg; int cfgVersion = 0; if (ai->cb->GetFileSize(cfgFileName.c_str()) != -1) { if (!ai->luaParser->Execute(cfgFileName, "config")) { msg << "\tparse-error in existing mod configuration file \""; msg << cfgFileName << "\": " << ai->luaParser->GetError(); ai->GetLogger()->Log(msg.str()); return; } else { msg << "\tparsed existing mod configuration file \""; msg << cfgFileName << "\""; ai->GetLogger()->Log(msg.str()); } const LuaTable* rootTbl = ai->luaParser->GetRootTbl(); const LuaTable* unitTbl = NULL; const UnitDef* unitDef = NULL; if (rootTbl->GetIntVal("version", cfgVersion) > CFGVERSION) { msg.str(""); msg << "\tconfig-file version (" << cfgVersion << ") is newer than current version (" << CFGVERSION << ")"; return; } UnitType* unitType = NULL; UnitCategory defUnitCat = CAT_LAST; UnitCategory cfgUnitCat = CAT_LAST; std::list<std::string> keys; rootTbl->GetStrTblKeys(&keys); for (std::list<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it) { unitDef = ai->cb->GetUnitDef((*it).c_str()); if (unitDef == NULL) { msg.str(""); msg << "\t\t.cfg entry \"" << (*it) << "\" does not refer to a valid unit-type"; ai->GetLogger()->Log(msg.str()); continue; } unitTbl = rootTbl->GetTblVal(*it); unitType = &unitTypes[unitDef->id]; unitType->costMultiplier = unitTbl->GetIntVal("costMult", 100) / 100.0f; unitType->techLevel = unitTbl->GetIntVal("techLevel", -1); defUnitCat = unitType->category; cfgUnitCat = UnitCategory(unitTbl->GetIntVal("category", CAT_LAST)); { msg.str(""); msg << "\t\tunitDef->id: " << unitDef->id << ", unitDef->name: " << unitDef->name; msg << ", default cat.: " << defUnitCat << ", .cfg cat.: " << cfgUnitCat; ai->GetLogger()->Log(msg.str()); } /* * TODO: look for any possible "side-effects" that might arise * from overriding categories like this, then enable overrides * other than builder --> attacker (ie. SEGV when an *unarmed* * CAT_BUILDER unit masquerading as a CAT_G_ATTACK'er wants to * or is attacked, due to NULL weapondefs) */ if (defUnitCat != cfgUnitCat) { if (cfgUnitCat < 0 || cfgUnitCat >= CAT_LAST) { // invalid unit-category number continue; } if (cfgUnitCat == CAT_G_ATTACK && defUnitCat == CAT_BUILDER) { { msg.str(""); msg << "\t\t\t.cfg unit category (CAT_G_ATTACK) overrides unitType->category (CAT_BUILDER)"; ai->GetLogger()->Log(msg.str()); } std::vector<int>::iterator vit; std::vector<int>& oldDefs = categoryData.GetDefsForUnitCat(defUnitCat); std::vector<int>& newDefs = categoryData.GetDefsForUnitCat(cfgUnitCat); for (vit = oldDefs.begin(); vit != oldDefs.end(); vit++) { const int unitDefID = *vit; if (unitDefID == unitDef->id) { oldDefs.erase(vit); newDefs.push_back(unitDefID); vit--; } } unitType->category = cfgUnitCat; } } } } else { { msg.str(""); msg << "\twriting new mod configuration file \""; msg << cfgFileName << "\""; ai->GetLogger()->Log(msg.str()); } cfgFile.open(cfgFileName.c_str(), std::ios::out); cfgFile << "config = {\n"; cfgFile << "\tversion = " << CFGVERSION << ",\n\n"; for (int i = 1; i <= numDefs; i++) { UnitType* unitType = &unitTypes[i]; // assign and write default values for costMultiplier // and techLevel, category is already set in ::Init() unitType->costMultiplier = 1.0f; unitType->techLevel = -1; cfgFile << "\t" << unitType->def->name << " = {\n"; cfgFile << "\t\tcostMult = " << unitType->costMultiplier << " * 100" << ",\n"; cfgFile << "\t\ttechLevel = " << unitType->techLevel << ",\n"; cfgFile << "\t\tcategory = " << unitType->category << ",\n"; cfgFile << "\t},\n"; } cfgFile << "}\n"; cfgFile.close(); } }