⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aai.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				ut->RemovePowerPlant(unit);
			}
			else if(category == STATIONARY_ARTY)
			{
				ut->RemoveStationaryArty(unit);
			}
			else if(category == STATIONARY_RECON)
			{
				ut->RemoveRecon(unit);
			}
			else if(category == STATIONARY_JAMMER)
			{
				ut->RemoveJammer(unit);
			}
			else if(category == METAL_MAKER)
			{
				ut->RemoveMetalMaker(unit);
			}
			
			// clean up 
			if(category == STATIONARY_CONSTRUCTOR)
			{
				ut->RemoveConstructor(unit, def->id);

				// speed up reconstruction
				execute->urgency[category] += 1.5;
		
				// clear buildmap
				map->Pos2BuildMapPos(&pos, def);

				if(bt->CanPlacedLand(def->id))
				{
					map->CheckRows(pos.x, pos.z, def->xsize, def->ysize, false, false);
					map->SetBuildMap(pos.x, pos.z, def->xsize, def->ysize, 0);
					map->BlockCells(pos.x, pos.z - 8, def->xsize, 8, false, false);
					map->BlockCells(pos.x + def->xsize, pos.z - 8, cfg->X_SPACE, def->ysize + 1.5 * cfg->Y_SPACE, false, false);
					map->BlockCells(pos.x, pos.z + def->ysize, def->xsize, 1.5 * cfg->Y_SPACE - 8, false, false);
				}
				else
				{
					map->CheckRows(pos.x, pos.z, def->xsize, def->ysize, false, true);	
					map->SetBuildMap(pos.x, pos.z, def->xsize, def->ysize, 4);
					map->BlockCells(pos.x, pos.z - 8, def->xsize, 8, false, true);
					map->BlockCells(pos.x + def->xsize, pos.z - 8, cfg->X_SPACE, def->ysize + 1.5 * cfg->Y_SPACE, false, true);
					map->BlockCells(pos.x, pos.z + def->ysize, def->xsize, 1.5 * cfg->Y_SPACE - 8, false, true);
				}
			}
			// hq
			else if(category == COMMANDER)
			{
				ut->RemoveCommander(unit, def->id);

				// clear buildmap
				map->Pos2BuildMapPos(&pos, def);

				if(def->minWaterDepth <= 0)
				{
					map->CheckRows(pos.x, pos.z, def->xsize, def->ysize, false, false);
					map->SetBuildMap(pos.x, pos.z, def->xsize, def->ysize, 0);
					map->BlockCells(pos.x, pos.z - 8, def->xsize, 8, false, false);
					map->BlockCells(pos.x + def->xsize, pos.z - 8, cfg->X_SPACE, def->ysize + 1.5 * cfg->Y_SPACE, false, false);
					map->BlockCells(pos.x, pos.z + def->ysize, def->xsize, 1.5 * cfg->Y_SPACE - 8, false, false);
				}
				else
				{
					map->CheckRows(pos.x, pos.z, def->xsize, def->ysize, false, true);	
					map->SetBuildMap(pos.x, pos.z, def->xsize, def->ysize, 4);
					map->BlockCells(pos.x, pos.z - 8, def->xsize, 8, false, true);
					map->BlockCells(pos.x + def->xsize, pos.z - 8, cfg->X_SPACE, def->ysize + 1.5 * cfg->Y_SPACE, false, true);
					map->BlockCells(pos.x, pos.z + def->ysize, def->xsize, 1.5 * cfg->Y_SPACE - 8, false, true);
				}
			}
			// other building
			else
			{
				// clear buildmap
				map->Pos2BuildMapPos(&pos, def);

				if(def->minWaterDepth <= 0)
				{
					map->SetBuildMap(pos.x, pos.z, def->xsize, def->ysize, 0);
					map->CheckRows(pos.x, pos.z, def->xsize, def->ysize, false, false);
				}
				else
				{
					map->SetBuildMap(pos.x, pos.z, def->xsize, def->ysize, 4);
					map->CheckRows(pos.x, pos.z, def->xsize, def->ysize, false, true);
				}
			}

			// if no buildings left in that sector, remove from base sectors
			if(map->sector[x][y].GetNumberOfBuildings() == 0 && brain->sectors[0].size() > 0)
			{
				map->sector[x][y].SetBase(false);

				brain->sectors[0].remove(&map->sector[x][y]);

				brain->UpdateNeighbouringSectors();
				brain->UpdateBaseCenter();

				brain->expandable = true;

				fprintf(file, "\nRemoving sector %i,%i from base; base size: %i \n", x, y, brain->sectors[0].size());
			}
		}
		else // finished unit has been killed
		{
			// scout
			if(category == SCOUT)
			{
				--activeScouts;

				// remove from scout list
				for(list<int>::iterator i = scouts.begin(); i != scouts.end(); i++)
				{
					if(*i == unit)
					{
						scouts.erase(i);
						break;
					}
				}

				// add building to sector
				if(validSector && map->sector[x][y].distance_to_base > 0)
					map->sector[x][y].enemy_structures += 5;
				
			}
			// assault units 
			else if(category >= GROUND_ASSAULT && category <= SUBMARINE_ASSAULT)
			{
				// look for a safer rallypoint if units get killed on their way 
				if(ut->units[unit].status == HEADING_TO_RALLYPOINT)
				{
					float3 pos = execute->GetRallyPoint(category, 1, 1, 10);

					if(pos.x > 0)
						ut->units[unit].group->rally_point = pos;
				}

				if(ut->units[unit].group)
					ut->units[unit].group->RemoveUnit(unit, attacker);
				else
					fprintf(file, "ERROR: tried to remove %s but group not found\n", bt->unitList[def->id-1]->name.c_str());		
			}
			// builder 
			else if(bt->IsBuilder(def->id))
			{
				ut->RemoveConstructor(unit, def->id);
			}
			else if(category == COMMANDER)
			{
				ut->RemoveCommander(unit, def->id);
			}
		}
	}

	ut->RemoveUnit(unit);
}

