Exemple #1
0
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);
}
Exemple #2
0
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();
	}
}