This commit is contained in:
Pan 2019-05-12 05:57:59 +12:00
parent b94af05a04
commit 889c30d603
12 changed files with 234 additions and 42 deletions

View File

@ -106,12 +106,12 @@ public class AssetManager {
goldMines = new goldMine[16];
goldMines[0] = new goldMine(2f,-0.515f, 1.25f, 45000);
goldMines[1] = new goldMine(9.5f,-0.515f, 5.5f, 45000);
goldMines[2] = new goldMine(2f,-0.515f, 28.25f, 55000);
goldMines[3] = new goldMine(26f,-0.515f, 3.5f, 55000);
goldMines[2] = new goldMine(2f,-0.515f, 28.25f, 60000);
goldMines[3] = new goldMine(26f,-0.515f, 3.5f, 60000);
goldMines[4] = new goldMine(29.75f,-0.515f, 30f, 45000);
goldMines[5] = new goldMine(22.5f,-0.515f, 25.5f, 45000);
goldMines[6] = new goldMine(15.75f,-0.515f, 18f, 55000);
goldMines[7] = new goldMine(16.25f,-0.515f, 12.25f, 55000);
goldMines[6] = new goldMine(15.75f,-0.515f, 18f, 60000);
goldMines[7] = new goldMine(16.25f,-0.515f, 12.25f, 60000);
//create trees from bitmap
@ -242,8 +242,8 @@ public class AssetManager {
for(int i = 0; i < 10; i ++){
for(int j = 0; j < 6; j++){
//heavyTank l = new heavyTank(new vector(i*0.25f+ 1.125f,-0.3f, 17.375f - 0.25f*j), 90, 0);
//addHeavyTank(l);
//harvester l = new harvester(new vector(i*0.25f+ 1.125f,-0.3f, 17.375f - 0.25f*j), 90, 0);
//addHarvester(l);
//l.hasMultiShotUpgrade = true;
//stealthTank l = new stealthTank(new vector(i*0.25f + 1.125f,-0.3f, 0.5f + 18.625f + j*0.25f), 90, 0);

View File

@ -59,6 +59,7 @@ public class mainThread extends JFrame implements KeyListener, ActionListener, M
public static final int endGameMenu = 3;
public static String timeString;
public static boolean fogOfWarDisabled;
public mainThread(){
setTitle("Battle Tank 3");
@ -506,7 +507,7 @@ public class mainThread extends JFrame implements KeyListener, ActionListener, M
sleepTime = 0;
/*while(System.currentTimeMillis()-lastDraw<frameInterval){
while(System.currentTimeMillis()-lastDraw<frameInterval){
try {
Thread.sleep(1);
@ -515,7 +516,7 @@ public class mainThread extends JFrame implements KeyListener, ActionListener, M
// TODO Auto-generated catch block
e1.printStackTrace();
}
}*/
}

View File

@ -82,7 +82,7 @@ public class postProcessingThread implements Runnable{
public static String buttonAction;
public static String timeString;
public static boolean fogOfWarDisabled;
//A pool of vectors which will be used for vector arithmetic
public static vector
@ -957,6 +957,7 @@ public class postProcessingThread implements Runnable{
gameEnded = mainThread.gameEnded;
timeString = mainThread.timeString;
fogOfWarDisabled = mainThread.fogOfWarDisabled;
currentScreen = mainThread.screen;
currentZbuffer = mainThread.zBuffer;

View File

@ -285,10 +285,11 @@ public class combatManagerAI {
if(troopsControlledByCombatAI[i] != null && troopsControlledByCombatAI[i].currentHP > 0){
if(Math.abs(troopsControlledByCombatAI[i].destinationX - myRallyPointX) > 0.25 || Math.abs(troopsControlledByCombatAI[i].destinationY - myRallyPointZ) > 0.25) {
troopsControlledByCombatAI[i].attackMoveTo(myRallyPointX, myRallyPointZ);
troopsControlledByCombatAI[i].currentCommand = solidObject.attackMove;
troopsControlledByCombatAI[i].secondaryCommand = solidObject.attackMove;
if(troopsControlledByCombatAI[i].secondaryDestinationX != myRallyPointX || troopsControlledByCombatAI[i].secondaryDestinationY != myRallyPointZ) {
troopsControlledByCombatAI[i].attackMoveTo(myRallyPointX, myRallyPointZ);
troopsControlledByCombatAI[i].currentCommand = solidObject.attackMove;
troopsControlledByCombatAI[i].secondaryCommand = solidObject.attackMove;
}
}
}
}
@ -741,18 +742,16 @@ public class combatManagerAI {
m3+=0.5f;
if(techCenter.stealthTankResearched_enemy == true && mainThread.ec.theMapAwarenessAI.playerHasMostlyLightTanks){
if(techCenter.stealthTankResearched_enemy == true && mainThread.ec.theMapAwarenessAI.playerArmyCanBeCounteredWithStealthTanks){
m3+=0.5f;
}
float m1 = 1;
if(mainThread.ec.theMapAwarenessAI.playerHasMostlyHeavyTanks){
if(mainThread.ec.theMapAwarenessAI.playerArmyCanBeCounteredWithLightTanks){
m1 = 1.2f;
if(techCenter.lightTankResearched_enemy == true && numberOfStealthTanks_player < 5){
if(techCenter.lightTankResearched_enemy == true){
m1=1.75f;
}

View File

@ -56,7 +56,6 @@ public class defenseManagerAI {
minorThreatLocation = new vector(0,0,0);
majorThreatLocation = new vector(0,0,0);
majorThreatCooldown = 20;
gunTurretDeployLocation = new vector(0,0,0);
missileTurretDeployLocation = new vector(0,0,0);
@ -215,13 +214,13 @@ public class defenseManagerAI {
//if the size of player unit cluster is bigger or equal to 5 then check if the threat is a big one
if(playerForceIsNearBase(mainPlayerForceLocation)) {
giveBackControlOfDefendersToCombatAI();
majorThreatCooldown = 20;
majorThreatCooldown = 30;
majorThreatLocation.set(mainPlayerForceLocation);
}else {
float d = playerForceIsMovingTwoardsBase(mainPlayerForceLocation, mainPlayerForceDirection);
if(d != -1) {
giveBackControlOfDefendersToCombatAI();
majorThreatCooldown = 20;
majorThreatCooldown = 30;
majorThreatLocation.set(mainPlayerForceLocation);
majorThreatLocation.add(mainPlayerForceDirection, d);
}
@ -245,7 +244,7 @@ public class defenseManagerAI {
if(d < 4) {
playerBuildingNearBase = true;
majorThreatCooldown = 20;
majorThreatCooldown = 30;
majorThreatLocation.set(playerStructures[i].centre);
break;

View File

@ -65,7 +65,7 @@ public class enemyCommander {
thinkHardLikeHumanPlayer();
drawVisionMap();
//drawVisionMap();
//reset tempBitmap;
for(int i = 0 ;i < tempBitmap.length; i++){

View File

@ -5,7 +5,9 @@
package enemyAI;
import core.baseInfo;
import core.gameData;
import core.mainThread;
import core.vector;
import entity.rocketTank;
import entity.solidObject;
import entity.stealthTank;
@ -26,21 +28,23 @@ public class harassmentAI {
public final int retreating = 3;
public stealthTank[] stealthTanksControlledByCombatAI;
public rocketTank[] rocketTanksControlledByCombatAI;
public vector targetLocation, gatherLocation, squadCenter, harassDirection;
public int harassTimer;
public harassmentAI(){
this.theBaseInfo = mainThread.ec.theBaseInfo;
squad = new rocketTank[3];
status = gathering;
targetLocation = new vector(0,0,0);
gatherLocation = new vector(0,0,0);
squadCenter = new vector(0,0,0);
harassDirection = new vector(0,0,0);
}
public void processAI(){
miniFrameAI++;
frameAI = mainThread.ec.frameAI;
if(miniFrameAI%30 == 29) {
System.out.println(frameAI + " " + mainThread.ec.theUnitProductionAI.numberOfRocketTanksControlledByCombatAI);
}
//only activate this AI after 660 game seconds (about 9 minutes in real time)
if(frameAI < 660)
@ -49,10 +53,13 @@ public class harassmentAI {
stealthTanksControlledByCombatAI = mainThread.ec.theUnitProductionAI.stealthTanksControlledByCombatAI;
rocketTanksControlledByCombatAI = mainThread.ec.theUnitProductionAI.rocketTanksControlledByCombatAI;
if(status == gathering) {
if(scout == null || scout.currentHP <=0) {
for(int i = 0; i < stealthTanksControlledByCombatAI.length; i++) {
for(int i = 0; i < stealthTanksControlledByCombatAI.length; i++) {
if(stealthTanksControlledByCombatAI[i] != null && stealthTanksControlledByCombatAI[i].currentHP == stealthTank.maxHP && stealthTanksControlledByCombatAI[i].attackStatus != solidObject.isAttacking) {
if(hasRoomToMove(stealthTanksControlledByCombatAI[i])) {
scout = stealthTanksControlledByCombatAI[i];
@ -84,7 +91,7 @@ public class harassmentAI {
}
int numberOfSquad = 0;
for(int i = 0; i < squad.length; i++) {
if(squad[i] != null) {
if(squad[i] != null && squad[i].currentHP > 0) {
squad[i].attackMoveTo(mainThread.ec.theUnitProductionAI.rallyPoint.x - 1,mainThread.ec.theUnitProductionAI.rallyPoint.z);
squad[i].currentCommand = solidObject.attackMove;
squad[i].secondaryCommand = solidObject.attackMove;
@ -92,15 +99,185 @@ public class harassmentAI {
}
}
if(numberOfSquad == squad.length && scout !=null) {
if(numberOfSquad == squad.length && scout !=null && scout.currentHP > 0) {
status = positioning;
targetLocation.set(0,0,0);
//find the location of the target location and gather location
if(gameData.getRandom() >= 512) {
if(playerBaseIsAround(mainThread.theAssetManager.goldMines[2].centre)) {
targetLocation = mainThread.theAssetManager.goldMines[2].centre;
gatherLocation.set(15, 0, 28);
}else if(playerBaseIsAround(mainThread.theAssetManager.goldMines[3].centre)) {
targetLocation = mainThread.theAssetManager.goldMines[3].centre;
gatherLocation.set(28.5f, 0, 15);
}
}else {
if(playerBaseIsAround(mainThread.theAssetManager.goldMines[3].centre)) {
targetLocation = mainThread.theAssetManager.goldMines[3].centre;
gatherLocation.set(28.5f, 0, 15);
}else if(playerBaseIsAround(mainThread.theAssetManager.goldMines[2].centre)) {
targetLocation = mainThread.theAssetManager.goldMines[2].centre;
gatherLocation.set(15, 0, 28);
}
}
if(targetLocation.x == 0 && targetLocation.z == 0) {
targetLocation.set(1.5f, 0, 1.5f);
if(gameData.getRandom() >= 512) {
gatherLocation.set(1.5f, 0, 15);
}else {
gatherLocation.set(15, 0, 1.5f);
}
}
}
}else if(status == positioning) {
//move squad and scout to gathering point
int numberOfSquad = 0;
for(int i = 0; i < squad.length; i++) {
if(squad[i] != null && squad[i].currentHP > 0 ) {
numberOfSquad++;
if(squad[i].secondaryDestinationX != gatherLocation.x || squad[i].secondaryDestinationY != gatherLocation.z || (squad[i].movement.x == 0 && squad[i].movement.z == 0 && squad[i].currentMovementStatus == solidObject.freeToMove)){
squad[i].attackMoveTo(gatherLocation.x,gatherLocation.z);
squad[i].currentCommand = solidObject.attackMove;
squad[i].secondaryCommand = solidObject.attackMove;
}
}
}
if(scout != null) {
scout.moveTo(gatherLocation.x,gatherLocation.z);
scout.currentCommand = solidObject.move;
scout.secondaryCommand = solidObject.StandBy;
}
boolean scoutInPosition = true;
float x = scout.centre.x;
float z = scout.centre.z;
double d = Math.sqrt((x - gatherLocation.x)*(x - gatherLocation.x) + (z - gatherLocation.z)*(z - gatherLocation.z));
if(d > 0.75)
scoutInPosition = false;
boolean squadInPosition = true;
for(int i = 0; i < squad.length; i++) {
x = squad[i].centre.x;
z = squad[i].centre.z;
d = Math.sqrt((x - gatherLocation.x)*(x - gatherLocation.x) + (z - gatherLocation.z)*(z - gatherLocation.z));
if(d > 1) {
squadInPosition = false;
break;
}
}
if(scoutInPosition && squadInPosition) {
status = harasing;
harassTimer = 0;
}
if(numberOfSquad < squad.length || scout == null || scout.currentHP <=0) {
status = gathering;
}
}else if(status == harasing) {
harassTimer++;
//move squad towards target base
squadCenter.reset();
int numberOfSquad = 0;
for(int i = 0; i < squad.length; i++) {
if(squad[i] != null && squad[i].currentHP > 0) {
if(squad[i].secondaryDestinationX != targetLocation.x || squad[i].secondaryDestinationY != targetLocation.z) {
if(harassTimer > 200) { //delay the squad moment a little bit, make sure scout stays ahead
squad[i].attackMoveTo(targetLocation.x,targetLocation.z);
squad[i].currentCommand = solidObject.attackMove;
squad[i].secondaryCommand = solidObject.attackMove;
}
}
squadCenter.add(squad[i].centre);
numberOfSquad++;
}
}
if(numberOfSquad > 0) {
squadCenter.x/=numberOfSquad;
squadCenter.z/=numberOfSquad;
harassDirection.set(targetLocation.x,0,targetLocation.z);
harassDirection.subtract(squadCenter);
harassDirection.unit();
if(scout != null) {
scout.moveTo(squadCenter.x + harassDirection.x*1.75f, squadCenter.z + harassDirection.z*1.75f);
scout.currentCommand = solidObject.move;
scout.secondaryCommand = solidObject.StandBy;
}
}
//attack the first building within range.
solidObject[] playerStructures = mainThread.ec.theMapAwarenessAI.playerStructures;
for(int i = 0; i < playerStructures.length; i++) {
if(playerStructures[i] != null && playerStructures[i].currentHP >0) {
float x = playerStructures[i].centre.x;
float z = playerStructures[i].centre.z;
double d = Math.sqrt((squadCenter.x-x)*(squadCenter.x-x) + (squadCenter.z-z)*(squadCenter.z-z));
if(d < 2.8) {
for(int j = 0; j < squad.length; j++) {
if(squad[j] != null && squad[j].currentHP > 0) {
double d1 = Math.sqrt((squad[j].centre.x-x)*(squad[j].centre.x-x) + (squad[j].centre.z-z)*(squad[j].centre.z-z));
if(d1 < 2.86) {
squad[j].attack(playerStructures[i]);
squad[j].currentCommand = solidObject.attackCautiously;
}
}
}
break;
}
}
}
//if the target location is clear of player base, then chance status to gathering
double distance = Math.sqrt((squadCenter.x-targetLocation.x)*(squadCenter.x-targetLocation.x) + (squadCenter.z-targetLocation.z)*(squadCenter.z-targetLocation.z));
if(distance < 1) {
if(!playerBaseIsAround(targetLocation)) {
status = gathering;
}
}
//if all squad members are dead, change status to gathering
if(numberOfSquad == 0) {
status = gathering;
}
}
}
public boolean playerBaseIsAround(vector v) {
solidObject[] playerStructures = mainThread.ec.theMapAwarenessAI.playerStructures;
for(int i = 0; i < playerStructures.length; i++) {
if(playerStructures[i] != null && playerStructures[i].currentHP >0) {
float x = playerStructures[i].centre.x;
float z = playerStructures[i].centre.z;
double d = Math.sqrt((v.x-x)*(v.x-x) + (v.z-z)*(v.z-z));
if(d < 3.5) {
return true;
}
}
}
return false;
}
public boolean hasRoomToMove(solidObject o) {
float x = o.centre.x;
float z = o.centre.x;

View File

@ -49,6 +49,7 @@ public class mapAwarenessAI {
public boolean playerLikelyCanNotProduceHighTierUnits;
public boolean playerDoesntHaveMassHeavyTanks;
public boolean playerArmyCanBeCounteredWithLightTanks;
public boolean playerArmyCanBeCounteredWithStealthTanks;
public boolean playerIsRushingLightTank;
public boolean playerHasManyLightTanksButNoHeavyTank;
public boolean playerHasMostlyHeavyAndStealthTanks;
@ -474,9 +475,12 @@ public class mapAwarenessAI {
if(frameAI < 600)
playerArmyCanBeCounteredWithLightTanks = false;
else {
playerArmyCanBeCounteredWithLightTanks = maxNumberOfStealthTanks_playerInLastFiveMinutes < 6 && maxNumberOfStealthTanks_playerInLastFiveMinutes/(totalNumberOfPlayerUnits + 1) < 0.2f;
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;
@ -760,7 +764,11 @@ public class mapAwarenessAI {
}
}
mainPlayerForceDirection.unit();
if(mainPlayerForceDirection.getLength() < 0.001) {
mainPlayerForceDirection.reset();
}else {
mainPlayerForceDirection.unit();
}
//check if player force is near any of AI's base
playerForceNearBase = false;

View File

@ -165,6 +165,7 @@ public class unitProductionAI {
boolean playerHasMostlyHeavyAndStealthTanks = mainThread.ec.theMapAwarenessAI.playerHasMostlyHeavyAndStealthTanks;
boolean playerHasMostlyLightAndStealthTanks = mainThread.ec.theMapAwarenessAI.playerHasMostlyLightAndStealthTanks;
boolean playerArmyCanBeCounteredWithLightTanks = mainThread.ec.theMapAwarenessAI.playerArmyCanBeCounteredWithLightTanks;
boolean playerArmyCanBeCounteredWithStealthTanks = mainThread.ec.theMapAwarenessAI.playerArmyCanBeCounteredWithStealthTanks;
int timeToBuildHeavyTank = 400;
int timeToBuildStealthTank = 200;
@ -178,15 +179,15 @@ public class unitProductionAI {
boolean b2 = (numberOfRocketTanks_AI < numberOfPlayerGunTurrets + numberOfPlayerMissileTurrets*1.5);
if( b1 || b2){
currentProductionOrder = produceRocketTank;
}else if(theBaseInfo.canBuildHeavyTank && !playerHasMostlyHeavyTanks && !playerHasMostlyLightTanks && !playerHasMostlyLightAndStealthTanks && !playerArmyCanBeCounteredWithLightTanks &&
}else if(theBaseInfo.canBuildHeavyTank && numberOfHeavyTanksControlledByCombatAI < 20 && !(numberOfStealthTanksControlledByCombatAI < 1) && !playerHasMostlyHeavyTanks && !playerHasMostlyLightTanks && !playerHasMostlyLightAndStealthTanks && !playerArmyCanBeCounteredWithLightTanks && !playerArmyCanBeCounteredWithStealthTanks &&
(playerHasMostlyHeavyAndStealthTanks || (frameAI > timeToBuildHeavyTank && numberOfHeavyTanks_AI < 3) ||
!playerHasManyLightTanksButNoHeavyTank
&& !(numberOfHeavyTanks_player == 0 && maxNumberOfStealthTanks_playerInLastFiveMinutes < 3 && frameAI > 600)
&& !(playerHasMostlyHeavyTanks && numberOfStealthTanks_player < numberOfHeavyTanks_AI*2)
&& (playIsRushingHighTierUnits || maxNumberOfStealthTanks_playerInLastFiveMinutes*4 > numberOfHeavyTanks_AI))){
currentProductionOrder = produceHeavyTank;
}else if(theBaseInfo.canBuildStealthTank && playerDoesntHaveMassHeavyTanks && !playerHasMostlyHeavyTanks && !playerArmyCanBeCounteredWithLightTanks && !(numberOfStealthTanksControlledByCombatAI >= 8 && frameAI < 600) && !(numberOfStealthTanksControlledByCombatAI >= 16 && frameAI > 600)
&& (playerHasMostlyLightTanks || playerLikelyCanNotProduceHighTierUnits || playerDoesntHaveMassHeavyTanks || playerHasMostlyLightAndStealthTanks) && !playerHasMostlyHeavyTanks && (frameAI > timeToBuildStealthTank || numberOfLightTanks_player > 8)){
}else if(theBaseInfo.canBuildStealthTank && ((numberOfStealthTanksControlledByCombatAI < 1) || (playerDoesntHaveMassHeavyTanks && !playerHasMostlyHeavyTanks && !playerArmyCanBeCounteredWithLightTanks && !(numberOfStealthTanksControlledByCombatAI >= 8 && frameAI < 600) && !(numberOfStealthTanksControlledByCombatAI >= 16 && frameAI > 600)
&& (playerHasMostlyLightTanks || playerLikelyCanNotProduceHighTierUnits || playerDoesntHaveMassHeavyTanks || playerHasMostlyLightAndStealthTanks) && !playerHasMostlyHeavyTanks && (frameAI > timeToBuildStealthTank || numberOfLightTanks_player > 8)))){
currentProductionOrder = produceStealthTank;
}else{
currentProductionOrder = produceLightTank;

View File

@ -271,6 +271,10 @@ public class rocketTank extends solidObject{
//update and draw model
public void update(){
if(isSelected) {
System.out.println(currentCommand + " " + secondaryCommand);
}
//check if tank has been destroyed
if(currentHP <= 0){

View File

@ -426,8 +426,9 @@ public class stealthTank extends solidObject{
if(isCloaked){
if(teamNo != 0){
//if(currentCloakingStatus < 127)
// currentCloakingStatus+=3;
if(!mainThread.fogOfWarDisabled)
if(currentCloakingStatus < 127)
currentCloakingStatus+=3;
}else{
if(currentCloakingStatus < 70){
currentCloakingStatus+=3;
@ -555,10 +556,10 @@ public class stealthTank extends solidObject{
}
//check if the tank object is visible in mini map
visible_minimap = theAssetManager.minimapBitmap[boundary2D.x1/16 + (127 - (boundary2D.y1-1)/16)*128];
visible_minimap = theAssetManager.minimapBitmap[boundary2D.x1/16 + (127 - (boundary2D.y1-1)/16)*128] || mainThread.fogOfWarDisabled;
if(teamNo == 0 || attackStatus == isAttacking || exposedCountDown > 0 || visible_minimap){
if(!(isCloaked && teamNo!=0)){
if(!(isCloaked && teamNo!=0) || mainThread.fogOfWarDisabled){
tempInt = theAssetManager.unitsForMiniMap[theAssetManager.unitsForMiniMapCount];
tempInt[0] = teamNo + (this.type << 8);
tempInt[1] = boundary2D.x1/16;

View File

@ -50,8 +50,9 @@ public class MiniMap {
drawBackground(screen, minimapBitmap);
//remove fog of war for testing
for(int i = 0; i < minimapBitmap.length; i++)
minimapBitmap[i] = true;
if(postProcessingThread.fogOfWarDisabled)
for(int i = 0; i < minimapBitmap.length; i++)
minimapBitmap[i] = true;
//draw unit positions on minimap
drawUnit(screen, minimapBitmap, unitsForMiniMap, unitsForMiniMapCount);