void AAI::UnitFinished(int unit) 
{
	if(!initialized)
		return;

	// get unit磗 id and side
	const UnitDef *def = cb->GetUnitDef(unit);
	int side = bt->GetSideByID(def->id)-1;

	UnitCategory category = bt->units_static[def->id].category;
	futureUnits[category] -= 1;
	activeUnits[category] += 1;
	
	bt->units_dynamic[def->id].requested -= 1;
	bt->units_dynamic[def->id].active += 1;

	// building was completed
	if(!def->movedata && !def->canfly)
	{
		// delete buildtask
		for(list<AAIBuildTask*>::iterator task = build_tasks.begin(); task != build_tasks.end(); task++)
		{
			if((*task)->unit_id == unit)
			{
				AAIBuildTask *build_task = *task;
				
				if((*task)->builder_id >= 0 && ut->units[(*task)->builder_id].cons)
					ut->units[(*task)->builder_id].cons->ConstructionFinished();
				
				build_tasks.erase(task);
				delete build_task;
				break;
			}
		}

		// check if building belongs to one of this groups
		if(category == EXTRACTOR)
		{
			ut->AddExtractor(unit);

			// order defence if necessary
			execute->DefendMex(unit, def->id);
		}
		else if(category == POWER_PLANT)
		{
			ut->AddPowerPlant(unit, def->id);
		}
		else if(category == STORAGE)
		{
			execute->futureStoredEnergy -= bt->unitList[def->id-1]->energyStorage;
			execute->futureStoredMetal -= bt->unitList[def->id-1]->metalStorage;
		}
		else if(category == METAL_MAKER)
		{
			ut->AddMetalMaker(unit, def->id);
		}
		else if(category == STATIONARY_RECON)
		{
			ut->AddRecon(unit, def->id);
		}
		else if(category == STATIONARY_JAMMER)
		{
			ut->AddJammer(unit, def->id);
		}
		else if(category == STATIONARY_ARTY)
		{
			ut->AddStationaryArty(unit, def->id);
		}
		else if(category == STATIONARY_CONSTRUCTOR)
		{
			ut->AddConstructor(unit, def->id);
		}
		return;
	}
	else	// unit was completed
	{
		// unit 
		if(category >= GROUND_ASSAULT && category <= SUBMARINE_ASSAULT)
		{
			execute->AddUnitToGroup(unit, def->id, category);

			brain->AddDefenceCapabilities(def->id, category);

			ut->SetUnitStatus(unit, HEADING_TO_RALLYPOINT);
		}
		// scout
		else if(category == SCOUT)
		{
			++activeScouts;
			--futureScouts;

			scouts.push_back(unit);

			// cloak scout if cloakable
			if(def->canCloak)
			{
				Command c;
				c.id = CMD_CLOAK;
				c.params.push_back(1);

				cb->GiveOrder(unit, &c);
			}
		}
		// builder 
		else if(bt->IsBuilder(def->id))
		{
			ut->AddConstructor(unit, def->id);
		}
	}
}

