792 lines
32 KiB
Java
792 lines
32 KiB
Java
package enemyAI;
|
|
|
|
import core.AssetManager;
|
|
import core.baseInfo;
|
|
import core.mainThread;
|
|
import entity.constructionYard;
|
|
import entity.goldMine;
|
|
import entity.harvester;
|
|
import entity.solidObject;
|
|
import core.vector;
|
|
|
|
//1. scan revealed area for player's units and building
|
|
//2. keep track of player's units
|
|
//3. create strategic information based on the quantity/location of player's units
|
|
|
|
|
|
public class mapAwarenessAI {
|
|
|
|
public baseInfo theBaseInfo;
|
|
public int frameAI;
|
|
|
|
public int numberOfLightTanks_player, numberOfLightTanks_AI, numberOfLightTanksOnMinimap_player;
|
|
public int numberOfStealthTanks_player, numberOfStealthTanks_AI, numberOfStealthTanksOnMinimap_player;
|
|
public int numberOfRocketTanks_player, numberOfRocketTanks_AI, numberOfRocketTanksOnMinimap_player;
|
|
public int numberOfHeavyTanks_player, numberOfHeavyTanks_AI, numberOfHeavyTanksOnMinimap_player;
|
|
public int numberOfPlayerUnitsOnMinimap;
|
|
public int totalNumberOfPlayerUnits;
|
|
public int numberOfGunTurret_player;
|
|
public int numberOfMissileTurret_player;
|
|
public int numberOfFactory_player;
|
|
public int numberOfRefinery_player;
|
|
public int numberOfConstructionYard_player;
|
|
public int numberOfCommunicationCenter_player;
|
|
public int numberOfTechCenter_player;
|
|
public int numberOfPowerPlant_player;
|
|
|
|
public int maxNumberOfStealthTanks_playerInLastFiveMinutes;
|
|
public int fiveMinuteTimer;
|
|
|
|
public int numberOfPlayerUnitDestroyed;
|
|
public int numberOfPlayerBuildingDestroyed;
|
|
public int numberOfPlayerUnitDestroyedInPreviousFrame;
|
|
public int numberOfPlayerBuildingDestroyedPreviousFrame;
|
|
public int playerAssetDestoryedCountDown;
|
|
|
|
public boolean playerHasMostlyLightTanks;
|
|
public boolean playerHasMostlyHeavyTanks;
|
|
public boolean playIsRushingHighTierUnits;
|
|
public boolean playerLikelyCanNotProduceHighTierUnits;
|
|
public boolean playerDoesntHaveMassHeavyTanks;
|
|
public boolean playerArmyCanBeCounteredWithLightTanks;
|
|
public boolean playerArmyCanBeCounteredWithStealthTanks;
|
|
public boolean playerIsRushingLightTank;
|
|
public boolean playerHasManyLightTanksButNoHeavyTank;
|
|
public boolean playerHasMostlyHeavyAndStealthTanks;
|
|
public boolean playerHasMostlyLightAndStealthTanks;
|
|
public boolean canRushPlayer;
|
|
public boolean playerIsFastExpanding;
|
|
public boolean playerForceNearBase;
|
|
|
|
public solidObject[] mapAsset;
|
|
public boolean[] visionMap;
|
|
public AssetManager theAssetManager;
|
|
public solidObject[] playerUnitInMinimap;
|
|
public solidObject[] playerStaticDefenceInMinimap;
|
|
public solidObject[] playerStructures;
|
|
public int numOfAIStructures;
|
|
public solidObject[] AIStructures;
|
|
|
|
public goldMine[] goldMines;
|
|
public int targetPlayerExpension;
|
|
public int[] playerExpensionInfo;
|
|
public int numberOfplayerMiningBases;
|
|
|
|
public vector mainPlayerForceLocation;
|
|
public vector mainPlayerForceDirection;
|
|
public int mainPlayerForceSize;
|
|
public vector[] playerForceLocations;
|
|
public vector[] playerForceDirections;
|
|
public int[] playerForceSize;
|
|
public vector playerNaturalLocation;
|
|
|
|
public vector[] playerStaticDefenseLocations;
|
|
public int[] playerStaticDefenseSize;
|
|
public int[] playerStaticDefenseStrength;
|
|
|
|
public mapAwarenessAI(){
|
|
this.theBaseInfo = mainThread.ec.theBaseInfo;
|
|
this.visionMap = mainThread.ec.visionMap;
|
|
|
|
mapAsset = new solidObject[1024];
|
|
playerUnitInMinimap = new solidObject[128];
|
|
playerStaticDefenceInMinimap = new solidObject[64];
|
|
playerStructures = new solidObject[256];
|
|
AIStructures = new solidObject[128];
|
|
|
|
goldMines = mainThread.theAssetManager.goldMines;
|
|
playerExpensionInfo = new int[goldMines.length];
|
|
playerNaturalLocation = goldMines[1].centre;
|
|
|
|
mainPlayerForceLocation = new vector(0,0,0);
|
|
mainPlayerForceDirection = new vector(0,0,0);
|
|
mainPlayerForceSize = 0;
|
|
playerForceLocations = new vector[3];
|
|
playerForceDirections = new vector[3];
|
|
playerForceSize = new int[3];
|
|
|
|
for(int i = 0; i < playerForceLocations.length; i++) {
|
|
playerForceLocations[i] = new vector(0,0,0);
|
|
playerForceDirections[i] = new vector(0,0,0);
|
|
playerForceSize[i] = 0;
|
|
}
|
|
|
|
playerStaticDefenseLocations = new vector[3];
|
|
playerStaticDefenseSize = new int[3];
|
|
playerStaticDefenseStrength = new int[3];
|
|
|
|
for(int i = 0; i < playerStaticDefenseLocations.length; i++) {
|
|
playerStaticDefenseLocations[i] = new vector(0,0,0);
|
|
playerStaticDefenseSize[i] = 0;
|
|
playerStaticDefenseStrength[i] = 0;
|
|
}
|
|
}
|
|
|
|
public void processAI(){
|
|
frameAI = mainThread.ec.frameAI;
|
|
|
|
theAssetManager = mainThread.theAssetManager;
|
|
|
|
//the number of player's military units in AI's vision
|
|
numberOfLightTanksOnMinimap_player = 0;
|
|
numberOfRocketTanksOnMinimap_player = 0;
|
|
numberOfStealthTanksOnMinimap_player = 0;
|
|
numberOfHeavyTanksOnMinimap_player = 0;
|
|
numberOfPlayerUnitsOnMinimap = 0;
|
|
|
|
//the total number of player's unit that are detected by AI
|
|
numberOfLightTanks_player = 0;
|
|
numberOfRocketTanks_player = 0;
|
|
numberOfStealthTanks_player = 0;
|
|
numberOfHeavyTanks_player = 0;
|
|
numberOfGunTurret_player = 0;
|
|
numberOfMissileTurret_player = 0;
|
|
numberOfFactory_player = 0;
|
|
numberOfRefinery_player = 0;
|
|
numberOfConstructionYard_player = 0;
|
|
numberOfCommunicationCenter_player = 0;
|
|
numberOfTechCenter_player = 0;
|
|
|
|
//the total number of AI military units
|
|
numberOfLightTanks_AI = 0;
|
|
numberOfRocketTanks_AI = 0;
|
|
numberOfStealthTanks_AI = 0;
|
|
numberOfHeavyTanks_AI = 0;
|
|
|
|
//clear info from previous frame
|
|
for(int i = 0; i < playerUnitInMinimap.length; i++)
|
|
playerUnitInMinimap[i] = null;
|
|
for(int i = 0; i < playerStaticDefenceInMinimap.length; i++)
|
|
playerStaticDefenceInMinimap[i] = null;
|
|
for(int i = 0; i < playerStructures.length; i++)
|
|
playerStructures[i] = null;
|
|
for(int i = 0; i < AIStructures.length; i++)
|
|
AIStructures[i] = null;
|
|
numOfAIStructures = 0;
|
|
|
|
if(playerAssetDestoryedCountDown > 0)
|
|
playerAssetDestoryedCountDown--;
|
|
|
|
|
|
for(int i = 0; i < theAssetManager.lightTanks.length; i++){
|
|
if(theAssetManager.lightTanks[i] != null && theAssetManager.lightTanks[i].teamNo ==0){
|
|
if(visionMap[theAssetManager.lightTanks[i].occupiedTile0]){
|
|
numberOfLightTanksOnMinimap_player++;
|
|
addPlayerUnitInMinimap(theAssetManager.lightTanks[i]);
|
|
if(mapAsset[theAssetManager.lightTanks[i].ID] == null) {
|
|
mapAsset[theAssetManager.lightTanks[i].ID] = theAssetManager.lightTanks[i];
|
|
mainThread.ec.theCombatManagerAI.unrevealedPlayerForceStrength-=1;
|
|
}
|
|
}
|
|
}else if(theAssetManager.lightTanks[i] != null && theAssetManager.lightTanks[i].teamNo !=0){
|
|
numberOfLightTanks_AI++;
|
|
if(mapAsset[theAssetManager.lightTanks[i].ID] == null){
|
|
mainThread.ec.theUnitProductionAI.addLightTank(theAssetManager.lightTanks[i]);
|
|
mapAsset[theAssetManager.lightTanks[i].ID] = theAssetManager.lightTanks[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < theAssetManager.rocketTanks.length; i++){
|
|
if(theAssetManager.rocketTanks[i] != null && theAssetManager.rocketTanks[i].teamNo ==0){
|
|
if(visionMap[theAssetManager.rocketTanks[i].occupiedTile0]){
|
|
numberOfRocketTanksOnMinimap_player++;
|
|
addPlayerUnitInMinimap(theAssetManager.rocketTanks[i]);
|
|
if(mapAsset[theAssetManager.rocketTanks[i].ID] == null) {
|
|
mapAsset[theAssetManager.rocketTanks[i].ID] = theAssetManager.rocketTanks[i];
|
|
mainThread.ec.theCombatManagerAI.unrevealedPlayerForceStrength-=1.5;
|
|
}
|
|
}
|
|
}else if(theAssetManager.rocketTanks[i] != null && theAssetManager.rocketTanks[i].teamNo !=0){
|
|
numberOfRocketTanks_AI++;
|
|
if(mapAsset[theAssetManager.rocketTanks[i].ID] == null){
|
|
mainThread.ec.theUnitProductionAI.addRocketTank(theAssetManager.rocketTanks[i]);
|
|
mapAsset[theAssetManager.rocketTanks[i].ID] = theAssetManager.rocketTanks[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < theAssetManager.stealthTanks.length; i++){
|
|
if(theAssetManager.stealthTanks[i] != null && theAssetManager.stealthTanks[i].teamNo ==0){
|
|
if(visionMap[theAssetManager.stealthTanks[i].occupiedTile0] && !theAssetManager.stealthTanks[i].isCloaked){
|
|
numberOfStealthTanksOnMinimap_player++;
|
|
addPlayerUnitInMinimap(theAssetManager.stealthTanks[i]);
|
|
if(mapAsset[theAssetManager.stealthTanks[i].ID] == null) {
|
|
mapAsset[theAssetManager.stealthTanks[i].ID] = theAssetManager.stealthTanks[i];
|
|
mainThread.ec.theCombatManagerAI.unrevealedPlayerForceStrength-=2;
|
|
}
|
|
}
|
|
}else if(theAssetManager.stealthTanks[i] != null && theAssetManager.stealthTanks[i].teamNo !=0){
|
|
numberOfStealthTanks_AI++;
|
|
if(mapAsset[theAssetManager.stealthTanks[i].ID] == null){
|
|
mainThread.ec.theUnitProductionAI.addStealthTank(theAssetManager.stealthTanks[i]);
|
|
mapAsset[theAssetManager.stealthTanks[i].ID] = theAssetManager.stealthTanks[i];
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
for(int i = 0; i < theAssetManager.heavyTanks.length; i++){
|
|
if(theAssetManager.heavyTanks[i] != null && theAssetManager.heavyTanks[i].teamNo ==0){
|
|
if(visionMap[theAssetManager.heavyTanks[i].occupiedTile0]){
|
|
numberOfHeavyTanksOnMinimap_player++;
|
|
addPlayerUnitInMinimap(theAssetManager.heavyTanks[i]);
|
|
if(mapAsset[theAssetManager.heavyTanks[i].ID] == null) {
|
|
mapAsset[theAssetManager.heavyTanks[i].ID] = theAssetManager.heavyTanks[i];
|
|
mainThread.ec.theCombatManagerAI.unrevealedPlayerForceStrength-=3.5;
|
|
}
|
|
}
|
|
}else if(theAssetManager.heavyTanks[i] != null && theAssetManager.heavyTanks[i].teamNo !=0){
|
|
numberOfHeavyTanks_AI++;
|
|
if(mapAsset[theAssetManager.heavyTanks[i].ID] == null){
|
|
mainThread.ec.theUnitProductionAI.addHeavyTank(theAssetManager.heavyTanks[i]);
|
|
mapAsset[theAssetManager.heavyTanks[i].ID] = theAssetManager.heavyTanks[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < theAssetManager.harvesters.length; i++){
|
|
if(theAssetManager.harvesters[i] != null && theAssetManager.harvesters[i].teamNo ==0){
|
|
if(visionMap[theAssetManager.harvesters[i].occupiedTile0]){
|
|
//addPlayerUnitInMinimap(theAssetManager.harvesters[i]);
|
|
mapAsset[theAssetManager.harvesters[i].ID] = theAssetManager.harvesters[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < theAssetManager.constructionVehicles.length; i++){
|
|
if(theAssetManager.constructionVehicles[i] != null && theAssetManager.constructionVehicles[i].teamNo ==0){
|
|
if(visionMap[theAssetManager.constructionVehicles[i].occupiedTile0]){
|
|
addPlayerUnitInMinimap(theAssetManager.constructionVehicles[i]);
|
|
mapAsset[theAssetManager.constructionVehicles[i].ID] = theAssetManager.constructionVehicles[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//add revealed player's building to mapAsset
|
|
for(int i = 0; i < theAssetManager.gunTurrets.length; i++){
|
|
if(theAssetManager.gunTurrets[i] != null && theAssetManager.gunTurrets[i].teamNo ==0){
|
|
if(visionMap[theAssetManager.gunTurrets[i].tileIndex[0]]){
|
|
if(mapAsset[theAssetManager.gunTurrets[i].ID] == null) {
|
|
mapAsset[theAssetManager.gunTurrets[i].ID] = theAssetManager.gunTurrets[i];
|
|
mainThread.ec.theCombatManagerAI.unrevealedPlayerForceStrength-=1;
|
|
}
|
|
}
|
|
}else if(theAssetManager.gunTurrets[i] != null && theAssetManager.gunTurrets[i].teamNo !=0) {
|
|
AIStructures[numOfAIStructures] = theAssetManager.gunTurrets[i];
|
|
numOfAIStructures++;
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < theAssetManager.missileTurrets.length; i++){
|
|
if(theAssetManager.missileTurrets[i] != null && theAssetManager.missileTurrets[i].teamNo ==0){
|
|
if(visionMap[theAssetManager.missileTurrets[i].tileIndex[0]]){
|
|
if(mapAsset[theAssetManager.missileTurrets[i].ID] == null) {
|
|
mapAsset[theAssetManager.missileTurrets[i].ID] = theAssetManager.missileTurrets[i];
|
|
mainThread.ec.theCombatManagerAI.unrevealedPlayerForceStrength-=2;
|
|
}
|
|
}
|
|
}else if(theAssetManager.missileTurrets[i] != null && theAssetManager.missileTurrets[i].teamNo !=0) {
|
|
AIStructures[numOfAIStructures] = theAssetManager.missileTurrets[i];
|
|
numOfAIStructures++;
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < theAssetManager.factories.length; i++){
|
|
if(theAssetManager.factories[i] != null && theAssetManager.factories[i].teamNo ==0){
|
|
for(int j = 0; j < 6; j++){
|
|
if(visionMap[theAssetManager.factories[i].tileIndex[j]]){
|
|
if(mapAsset[theAssetManager.factories[i].ID] == null)
|
|
mapAsset[theAssetManager.factories[i].ID] = theAssetManager.factories[i];
|
|
break;
|
|
}
|
|
}
|
|
}else if(theAssetManager.factories[i] != null && theAssetManager.factories[i].teamNo !=0) {
|
|
AIStructures[numOfAIStructures] = theAssetManager.factories[i];
|
|
numOfAIStructures++;
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < theAssetManager.refineries.length; i++){
|
|
if(theAssetManager.refineries[i] != null && theAssetManager.refineries[i].teamNo ==0){
|
|
for(int j = 0; j < 6; j++){
|
|
if(visionMap[theAssetManager.refineries[i].tileIndex[j]]){
|
|
if(mapAsset[theAssetManager.refineries[i].ID] == null)
|
|
mapAsset[theAssetManager.refineries[i].ID] = theAssetManager.refineries[i];
|
|
break;
|
|
}
|
|
}
|
|
}else if(theAssetManager.refineries[i] != null && theAssetManager.refineries[i].teamNo !=0) {
|
|
AIStructures[numOfAIStructures] = theAssetManager.refineries[i];
|
|
numOfAIStructures++;
|
|
}
|
|
}
|
|
|
|
|
|
for(int i = 0; i < theAssetManager.constructionYards.length; i++){
|
|
if(theAssetManager.constructionYards[i] != null && theAssetManager.constructionYards[i].teamNo ==0){
|
|
for(int j = 0; j < 9; j++){
|
|
if(visionMap[theAssetManager.constructionYards[i].tileIndex[j]]){
|
|
if(mapAsset[theAssetManager.constructionYards[i].ID] == null)
|
|
mapAsset[theAssetManager.constructionYards[i].ID] = theAssetManager.constructionYards[i];
|
|
break;
|
|
}
|
|
}
|
|
}else if(theAssetManager.constructionYards[i] != null && theAssetManager.constructionYards[i].teamNo !=0) {
|
|
AIStructures[numOfAIStructures] = theAssetManager.constructionYards[i];
|
|
numOfAIStructures++;
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < theAssetManager.communicationCenters.length; i++){
|
|
if(theAssetManager.communicationCenters[i] != null && theAssetManager.communicationCenters[i].teamNo ==0){
|
|
for(int j = 0; j < 4; j++){
|
|
if(visionMap[theAssetManager.communicationCenters[i].tileIndex[j]]){
|
|
if(mapAsset[theAssetManager.communicationCenters[i].ID] == null)
|
|
mapAsset[theAssetManager.communicationCenters[i].ID] = theAssetManager.communicationCenters[i];
|
|
break;
|
|
}
|
|
}
|
|
}else if(theAssetManager.communicationCenters[i] != null && theAssetManager.communicationCenters[i].teamNo !=0) {
|
|
AIStructures[numOfAIStructures] = theAssetManager.communicationCenters[i];
|
|
numOfAIStructures++;
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < theAssetManager.techCenters.length; i++){
|
|
if(theAssetManager.techCenters[i] != null && theAssetManager.techCenters[i].teamNo ==0){
|
|
for(int j = 0; j < 4; j++){
|
|
if(visionMap[theAssetManager.techCenters[i].tileIndex[j]]){
|
|
if(mapAsset[theAssetManager.techCenters[i].ID] == null)
|
|
mapAsset[theAssetManager.techCenters[i].ID] = theAssetManager.techCenters[i];
|
|
break;
|
|
}
|
|
}
|
|
}else if(theAssetManager.techCenters[i] != null && theAssetManager.techCenters[i].teamNo !=0) {
|
|
AIStructures[numOfAIStructures] = theAssetManager.techCenters[i];
|
|
numOfAIStructures++;
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < theAssetManager.powerPlants.length; i++){
|
|
if(theAssetManager.powerPlants[i] != null && theAssetManager.powerPlants[i].teamNo ==0){
|
|
for(int j = 0; j < 4; j++){
|
|
if(visionMap[theAssetManager.powerPlants[i].tileIndex[j]]){
|
|
if(mapAsset[theAssetManager.powerPlants[i].ID] == null)
|
|
mapAsset[theAssetManager.powerPlants[i].ID] = theAssetManager.powerPlants[i];
|
|
break;
|
|
}
|
|
}
|
|
}else if(theAssetManager.powerPlants[i] != null && theAssetManager.powerPlants[i].teamNo !=0) {
|
|
AIStructures[numOfAIStructures] = theAssetManager.powerPlants[i];
|
|
numOfAIStructures++;
|
|
}
|
|
}
|
|
|
|
|
|
numberOfPlayerUnitDestroyed = 0;
|
|
numberOfPlayerBuildingDestroyed = 0;
|
|
|
|
|
|
for(int i = 0; i < mapAsset.length; i++){
|
|
if(mapAsset[i] != null && mapAsset[i].teamNo == 0){
|
|
if(mapAsset[i].currentHP>0){
|
|
if(mapAsset[i].type == 0 )
|
|
numberOfLightTanks_player++;
|
|
else if(mapAsset[i].type == 1)
|
|
numberOfRocketTanks_player++;
|
|
else if(mapAsset[i].type == 6)
|
|
numberOfStealthTanks_player++;
|
|
else if(mapAsset[i].type == 7)
|
|
numberOfHeavyTanks_player++;
|
|
else{
|
|
mapAsset[i].isRevealed_AI = true;
|
|
if(mapAsset[i].type == 200){
|
|
numberOfGunTurret_player++;
|
|
addPlayerStaticDefenceInMinimap(mapAsset[i]);
|
|
addPlayerStructure(mapAsset[i]);
|
|
}else if(mapAsset[i].type == 199){
|
|
addPlayerStaticDefenceInMinimap(mapAsset[i]);
|
|
addPlayerStructure(mapAsset[i]);
|
|
numberOfMissileTurret_player++;
|
|
}else if(mapAsset[i].type == 105){
|
|
addPlayerStructure(mapAsset[i]);
|
|
numberOfFactory_player++;
|
|
}else if(mapAsset[i].type == 102){
|
|
numberOfRefinery_player++;
|
|
addPlayerStructure(mapAsset[i]);
|
|
}else if(mapAsset[i].type == 104){
|
|
addPlayerStructure(mapAsset[i]);
|
|
numberOfConstructionYard_player++;
|
|
}else if(mapAsset[i].type == 106){
|
|
addPlayerStructure(mapAsset[i]);
|
|
numberOfCommunicationCenter_player++;
|
|
}else if(mapAsset[i].type == 107){
|
|
addPlayerStructure(mapAsset[i]);
|
|
numberOfTechCenter_player++;
|
|
}else if(mapAsset[i].type == 101){
|
|
addPlayerStructure(mapAsset[i]);
|
|
numberOfPowerPlant_player++;
|
|
}
|
|
}
|
|
}else{
|
|
if(mapAsset[i].attacker != null && mapAsset[i].attacker.teamNo != 0) {
|
|
if(mapAsset[i].type < 100)
|
|
numberOfPlayerUnitDestroyed++;
|
|
else
|
|
numberOfPlayerBuildingDestroyed++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(numberOfPlayerUnitDestroyed > numberOfPlayerUnitDestroyedInPreviousFrame || numberOfPlayerBuildingDestroyed > numberOfPlayerBuildingDestroyedPreviousFrame) {
|
|
playerAssetDestoryedCountDown = 30;
|
|
}
|
|
|
|
numberOfPlayerUnitDestroyedInPreviousFrame = numberOfPlayerUnitDestroyed;
|
|
numberOfPlayerBuildingDestroyedPreviousFrame = numberOfPlayerBuildingDestroyed;
|
|
|
|
//analyze the enemy units composition
|
|
totalNumberOfPlayerUnits = numberOfLightTanks_player + numberOfRocketTanks_player + numberOfStealthTanks_player + numberOfHeavyTanks_player;
|
|
|
|
float lightTankRatio = (float)(numberOfLightTanks_player)/(totalNumberOfPlayerUnits + 1);
|
|
|
|
playerHasMostlyLightTanks = (numberOfLightTanks_player > 5 && lightTankRatio > 0.8f) || (frameAI < 420 && numberOfLightTanks_player > 1 && lightTankRatio >= 0.75f);
|
|
playerHasMostlyHeavyTanks = numberOfHeavyTanks_player > 1 && (float)(numberOfHeavyTanks_player)/(totalNumberOfPlayerUnits) > 0.8f;
|
|
playerHasManyLightTanksButNoHeavyTank = lightTankRatio > 0.5 && numberOfHeavyTanks_player < 3;
|
|
|
|
playIsRushingHighTierUnits = mainThread.gameFrame/30 > 250 && mainThread.gameFrame/30 < 400
|
|
&& mainThread.ec.theMapAwarenessAI.numberOfTechCenter_player >0
|
|
&& mainThread.ec.theMapAwarenessAI.numberOfMissileTurret_player < 2
|
|
&& mainThread.ec.theMapAwarenessAI.numberOfGunTurret_player < 4
|
|
&& numberOfLightTanks_player + numberOfRocketTanks_player + numberOfStealthTanks_player < 5;
|
|
|
|
playerLikelyCanNotProduceHighTierUnits = mainThread.ec.theMapAwarenessAI.numberOfTechCenter_player == 0 && mainThread.ec.theMapAwarenessAI.numberOfHeavyTanks_player == 0;
|
|
playerDoesntHaveMassHeavyTanks = (float)numberOfHeavyTanks_player/( 1 + numberOfLightTanks_AI + numberOfRocketTanks_player + numberOfStealthTanks_player) < 0.2f;
|
|
|
|
playerIsRushingLightTank = mainThread.gameFrame/30 > 300 && mainThread.gameFrame/30 < 600 && ((playerLikelyCanNotProduceHighTierUnits && numberOfStealthTanks_player < 3) || playerHasMostlyLightTanks);
|
|
|
|
playerHasMostlyHeavyAndStealthTanks = (maxNumberOfStealthTanks_playerInLastFiveMinutes >=3 ) && (float)(numberOfHeavyTanks_player + numberOfStealthTanks_player)/totalNumberOfPlayerUnits > 0.85f;
|
|
|
|
playerHasMostlyLightAndStealthTanks = numberOfLightTanks_player > 5 && maxNumberOfStealthTanks_playerInLastFiveMinutes >=3 && (float)(numberOfLightTanks_player + numberOfStealthTanks_player)/totalNumberOfPlayerUnits > 0.85f;
|
|
|
|
if(frameAI < 600)
|
|
playerArmyCanBeCounteredWithLightTanks = false;
|
|
else {
|
|
playerArmyCanBeCounteredWithLightTanks = maxNumberOfStealthTanks_playerInLastFiveMinutes < 6 && (float)(numberOfHeavyTanks_player+ numberOfRocketTanks_player)/(totalNumberOfPlayerUnits + 1) > 0.85f;
|
|
}
|
|
|
|
playerArmyCanBeCounteredWithStealthTanks = (float)(numberOfLightTanks_player+ numberOfRocketTanks_player)/(totalNumberOfPlayerUnits + 1) > 0.85f;
|
|
|
|
|
|
//advanced counting of player units
|
|
if(numberOfStealthTanks_player > maxNumberOfStealthTanks_playerInLastFiveMinutes) {
|
|
maxNumberOfStealthTanks_playerInLastFiveMinutes = numberOfStealthTanks_player;
|
|
fiveMinuteTimer = 300;
|
|
}
|
|
if(fiveMinuteTimer > 0)
|
|
fiveMinuteTimer--;
|
|
else
|
|
maxNumberOfStealthTanks_playerInLastFiveMinutes = 0;
|
|
|
|
|
|
//if player fast expand then AI can rush the player
|
|
canRushPlayer = false;
|
|
if(frameAI >= 240 && frameAI < 360) {
|
|
|
|
for(int i = 0; i < playerStructures.length; i++) {
|
|
if(playerStructures[i] != null && playerStructures[i].currentHP > 0) {
|
|
float x1 = playerStructures[i].centre.x;
|
|
float z1 = playerStructures[i].centre.z;
|
|
float x2 = playerNaturalLocation.x;
|
|
float z2 = playerNaturalLocation.z;
|
|
|
|
if(Math.sqrt((x1-x2)*(x1-x2) + (z1-z2)*(z1-z2)) < 3.5f) {
|
|
playerIsFastExpanding = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
harvester[] harvesters = mainThread.theAssetManager.harvesters;
|
|
for(int i = 0; i < harvesters.length; i++) {
|
|
if(harvesters[i] != null && harvesters[i].currentHP > 0) {
|
|
float x1 = harvesters[i].centre.x;
|
|
float z1 = harvesters[i].centre.z;
|
|
float x2 = playerNaturalLocation.x;
|
|
float z2 = playerNaturalLocation.z;
|
|
|
|
if(Math.sqrt((x1-x2)*(x1-x2) + (z1-z2)*(z1-z2)) < 3.5f) {
|
|
playerIsFastExpanding = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(playerIsFastExpanding) {
|
|
|
|
if(mainThread.ec.theCombatManagerAI.checkIfAIHasBiggerForce(0.5f))
|
|
canRushPlayer = true;
|
|
}
|
|
|
|
findTheMostVulnerablePlayerBase();
|
|
|
|
findPlayerForceLocation();
|
|
|
|
findPlayerStaticDefense();
|
|
|
|
}
|
|
|
|
|
|
public void addPlayerUnitInMinimap(solidObject o){
|
|
for(int i = 0; i < playerUnitInMinimap.length; i++){
|
|
if(playerUnitInMinimap[i] == null){
|
|
playerUnitInMinimap[i] = o;
|
|
numberOfPlayerUnitsOnMinimap++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void addPlayerStaticDefenceInMinimap(solidObject o){
|
|
for(int i = 0; i < playerStaticDefenceInMinimap.length; i++){
|
|
if(playerStaticDefenceInMinimap[i] == null){
|
|
playerStaticDefenceInMinimap[i] = o;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void addPlayerStructure(solidObject o){
|
|
for(int i = 0; i < playerStructures.length; i++){
|
|
if(playerStructures[i] == null){
|
|
playerStructures[i] = o;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void findTheMostVulnerablePlayerBase(){
|
|
|
|
//check if there are any player's structure around each gold mine.
|
|
for(int i = 0; i < goldMines.length; i++){
|
|
playerExpensionInfo[i] = findplayexpensionDefenseScore(goldMines[i], 3.5f);
|
|
}
|
|
|
|
//compute the target player expansion defense score
|
|
targetPlayerExpension = -1;
|
|
int playExpensionDefenseScore = 999999;
|
|
|
|
|
|
numberOfplayerMiningBases = 0;
|
|
for(int i = 0; i < playerExpensionInfo.length; i++){
|
|
if(goldMines[i] != null && goldMines[i].goldDeposite > 5000 && playerExpensionInfo[i] != 0){
|
|
numberOfplayerMiningBases++;
|
|
if(playerExpensionInfo[i] < playExpensionDefenseScore){
|
|
playExpensionDefenseScore = playerExpensionInfo[i];
|
|
targetPlayerExpension = i;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
//if a player expansion exists on the path to the target expansion is already been taken by player's force,
|
|
//then mark it as the target expansion instead
|
|
if(targetPlayerExpension == 0){
|
|
if(playerExpensionInfo[5] >0)
|
|
targetPlayerExpension = 5;
|
|
else if(playerExpensionInfo[6] >0)
|
|
targetPlayerExpension = 6;
|
|
else if(playerExpensionInfo[7] >0)
|
|
targetPlayerExpension = 7;
|
|
else if(playerExpensionInfo[1] > 0)
|
|
targetPlayerExpension = 1;
|
|
}else if(targetPlayerExpension == 1){
|
|
if(playerExpensionInfo[5] >0)
|
|
targetPlayerExpension = 5;
|
|
else if(playerExpensionInfo[6] >0)
|
|
targetPlayerExpension = 6;
|
|
else if(playerExpensionInfo[7] >0)
|
|
targetPlayerExpension = 7;
|
|
}else if(targetPlayerExpension == 7){
|
|
if(playerExpensionInfo[5] >0)
|
|
targetPlayerExpension = 5;
|
|
else if(playerExpensionInfo[6] >0)
|
|
targetPlayerExpension = 6;
|
|
}else if(targetPlayerExpension == 6){
|
|
if(playerExpensionInfo[5] >0)
|
|
targetPlayerExpension = 5;
|
|
}
|
|
|
|
//if(targetPlayerExpension != -1)
|
|
// return playerExpensionInfo[targetPlayerExpension];
|
|
|
|
//return 0;
|
|
}
|
|
|
|
public int findplayexpensionDefenseScore(goldMine g, float r){
|
|
if(g == null)
|
|
return 0;
|
|
|
|
solidObject[] playerStructures = mainThread.ec.theMapAwarenessAI.playerStructures;
|
|
solidObject[] playerStaticDefence = mainThread.ec.theMapAwarenessAI.playerStaticDefenceInMinimap;
|
|
|
|
float x = g.centre.x;
|
|
float z = g.centre.z;
|
|
|
|
int playexpensionDefenseScore = 0;
|
|
for(int i = 0 ; i < playerStructures.length; i++){
|
|
if(playerStructures[i]!= null && Math.abs(playerStructures[i].centre.x - x) < r && Math.abs(playerStructures[i].centre.z - z) < r)
|
|
playexpensionDefenseScore++;
|
|
}
|
|
|
|
for(int i = 0 ; i < playerStaticDefence.length; i++){
|
|
if(playerStaticDefence[i]!= null && Math.abs(playerStructures[i].centre.x - x) < r && Math.abs(playerStructures[i].centre.z - z) < r){
|
|
if(playerStaticDefence[i].type == 200) //gun turret will increase player base's defense score
|
|
playexpensionDefenseScore+=1000;
|
|
if(playerStaticDefence[i].type == 199) //missile turret will increase player base's defense score even futher
|
|
playexpensionDefenseScore+=3000;
|
|
}
|
|
}
|
|
|
|
|
|
//if the player already takes the expansion which the enemy AI plans to expand to, assign zero score to this expansion
|
|
if(g == mainThread.ec.theBaseExpentionAI.expensionGoldMine && playexpensionDefenseScore > 0){
|
|
return -1;
|
|
}
|
|
|
|
return playexpensionDefenseScore;
|
|
}
|
|
|
|
//find the center of the clusters of player's static defenses. As well as the size of the clusters.
|
|
public void findPlayerStaticDefense() {
|
|
for(int i = 0; i < playerStaticDefenseLocations.length; i++) {
|
|
playerStaticDefenseLocations[i].set(0,0,0);
|
|
playerStaticDefenseSize[i] = 0;
|
|
playerStaticDefenseStrength[i] = 0;
|
|
}
|
|
|
|
for(int i = 0; i < playerStaticDefenceInMinimap.length; i++) {
|
|
if(playerStaticDefenceInMinimap[i] == null)
|
|
continue;
|
|
float xPos = playerStaticDefenceInMinimap[i].centre.x;
|
|
float zPos = playerStaticDefenceInMinimap[i].centre.z;
|
|
|
|
for(int j = 0; j < playerStaticDefenseLocations.length; j++) {
|
|
//always add the player static defense location to the empty list
|
|
if(playerStaticDefenseLocations[j].x == 0) {
|
|
playerStaticDefenseLocations[j].add(playerStaticDefenceInMinimap[i].centre);
|
|
playerStaticDefenseSize[j]++;
|
|
if(playerStaticDefenceInMinimap[j].type == 200)
|
|
playerStaticDefenseStrength[j]+=2;
|
|
if(playerStaticDefenceInMinimap[j].type == 199)
|
|
playerStaticDefenseStrength[j]+=6;
|
|
break;
|
|
}
|
|
float centerX = playerStaticDefenseLocations[j].x/playerStaticDefenseSize[j];
|
|
float centerZ = playerStaticDefenseLocations[j].z/playerStaticDefenseSize[j];
|
|
float d = (centerX - xPos) * (centerX - xPos) + (centerZ - zPos) * (centerZ - zPos);
|
|
//if the player static defence is close enough to the cluster center then add it to the list
|
|
if(d < 4) {
|
|
playerStaticDefenseLocations[j].add(playerStaticDefenceInMinimap[i].centre);
|
|
playerStaticDefenseSize[j]++;
|
|
if(playerStaticDefenceInMinimap[j].type == 200)
|
|
playerStaticDefenseStrength[j]+=2;
|
|
if(playerStaticDefenceInMinimap[j].type == 199)
|
|
playerStaticDefenseStrength[j]+=6;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
for(int i = 0; i < playerStaticDefenseLocations.length; i++) {
|
|
if(playerStaticDefenseSize[i] > 0)
|
|
playerStaticDefenseLocations[i].set(playerStaticDefenseLocations[i].x/playerStaticDefenseSize[i], 0, playerStaticDefenseLocations[i].z/playerStaticDefenseSize[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
//find the center of the biggest cluster of player units that are visible on the minimap. It will tells the AI which area is in danger of being attacked.
|
|
public void findPlayerForceLocation(){
|
|
mainPlayerForceLocation.set(0,0,0);
|
|
mainPlayerForceDirection.set(0,0,0);
|
|
mainPlayerForceSize = 0;
|
|
|
|
for(int i = 0; i < playerForceLocations.length; i++) {
|
|
playerForceLocations[i].set(0,0,0);
|
|
playerForceDirections[i].set(0,0,0);
|
|
playerForceSize[i] = 0;
|
|
}
|
|
|
|
for(int i = 0; i < playerUnitInMinimap.length; i++) {
|
|
if(playerUnitInMinimap[i] == null)
|
|
continue;
|
|
float xPos = playerUnitInMinimap[i].centre.x;
|
|
float zPos = playerUnitInMinimap[i].centre.z;
|
|
|
|
for(int j = 0; j < playerForceLocations.length; j++) {
|
|
//always add the player unit location to the empty list
|
|
if(playerForceLocations[j].x == 0) {
|
|
playerForceLocations[j].add(playerUnitInMinimap[i].centre);
|
|
playerForceSize[j]++;
|
|
playerForceDirections[j].add(playerUnitInMinimap[i].movement);
|
|
break;
|
|
}
|
|
float centerX = playerForceLocations[j].x/playerForceSize[j];
|
|
float centerZ = playerForceLocations[j].z/playerForceSize[j];
|
|
float d = (centerX - xPos) * (centerX - xPos) + (centerZ - zPos) * (centerZ - zPos);
|
|
//if the player unit is close enough to the force center then add it to the list
|
|
if(d < 4) {
|
|
playerForceLocations[j].add(playerUnitInMinimap[i].centre);
|
|
playerForceSize[j]++;
|
|
playerForceDirections[j].add(playerUnitInMinimap[i].movement);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < playerForceLocations.length; i++) {
|
|
if(playerForceSize[i] > mainPlayerForceSize) {
|
|
mainPlayerForceSize = playerForceSize[i];
|
|
mainPlayerForceLocation.set(playerForceLocations[i].x/mainPlayerForceSize,0,playerForceLocations[i].z/mainPlayerForceSize);
|
|
mainPlayerForceDirection.set(playerForceDirections[i].x/mainPlayerForceSize, 0, playerForceDirections[i].z/mainPlayerForceSize);
|
|
}
|
|
}
|
|
|
|
if(mainPlayerForceDirection.getLength() < 0.001) {
|
|
mainPlayerForceDirection.reset();
|
|
}else {
|
|
mainPlayerForceDirection.unit();
|
|
}
|
|
|
|
//check if player force is near any of AI's base
|
|
playerForceNearBase = false;
|
|
float x = mainPlayerForceLocation.x;
|
|
float z = mainPlayerForceLocation.z;
|
|
constructionYard[] constructionYards = mainThread.theAssetManager.constructionYards;
|
|
for(int i = 0; i < constructionYards.length; i++) {
|
|
if(constructionYards[i] != null && constructionYards[i].teamNo != 0 && constructionYards[i].currentHP > 0) {
|
|
double d = Math.sqrt((constructionYards[i].centre.x - x)*(constructionYards[i].centre.x - x) + (constructionYards[i].centre.z - z)*(constructionYards[i].centre.z - z));
|
|
if(d < 4.75) {
|
|
playerForceNearBase = true;
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|