/** ** Define a force, a groups of units. ** ** @param l Lua state. */ static int CclAiForce(lua_State *l) { LuaCheckArgs(l, 2); if (!lua_istable(l, 2)) { LuaError(l, "incorrect argument"); } int force = LuaToNumber(l, 1); if (force < 0 || force >= AI_MAX_FORCES) { LuaError(l, "Force out of range: %d" _C_ force); } AiForce &aiforce = AiPlayer->Force[AiPlayer->Force.getScriptForce(force)]; int args = lua_rawlen(l, 2); for (int j = 0; j < args; ++j) { lua_rawgeti(l, 2, j + 1); CUnitType *type = CclGetUnitType(l); lua_pop(l, 1); ++j; lua_rawgeti(l, 2, j + 1); int count = LuaToNumber(l, -1); lua_pop(l, 1); if (!type) { // bulletproof continue; } // Use the equivalent unittype. type = UnitTypes[UnitTypeEquivs[type->Slot]]; // Look if already in force. size_t i; for (i = 0; i < aiforce.UnitTypes.size(); ++i) { AiUnitType *aiut = &aiforce.UnitTypes[i]; if (aiut->Type->Slot == type->Slot) { // found if (count) { aiut->Want = count; } else { aiforce.UnitTypes.erase(aiforce.UnitTypes.begin() + i); } break; } } // New type append it. if (i == aiforce.UnitTypes.size()) { AiUnitType newaiut; newaiut.Want = count; newaiut.Type = type; aiforce.UnitTypes.push_back(newaiut); } } AiAssignFreeUnitsToForce(); lua_pushboolean(l, 0); return 1; }
/** ** Entry point of force manager, perodic called. */ global void AiForceManager(void) { int force; // // Look if our defenders still have enemies in range. // for( force=0; force<AI_MAX_FORCES; ++force ) { if( AiPlayer->Force[force].Defending ) { const AiUnit* aiunit; AiCleanForce(force); // // Look if still enemies in attack range. // aiunit=AiPlayer->Force[force].Units; while( aiunit ) { if( aiunit->Unit->Type->CanAttack && AttackUnitsInReactRange(aiunit->Unit) ) { break; } aiunit=aiunit->Next; } if( !aiunit ) { // No enemies go home. DebugLevel0Fn("FIXME: not written, should send force home\n"); AiPlayer->Force[force].Defending=0; AiPlayer->Force[force].Attacking=0; } } if( AiPlayer->Force[force].Attacking ) { AiCleanForce(force); AiGuideAttackForce(&AiPlayer->Force[force]); } } AiAssignFreeUnitsToForce(); }
/** ** Entry point of force manager, periodic called. */ void AiForceManager() { AiPlayer->Force.Update(); AiAssignFreeUnitsToForce(); }