void AAI::UnitIdle(int unit)
{
	// if factory is idle, start construction of further units
	if(ut->units[unit].cons)
	{
		if(ut->units[unit].cons->assistance < 0 && ut->units[unit].cons->construction_unit_id < 0 )
		{	
			/*if(!ut->units[unit].cons->factory)
			{
				char c[120];

				if(ut->units[unit].cons->construction_unit_id == -1)
					sprintf(c, "%s / %i is idle\n", bt->unitList[ut->units[unit].cons->def_id-1]->humanName.c_str(), unit);
				else
					sprintf(c, "%s is idle building %s\n", bt->unitList[ut->units[unit].cons->def_id-1]->humanName.c_str(), bt->unitList[ut->units[unit].cons->construction_def_id-1]->humanName.c_str());

				cb->SendTextMsg(c,0);
			}*/

			ut->units[unit].cons->Idle();

			if(ut->constructors.size() < 4)
				execute->CheckConstruction();

			ut->SetUnitStatus(unit, UNIT_IDLE);
		}
	}
	// idle combat units will report to their groups
	else if(ut->units[unit].group)
	{
		ut->SetUnitStatus(unit, UNIT_IDLE);
		ut->units[unit].group->UnitIdle(unit);
	}
	else
		ut->SetUnitStatus(unit, UNIT_IDLE);

}

void AAI::UnitMoveFailed(int unit) 
{
	// not a good solution at all, hopefully not necessary in the future due to bug fixes 
	// in the path finding routines
	/*float3 pos = cb->GetUnitPos(unit);

	int x = pos.x/map->xSectorSize;
	int y = pos.z/map->ySectorSize;
	
	if(x < 0 || y < 0 || x >= map->xSectors || y >= map->ySectors)
		return;

	pos = map->sector[x][y].GetCenter();
	pos.x += rand()%4 * map->xSectorSize;
	pos.z += rand()%4 * map->ySectorSize;

	execute->moveUnitTo(unit, &pos);*/

	
	const UnitDef *def = cb->GetUnitDef(unit);

	if(ut->units[unit].cons)
	{
		AAIConstructor* builder = ut->units[unit].cons;

		if(builder->task == BUILDING)
		{
			if(builder->construction_unit_id == -1)
			{
				--bt->units_dynamic[builder->construction_def_id].requested;
				--futureUnits[builder->construction_category];

				// clear up buildmap etc.
				execute->ConstructionFailed(builder->build_pos, builder->construction_def_id);

				// free builder
				builder->ConstructionFinished();
			}
		}
	}


}

void AAI::EnemyEnterLOS(int enemy) {}
void AAI::EnemyLeaveLOS(int enemy) {}
void AAI::EnemyEnterRadar(int enemy) {}
void AAI::EnemyLeaveRadar(int enemy) {}

