This commit is contained in:
Pan 2019-04-21 09:58:12 +12:00
parent 697f91ca42
commit 1c9bbd5f84
17 changed files with 147 additions and 73 deletions

1
core/.gitignore vendored
View File

@ -19,3 +19,4 @@
/texture.class
/vector.class
/playerCommander.class
/sideBarManager.class

View File

@ -183,14 +183,14 @@ public class AssetManager {
gunTurrets = new gunTurret[512];
missileTurrets = new missileTurret[256];
goldMines[0].goldDeposite = 45000;
goldMines[1].goldDeposite = 45000;
goldMines[2].goldDeposite = 50000;
goldMines[3].goldDeposite = 50000;
goldMines[4].goldDeposite = 45000;
goldMines[5].goldDeposite = 45000;
goldMines[6].goldDeposite = 55000;
goldMines[7].goldDeposite = 55000;
goldMines[0].goldDeposite = goldMines[0].maxDeposite;
goldMines[1].goldDeposite = goldMines[1].maxDeposite;
goldMines[2].goldDeposite = goldMines[2].maxDeposite;
goldMines[3].goldDeposite = goldMines[3].maxDeposite;
goldMines[4].goldDeposite = goldMines[4].maxDeposite;
goldMines[5].goldDeposite = goldMines[5].maxDeposite;
goldMines[6].goldDeposite = goldMines[6].maxDeposite;
goldMines[7].goldDeposite = goldMines[7].maxDeposite;
bullets = new bullet[200];
for(int i = 0; i < 200; i ++){
@ -305,14 +305,14 @@ public class AssetManager {
gunTurrets = null;
missileTurrets = null;
goldMines[0].goldDeposite = 45000;
goldMines[1].goldDeposite = 45000;
goldMines[2].goldDeposite = 50000;
goldMines[3].goldDeposite = 50000;
goldMines[4].goldDeposite = 45000;
goldMines[5].goldDeposite = 45000;
goldMines[6].goldDeposite = 55000;
goldMines[7].goldDeposite = 55000;
goldMines[0].goldDeposite = goldMines[0].maxDeposite;
goldMines[1].goldDeposite = goldMines[1].maxDeposite;
goldMines[2].goldDeposite = goldMines[2].maxDeposite;
goldMines[3].goldDeposite = goldMines[3].maxDeposite;
goldMines[4].goldDeposite = goldMines[4].maxDeposite;
goldMines[5].goldDeposite = goldMines[5].maxDeposite;
goldMines[6].goldDeposite = goldMines[6].maxDeposite;
goldMines[7].goldDeposite = goldMines[7].maxDeposite;
bullets = null;
rockets = null;

View File

@ -6,7 +6,6 @@ import entity.constructionYard;
import entity.factory;
import entity.solidObject;
import gui.inputHandler;
import gui.sideBarManager;
//this class interprets player's inputs and turns them into commands that can be issued to game units
public class playerCommander {

View File

@ -1,8 +1,7 @@
package gui;
package core;
import core.mainThread;
import core.playerCommander;
import entity.*;
import gui.inputHandler;
//this class handles player's interaction with the sidebar
public class sideBarManager {

1
enemyAI/.gitignore vendored
View File

@ -8,3 +8,4 @@
/microManagementAI.class
/scoutingManagerAI.class
/unitProductionAI.class
/harassmentAI.class

View File

@ -23,8 +23,8 @@ public class baseExpensionAI {
public boolean allExpansionOccupied;
public int lastExpansionLocation;
public baseExpensionAI(baseInfo theBaseInfo){
this.theBaseInfo = theBaseInfo;
public baseExpensionAI(){
this.theBaseInfo = mainThread.ec.theBaseInfo;
frameAI = 0;
temp = new vector(0,0,0);
@ -144,7 +144,7 @@ public class baseExpensionAI {
boolean playerHasLessUnits = mainThread.ec.theCombatManagerAI.checkIfAIHasBiggerForce(1f);
int lowGoldmineThreshold = 20000;
int lowGoldmineThreshold = 22500;
if(playerHasLessUnits) {
@ -172,14 +172,13 @@ public class baseExpensionAI {
if(numberOfMCVOnQueue == 0 && theBaseInfo.canBuildMCV){
for(int i = 0; i < mainThread.theAssetManager.factories.length; i++){
if(mainThread.theAssetManager.factories[i] != null && mainThread.theAssetManager.factories[i].teamNo != 0){
//if(main.theAssetManager.factories[i].lightTankProgress < 240 || main.theAssetManager.factories[i].isIdle()){
mainThread.theAssetManager.factories[i].cancelItemFromProductionQueue(factory.lightTankType);
mainThread.theAssetManager.factories[i].cancelItemFromProductionQueue(factory.rocketTankType);
mainThread.theAssetManager.factories[i].cancelItemFromProductionQueue(factory.stealthTankType);
mainThread.theAssetManager.factories[i].cancelItemFromProductionQueue(factory.heavyTankType);
mainThread.theAssetManager.factories[i].buildMCV();
break;
//}
break;
}
}
}

View File

@ -20,8 +20,8 @@ public class buildingManagerAI {
public int frameIndex;
public buildingManagerAI (baseInfo theBaseInfo){
this.theBaseInfo = theBaseInfo;
public buildingManagerAI (){
this.theBaseInfo = mainThread.ec.theBaseInfo;
buildingPlacementCheckTiles = solidObject.generateTileCheckList(13);
buildingPlacementCheckTiles_2x2 = new int[buildingPlacementCheckTiles.length];

View File

@ -61,10 +61,15 @@ public class combatManagerAI {
public boolean unitCountLow;
public int standardAttackTime, rushAttackTime;
public combatManagerAI(baseInfo theBaseInfo){
this.theBaseInfo = theBaseInfo;
public combatManagerAI(){
this.theBaseInfo = mainThread.ec.theBaseInfo;
standardAttackTime = 600;
rushAttackTime = 300;
goldMines = mainThread.theAssetManager.goldMines;
@ -152,15 +157,18 @@ public class combatManagerAI {
if(currentState == booming){
//enemy AI compares its own force with player's force, then make a decision whether it should attack or not
int attackTime = 540;
int attackTime = standardAttackTime;
if(mainThread.ec.theMapAwarenessAI.canRushPlayer)
attackTime = 300;
attackTime = rushAttackTime;
int targetPlayerExpension = mainThread.ec.theMapAwarenessAI.targetPlayerExpension;
if(frameAI > attackTime) {
if(targetPlayerExpension == 0 || targetPlayerExpension == 1 || targetPlayerExpension == 6 || targetPlayerExpension == 7)
shouldAttack = checkIfAIHasBiggerForce(0.9f);
if(frameAI < 700)
shouldAttack = checkIfAIHasBiggerForce(0.5f);
else
shouldAttack = checkIfAIHasBiggerForce(0.75f);
else
shouldAttack = checkIfAIHasBiggerForce(1.2f);
}
@ -305,6 +313,11 @@ public class combatManagerAI {
}
}
//if a rush tactics is denied by the player (e.g player builds static defenses around natural), then change status to booming
if(frameAI < standardAttackTime && !mainThread.ec.theMapAwarenessAI.canRushPlayer){
currentState = booming;
return;
}
attackDirection.set(attackPosition.x - combatCenterX, 0, attackPosition.z - combatCenterZ);
distanceToTarget = attackDirection.getLength();
@ -364,7 +377,7 @@ public class combatManagerAI {
//check if the player force has become stronger than the AI during the marching towards attack position
//System.out.println("distanceToTarget: " + distanceToTarget);
if(checkIfAIHasBiggerForce(1.5f) == false && distanceToTarget > 5){
if(checkIfAIHasBiggerForce(1.5f) == false && distanceToTarget > 6){
playerHasBecomeStrongerThanAIDuringMarching = true;
}

View File

@ -44,8 +44,8 @@ public class defenseManagerAI {
public vector missileTurretDeployLocation;
public defenseManagerAI(baseInfo theBaseInfo){
this.theBaseInfo = theBaseInfo;
public defenseManagerAI(){
this.theBaseInfo = mainThread.ec.theBaseInfo;
observers = new solidObject[4];
@ -95,7 +95,7 @@ public class defenseManagerAI {
}
if(gameTime > 880) {
if(gameTime > 980) {
xPos = 0.25f;
zPos = 20.5f;
@ -133,7 +133,7 @@ public class defenseManagerAI {
zPos = 24.5f;
}
if(gameTime > 880) {
if(gameTime > 980) {
if(gameTime%18 < 9) {
xPos = 0.25f;
zPos = 20.5f;
@ -155,7 +155,7 @@ public class defenseManagerAI {
zPos = 20f;
}
if(gameTime > 880) {
if(gameTime > 980) {
if(gameTime%14 < 7) {
xPos = 18.75f;
zPos = 5f;
@ -350,9 +350,9 @@ public class defenseManagerAI {
float d = (float)Math.sqrt((minorThreatLocation.x-AIStructures[i].centre.x)*(minorThreatLocation.x-AIStructures[i].centre.x) +
(minorThreatLocation.z-AIStructures[i].centre.z)*(minorThreatLocation.z-AIStructures[i].centre.z));
if(AIStructures[i].type == 200 && d <= 2)
if(AIStructures[i].type == 200 && d <= 2.5)
numOfGunTurretNearThreat++;
if(AIStructures[i].type == 199 && d <= 2.4)
if(AIStructures[i].type == 199 && d <= 2.9)
numOfMissileTurretNearThreat++;
}
}
@ -367,15 +367,17 @@ public class defenseManagerAI {
float d = (float)Math.sqrt((majorThreatLocation.x-AIStructures[i].centre.x)*(majorThreatLocation.x-AIStructures[i].centre.x) +
(majorThreatLocation.z-AIStructures[i].centre.z)*(majorThreatLocation.z-AIStructures[i].centre.z));
if(AIStructures[i].type == 200 && d <= 2)
if(AIStructures[i].type == 200 && d <= 2.5)
numOfGunTurretNearThreat++;
if(AIStructures[i].type == 199 && d <= 2.4)
if(AIStructures[i].type == 199 && d <= 2.9)
numOfMissileTurretNearThreat++;
}
}
}
//System.out.println("mainPlayerForceSize: " + mainPlayerForceSize + " " + "numOfGunTurretNearThreat: " +numOfGunTurretNearThreat + " " + "numOfMissileTurretNearThreat: " + numOfMissileTurretNearThreat);
for(int i = 0; i < constructionYards.length; i++){
if(constructionYards[i] != null && constructionYards[i].teamNo != 0 && constructionYards[i].currentHP >0) {
@ -414,7 +416,7 @@ public class defenseManagerAI {
}
//find deploy location of missile turret
if(threatX != 0 && distanceToThreat < 5.15 && (numOfMissileTurretNearThreat < mainPlayerForceSize/6 || !gunTurretAlreadyInQueue)) {
if(threatX != 0 && distanceToThreat < 5.15 && (numOfMissileTurretNearThreat < mainPlayerForceSize/6 )) {
float d = 1.65f; //minimum deploy distance from conyard
if(distanceToThreat > d + missileTurret.attackRange)

View File

@ -19,8 +19,8 @@ public class economyManagerAI {
public vector evadeDirection;
public int numberOfFunctionalRefinery;
public economyManagerAI(baseInfo theBaseInfo){
this.theBaseInfo = theBaseInfo;
public economyManagerAI(){
this.theBaseInfo = mainThread.ec.theBaseInfo;;
evadeDirection = new vector(0,0,0);

View File

@ -21,6 +21,7 @@ public class enemyCommander {
public defenseManagerAI theDefenseManagerAI;
public combatManagerAI theCombatManagerAI;
public microManagementAI theMicroManagementAI;
public harassmentAI theHarassmentAI;
public int difficulty;
@ -33,15 +34,16 @@ public class enemyCommander {
theBaseInfo = new baseInfo();
theBuildingManagerAI = new buildingManagerAI(theBaseInfo);
theEconomyManagerAI = new economyManagerAI(theBaseInfo);
theMapAwarenessAI = new mapAwarenessAI(theBaseInfo, visionMap);
theUnitProductionAI = new unitProductionAI(theBaseInfo);
theBaseExpentionAI = new baseExpensionAI(theBaseInfo);
theScoutingManagerAI = new scoutingManagerAI(theBaseInfo);
theDefenseManagerAI = new defenseManagerAI(theBaseInfo);
theCombatManagerAI = new combatManagerAI(theBaseInfo);
theMicroManagementAI = new microManagementAI(theBaseInfo);
theBuildingManagerAI = new buildingManagerAI();
theEconomyManagerAI = new economyManagerAI();
theMapAwarenessAI = new mapAwarenessAI();
theUnitProductionAI = new unitProductionAI();
theBaseExpentionAI = new baseExpensionAI();
theScoutingManagerAI = new scoutingManagerAI();
theDefenseManagerAI = new defenseManagerAI();
theCombatManagerAI = new combatManagerAI();
theMicroManagementAI = new microManagementAI();
theHarassmentAI = new harassmentAI();
}
@ -119,6 +121,10 @@ public class enemyCommander {
theDefenseManagerAI.processAI();
}
if(mainThread.gameFrame % 30 == 8) {
theHarassmentAI.processAI();
}
//if(mainThread.frameIndex % 5 == 0){
theMicroManagementAI.processAI();
//}

31
enemyAI/harassmentAI.java Normal file
View File

@ -0,0 +1,31 @@
//This AI agent will perform hit and run tactics against the player.
//It will try to harass plahyer's mineral line, and destroy player's building from a distance.
//It will most likely act at the same time when the AI's main attack force is launching an attack,
package enemyAI;
import core.baseInfo;
import core.mainThread;
public class harassmentAI {
public baseInfo theBaseInfo;
public int gameTime;
public harassmentAI(){
this.theBaseInfo = mainThread.ec.theBaseInfo;
}
public void processAI(){
gameTime++;
}
}

View File

@ -79,9 +79,9 @@ public class mapAwarenessAI {
public int[] playerStaticDefenseSize;
public int[] playerStaticDefenseStrength;
public mapAwarenessAI(baseInfo theBaseInfo, boolean[] visionMap){
this.theBaseInfo = theBaseInfo;
this.visionMap = visionMap;
public mapAwarenessAI(){
this.theBaseInfo = mainThread.ec.theBaseInfo;
this.visionMap = mainThread.ec.visionMap;
mapAsset = new solidObject[1024];
playerUnitInMinimap = new solidObject[128];
@ -463,7 +463,7 @@ public class mapAwarenessAI {
playerIsRushingLightTank = mainThread.gameFrame/30 > 300 && mainThread.gameFrame/30 < 600 && ((playerLikelyCanNotProduceHighTierUnits && numberOfStealthTanks_player < 3) || playerHasMostlyLightTanks);
playerHasMostlyHeavyAndStealthTanks = (maxNumberOfStealthTanks_playerInLastFiveMinutes >=2 ) && (float)(numberOfHeavyTanks_player + numberOfStealthTanks_player)/totalNumberOfPlayerUnits > 0.8f;
playerHasMostlyHeavyAndStealthTanks = (maxNumberOfStealthTanks_playerInLastFiveMinutes >=3 ) && (float)(numberOfHeavyTanks_player + numberOfStealthTanks_player)/totalNumberOfPlayerUnits > 0.8f;
//advanced counting of player units
@ -515,7 +515,26 @@ public class mapAwarenessAI {
}
if(playerIsFastExpanding) {
canRushPlayer = true;
//check if there is any static defense around player's natural
boolean staticDefenceNearPlayerExpansion = false;
solidObject[] playerStaticDefence = mainThread.ec.theMapAwarenessAI.playerStaticDefenceInMinimap;
for(int i = 0; i < playerStaticDefence.length; i++) {
if(playerStaticDefence[i] != null && playerStaticDefence[i].currentHP > 0) {
float x1 = playerStaticDefence[i].centre.x;
float z1 = playerStaticDefence[i].centre.z;
float x2 = playerNaturalLocation.x;
float z2 = playerNaturalLocation.z;
if(Math.sqrt((x1-x2)*(x1-x2) + (z1-z2)*(z1-z2)) < 3f) {
staticDefenceNearPlayerExpansion = true;
break;
}
}
}
if(!staticDefenceNearPlayerExpansion)
canRushPlayer = true;
}

View File

@ -28,8 +28,8 @@ public class microManagementAI {
public int numberOfPlayerUnitsOnMinimap;
public microManagementAI(baseInfo theBaseInfo){
this.theBaseInfo = theBaseInfo;
public microManagementAI(){
this.theBaseInfo = mainThread.ec.theBaseInfo;
}
public void processAI(){

View File

@ -32,8 +32,8 @@ public class scoutingManagerAI {
//scout unit consists a sole light tank
public solidObject scout;
public scoutingManagerAI(baseInfo theBaseInfo){
this.theBaseInfo = theBaseInfo;
public scoutingManagerAI(){
this.theBaseInfo = mainThread.ec.theBaseInfo;
patrolNodes = new float[][]{
{16, 30}, {2, 29}, {15, 17}, {16, 14}, {27f, 1}, {30, 16}, {16, 14}, {15, 17}
@ -56,12 +56,12 @@ public class scoutingManagerAI {
public void processAI(){
gameTime++;
if(avoidingIncomingPlayerUnitCooldown > 0)
avoidingIncomingPlayerUnitCooldown--;
boolean scoutIsLightTank = scout != null && scout.type == 0;
if((gameTime%275 > 235 && gameTime%275 < 275 && !scoutIsLightTank) && gameTime < 600 && scoutingMode == patrolling || (scoutIsLightTank && gameTime < 240)){
if((gameTime%275 > 235 && gameTime%275 < 275 && !scoutIsLightTank) && gameTime < 900 && scoutingMode == patrolling || (scoutIsLightTank && gameTime < 240)){
scoutingMode = exploring;
destinationNode = 0;
movementOrderIssued = false;

View File

@ -47,8 +47,8 @@ public class unitProductionAI {
public int frameAI;
public unitProductionAI(baseInfo theBaseInfo){
this.theBaseInfo = theBaseInfo;
public unitProductionAI(){
this.theBaseInfo = mainThread.ec.theBaseInfo;
rallyPoint = new vector(0,0,0);
@ -166,15 +166,18 @@ public class unitProductionAI {
boolean playerHasManyLightTanksButNoHeavyTank = mainThread.ec.theMapAwarenessAI.playerHasManyLightTanksButNoHeavyTank;
boolean playerHasMostlyHeavyAndStealthTanks = mainThread.ec.theMapAwarenessAI.playerHasMostlyHeavyAndStealthTanks;
if((numberOfRocketTanks_AI < 2 && (frameAI > 400 || frameAI > 170 && frameAI < 240 && mainThread.ec.theMapAwarenessAI.numberOfConstructionYard_player > 0) && !playerHasMostlyLightTanks) || numberOfRocketTanks_AI < numberOfPlayerGunTurrets + numberOfPlayerMissileTurrets*1.5 || (gameData.getRandom() > 925 && !playerHasMostlyLightTanks)){
boolean b1 = (numberOfRocketTanks_AI < 2 && (frameAI > 400 || frameAI > 170 && frameAI < 240 && mainThread.ec.theMapAwarenessAI.numberOfConstructionYard_player > 0) && !playerHasMostlyLightTanks);
boolean b2 = (numberOfRocketTanks_AI < numberOfPlayerGunTurrets + numberOfPlayerMissileTurrets*1.5);
if( b1 || b2){
currentProductionOrder = produceRocketTank;
}else if(theBaseInfo.canBuildHeavyTank &&
playerHasMostlyHeavyAndStealthTanks ||
(!playerHasManyLightTanksButNoHeavyTank
(playerHasMostlyHeavyAndStealthTanks ||
!playerHasManyLightTanksButNoHeavyTank
&& !playerHasMostlyLightTanks
&& !(numberOfHeavyTanks_player == 0 && maxNumberOfStealthTanks_playerInLastFiveMinutes < 3 && mainThread.gameFrame/30 > 600)
&& !(playerHasMostlyHeavyTanks && numberOfStealthTanks_player < numberOfHeavyTanks_AI*2)
&& (playIsRushingHighTierUnits || gameData.getRandom() > 985 || maxNumberOfStealthTanks_playerInLastFiveMinutes*4 > numberOfHeavyTanks_AI || (mainThread.gameFrame/30 > 400 && mainThread.gameFrame/30 < 600 && numberOfPlayerGunTurrets + numberOfPlayerMissileTurrets+ numberOfLightTanks_player + numberOfRocketTanks_player + numberOfHeavyTanks_player*5 < 5)))){
&& (playIsRushingHighTierUnits || maxNumberOfStealthTanks_playerInLastFiveMinutes*4 > numberOfHeavyTanks_AI || (mainThread.gameFrame/30 > 400 && mainThread.gameFrame/30 < 600 && numberOfPlayerGunTurrets + numberOfPlayerMissileTurrets+ numberOfLightTanks_player + numberOfRocketTanks_player + numberOfHeavyTanks_player*5 < 5)))){
currentProductionOrder = produceHeavyTank;
}else if(theBaseInfo.canBuildStealthTank && (playerHasMostlyLightTanks || playerLikelyCanNotProduceHighTierUnits || playerDoesntHaveMassHeavyTanks) && !playerHasMostlyHeavyTanks){
currentProductionOrder = produceStealthTank;
@ -182,7 +185,7 @@ public class unitProductionAI {
currentProductionOrder = produceLightTank;
}
//make decision on what tech to research
if(mainThread.ec.theBuildingManagerAI.theBaseInfo.numberOfCommunicationCenter > 0) {
if(mainThread.ec.theDefenseManagerAI.needMissileTurret || theBaseInfo.currentCredit > 1500) {

View File

@ -35,6 +35,7 @@ public class lightPole extends solidObject{
//uncontrollable unit, but act as a small sized static collidable agent
ID = -1;
type = 100;
teamNo = -1;
this.angle = angle;