void AAI::EnemyDestroyed(int enemy, int attacker) 
{
	// remove enemy from unittable
	ut->EnemyKilled(enemy);

	if(attacker)
	{	
		// get unit磗 id 
		const UnitDef *def = cb->GetUnitDef(enemy);
		const UnitDef *def_att = cb->GetUnitDef(attacker);

		if(def_att)
		{
			// unit was destroyed
			if(def)
			{
				int killer = bt->GetIDOfAssaultCategory(bt->units_static[def_att->id].category);
				int killed = bt->GetIDOfAssaultCategory(bt->units_static[def->id].category);

				if(killer != -1 && killed != -1)
				{
					bt->UpdateTable(def_att, killer, def, killed);
					map->UpdateCategoryUsefulness(def_att, killer, def, killed);
				}
			}
		}
	}
}

void AAI::Update()
{
	int tick = cb->GetCurrentFrame();

	if(!initialized)
	{
		if(!(tick%450))
			cb->SendTextMsg("Failed to initialize AAI! Please view ai log for further information and check if AAI supports this mod", 0);

		return;
	}

	// scouting
	if(!(tick%cfg->SCOUT_UPDATE_FREQUENCY))
	{
		execute->UpdateRecon(); // update threat values for all sectors, move scouts...
	}
	
	// update groups
	if(!(tick%219))
	{
		for(list<UnitCategory>::iterator category = bt->assault_categories.begin(); category != bt->assault_categories.end(); category++)
		{
			for(list<AAIGroup*>::iterator group = group_list[*category].begin(); group != group_list[*category].end(); group++)
				(*group)->Update();
		}

		return;
	}

	// unit management 
	if(!(tick%649))
	{
		execute->CheckBuildques();
		brain->BuildUnits();
	}

	if(!(tick%911))
	{
		// check attack
		am->Update();
		af->BombBestUnit(2, 2);
		return;
	}

	// ressource management
	if(!(tick%199))
	{
		execute->CheckRessources();
	}

	// update sectors
	if(!(tick%423))
	{
		brain->UpdateAttackedByValues();
		map->UpdateSectors();
	}

	// builder management
	if(!(tick%917))
	{
		brain->UpdateDefenceCapabilities();
	}

	// update income 
	if(!(tick%45))
	{
		execute->UpdateRessources();
	}

	// building management
	if(!(tick%97))
	{
		execute->CheckConstruction();
	}

	// builder/factory management
	if(!(tick%677))
	{
		for(set<int>::iterator builder = ut->constructors.begin(); builder != ut->constructors.end(); ++builder)
			ut->units[(*builder)].cons->Update();
	}

	
	if(!(tick%437))
	{
		execute->CheckFactories();
	}

	if(!(tick%1079))
	{
		execute->CheckDefences(); 
	}

	// build radar/jammer
	if(!(tick%1177))
	{
		execute->CheckRecon();
		execute->CheckJammer();
		execute->CheckStationaryArty();
		execute->CheckAirBase();
	}

	// upgrade mexes
	if(!(tick%2173))
	{
		execute->CheckMexUpgrade();
		execute->CheckRadarUpgrade();
		execute->CheckJammerUpgrade();
	}

	// recheck rally points
	if(!(tick%2577))
	{
		for(list<UnitCategory>::iterator category = bt->assault_categories.begin(); category != bt->assault_categories.end(); category++)
		{
			for(list<AAIGroup*>::iterator group = group_list[*category].begin(); group != group_list[*category].end(); group++)
				(*group)->rally_point = execute->GetRallyPoint(*category, 1, 1, 10);
		}
	}

	// recalculate efficiency stats
	if(!(tick%2827))
	{
		if(aai_instance == 1)
			bt->UpdateMinMaxAvgEfficiency();
	}
}

int AAI::HandleEvent(int msg,const void* data)
{
   switch (msg)
   {
   case AI_EVENT_UNITCAPTURED: // 2
      {
         const IGlobalAI::ChangeTeamEvent* cte = (const IGlobalAI::ChangeTeamEvent*) data;
         UnitDestroyed(cte->unit,-1);
      }
      break;
   }
   return 0;
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -