diff --git a/core/mainThread.java b/core/mainThread.java index 318912e..9359e48 100644 --- a/core/mainThread.java +++ b/core/mainThread.java @@ -77,16 +77,7 @@ public class mainThread extends JFrame implements KeyListener, ActionListener, M setLocation(dim.width/2-this.getSize().width/2, dim.height/2-this.getSize().height/2); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - //hide mouse cursor - // Transparent 16 x 16 pixel cursor image. - BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB); - - // Create a new blank cursor. - Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor( - cursorImg, new Point(0, 0), "blank cursor"); - - // Set the blank cursor to the JFrame. - this.getContentPane().setCursor(blankCursor); + //create screen buffer @@ -191,6 +182,17 @@ public class mainThread extends JFrame implements KeyListener, ActionListener, M theGameCursor = new gameCursor(); theGameCursor.init(); + + //hide mouse cursor + // Transparent 16 x 16 pixel cursor image. + BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB); + + // Create a new blank cursor. + Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor( + cursorImg, new Point(0, 0), "blank cursor"); + + // Set the blank cursor to the JFrame. + this.getContentPane().setCursor(blankCursor); } frameIndex++; diff --git a/core/playerCommander.java b/core/playerCommander.java index 639151b..69f4fd2 100644 --- a/core/playerCommander.java +++ b/core/playerCommander.java @@ -47,6 +47,15 @@ public class playerCommander { public baseInfo theBaseInfo; + public boolean mouseOverSelectableUnit; + public int mouseOverUnitType; + public int mouseOverUnitTeam; + public boolean mouseOverUnitIsSelected; + public boolean hasConVehicleSelected; + public boolean hasHarvesterSelected; + public boolean hasTroopsSelected; + public boolean hasTowerSelected; + public void init(){ selectedUnits = new solidObject[100]; groups = new solidObject[5][100]; @@ -382,7 +391,16 @@ public class playerCommander { } if(holdKeyPressed){ - holdAllSelectedUnit(); + + if(attackKeyPressed) { + + attackKeyPressed = false; + + }else { + + attackKeyPressed = false; + holdAllSelectedUnit(); + } } if(toggleConyard) { @@ -497,11 +515,32 @@ public class playerCommander { area.setBounds(xPos, yPos, 100, 100); areaSmall.setBounds(xPos_small, yPos_small, 60,60); addMouseHoverUnitToDisplayInfo(area, areaSmall); - } theSideBarManager.update(); + hasConVehicleSelected = false; + hasHarvesterSelected = false; + hasTroopsSelected = false; + hasTowerSelected = false; + + for(int i = 0; i < selectedUnits.length; i++){ + if(selectedUnits[i] != null && selectedUnits[i].teamNo == 0 && selectedUnits[i].currentHP > 0){ + if(selectedUnits[i].type == 0 || selectedUnits[i].type == 1 || selectedUnits[i].type == 6 || selectedUnits[i].type == 7) { + hasTroopsSelected = true; + }else if(selectedUnits[i].type == 2) { + hasHarvesterSelected = true; + }else if(selectedUnits[i].type == 3) { + hasConVehicleSelected = true; + }else if(selectedUnits[i].type == 200 || selectedUnits[i].type == 199) { + hasTowerSelected = true; + } + + } + } + + + leftMouseButtonPressed = false; rightMouseButtonPressed = false; leftMouseButtonReleased = false; @@ -605,6 +644,8 @@ public class playerCommander { public void addMouseHoverUnitToDisplayInfo(Rectangle unitArea, Rectangle unitAreaSmall){ solidObject theSelected = null; + mouseOverSelectableUnit = false; + mouseOverUnitIsSelected = false; for(int i = 0; i < theAssetManager.visibleUnitCount; i++){ if(unitArea.contains(theAssetManager.visibleUnit[i].tempCentre.screenX, theAssetManager.visibleUnit[i].tempCentre.screenY)){ if((theAssetManager.visibleUnit[i].type < 100 || theAssetManager.visibleUnit[i].type >= 199) && !unitAreaSmall.contains(theAssetManager.visibleUnit[i].tempCentre.screenX, theAssetManager.visibleUnit[i].tempCentre.screenY)) @@ -619,7 +660,17 @@ public class playerCommander { } } - if(theSelected != null && !theSelected.isSelected && theSelected.isSelectable){ + if(theSelected != null && theSelected.isSelectable && !cursorIsInMiniMap() && !cursorIsInSideBar()) { + mouseOverSelectableUnit = true; + mouseOverUnitType = theSelected.type; + mouseOverUnitTeam = theSelected.teamNo; + if(theSelected.isSelected) { + mouseOverUnitIsSelected = true; + } + + } + + if(theSelected != null && !theSelected.isSelected && theSelected.isSelectable && !cursorIsInMiniMap() && !cursorIsInSideBar()){ mainThread.theAssetManager.selectedUnitsInfo[99][0] = theSelected.level << 16 | theSelected.groupNo << 8 | theSelected.type; mainThread.theAssetManager.selectedUnitsInfo[99][1] = (int)theSelected.tempCentre.screenX; mainThread.theAssetManager.selectedUnitsInfo[99][2] = (int)theSelected.tempCentre.screenY; diff --git a/enemyAI/combatManagerAI.java b/enemyAI/combatManagerAI.java index 9f830b7..f013e34 100644 --- a/enemyAI/combatManagerAI.java +++ b/enemyAI/combatManagerAI.java @@ -384,9 +384,12 @@ public class combatManagerAI { //check if the troops is near a concentration of player's static defense. //If true, then check if AI has enough troops to deal with the static defense. staticDefenseAhead = false; + int staticDefenseThreshold = 0; + if(frameAI > 600 && mainThread.ec.theUnitProductionAI.numberOfUnitInCombatRadius > 15) + staticDefenseThreshold = 4; double distanceToTower = 999; for(int i = 0; i < mainThread.ec.theMapAwarenessAI.playerStaticDefenseLocations.length; i++) { - if(mainThread.ec.theMapAwarenessAI.playerStaticDefenseSize[i] > 0) { + if(mainThread.ec.theMapAwarenessAI.playerStaticDefenseSize[i] > staticDefenseThreshold) { float xPos = mainThread.ec.theMapAwarenessAI.playerStaticDefenseLocations[i].x; float zPos = mainThread.ec.theMapAwarenessAI.playerStaticDefenseLocations[i].z; diff --git a/gui/gameCursor.java b/gui/gameCursor.java index 9e038cc..838f8fa 100644 --- a/gui/gameCursor.java +++ b/gui/gameCursor.java @@ -11,6 +11,7 @@ import core.mainThread; public class gameCursor { public int[][] arrowIcons; + public int[][] smallArrowIcons; public int[] cursorIcon; public int[] screen; @@ -23,6 +24,11 @@ public class gameCursor { loadTexture(folder + "arrow"+i+".png", arrowIcons[i], 24,24); } + smallArrowIcons = new int[4][20*20]; + for(int i = 0; i < 4; i++) { + loadTexture(folder + "smallArrow"+i+".png", smallArrowIcons[i], 20,20); + } + cursorIcon = new int[24*24]; loadTexture(folder + "cursor.png", cursorIcon, 24,24); } @@ -32,6 +38,17 @@ public class gameCursor { int mouseX = inputHandler.mouse_x; int mouseY = inputHandler.mouse_y; + boolean mouseOverSelectableUnit = mainThread.pc.mouseOverSelectableUnit; + int mouseOverUnitType = mainThread.pc.mouseOverUnitType; + int mouseOverUnitTeam = mainThread.pc.mouseOverUnitTeam; + boolean mouseOverUnitIsSelected = mainThread.pc.mouseOverUnitIsSelected; + boolean hasConVehicleSelected = mainThread.pc.hasConVehicleSelected; + boolean hasHarvesterSelected = mainThread.pc.hasHarvesterSelected; + boolean hasTroopsSelected = mainThread.pc.hasTroopsSelected; + boolean hasTowerSelected = mainThread.pc.hasTowerSelected; + boolean attackKeyPressed = mainThread.pc.attackKeyPressed; + boolean cursorIsInMiniMap = mainThread.pc.cursorIsInMiniMap(); + boolean cursorIsInSideBar = mainThread.pc.cursorIsInSideBar(); if(!mainThread.gamePaused && mainThread.gameStarted) { @@ -101,8 +118,40 @@ public class gameCursor { cursorY = 491; drawIcon(arrowIcons[5], cursorX, cursorY); + }else if(mouseOverSelectableUnit && !cursorIsInMiniMap && !cursorIsInSideBar){ + if(!hasHarvesterSelected && !hasTroopsSelected && !hasTowerSelected) { + //if(!mouseOverUnitIsSelected) + // drawSelectionIcon(mouseX, mouseY); + //else + drawIcon(cursorIcon, mouseX, mouseY); + }else if(mouseOverUnitTeam == 0 && !(attackKeyPressed && (hasTroopsSelected || hasTowerSelected)) && !(hasHarvesterSelected && mouseOverUnitType == 102)) { + //if(!mouseOverUnitIsSelected) + // drawSelectionIcon(mouseX, mouseY); + //else + drawIcon(cursorIcon, mouseX, mouseY); + }else if(mouseOverUnitType == 103 && !hasHarvesterSelected && !((hasTroopsSelected || hasTowerSelected) && attackKeyPressed)) { + //if(!mouseOverUnitIsSelected) + // drawSelectionIcon(mouseX, mouseY); + //else + drawIcon(cursorIcon, mouseX, mouseY); + }else if((hasTroopsSelected || hasTowerSelected) && attackKeyPressed) { + drawActionIcon(mouseX, mouseY, 1); + }else if(hasHarvesterSelected && (mouseOverUnitType == 102 || mouseOverUnitType == 103)) { + drawActionIcon(mouseX, mouseY, 2); + }else { + drawIcon(cursorIcon, mouseX, mouseY); + } + + }else if(!mouseOverSelectableUnit && !cursorIsInMiniMap && !cursorIsInSideBar){ + if(!hasHarvesterSelected && !hasTroopsSelected && !hasTowerSelected && !hasConVehicleSelected) { + drawIcon(cursorIcon, mouseX, mouseY); + }else if(((hasHarvesterSelected || hasConVehicleSelected) && !(hasTroopsSelected)) || (hasTroopsSelected && !attackKeyPressed) ) { + //drawActionIcon(mouseX, mouseY, 0); + drawIcon(cursorIcon, mouseX, mouseY); + }else if(hasTroopsSelected && attackKeyPressed) { + drawActionIcon(mouseX, mouseY, 1); + } }else { - //draw default icon drawIcon(cursorIcon, mouseX, mouseY); @@ -132,7 +181,138 @@ public class gameCursor { } } + public void drawActionIcon(int xPos, int yPos, int type) { + xPos-=10; + yPos-=10; + + int r = (7 - (mainThread.gameFrame%21)/3) + 9; + + int index = 0; + int color = 0; + int blue = 0; + int red = 0; + int arrowColor = 0; + + + if(type == 0) + arrowColor = 34 << 16 | 200 << 8 | 76; + if(type == 1) + arrowColor = 240 << 16 | 76 << 8 | 34; + if(type == 2) + arrowColor = 255 << 16 | 242 << 8 | 0; + + //draw up left arrow + int start = xPos - r + (yPos-r)*768; + for(int i = 0; i < 20; i++) { + for(int j = 0; j < 20; j++) { + index = start + j + i*768; + if(index > 0 && index < 393216) { + color = smallArrowIcons[2][j+i*20]; + + blue = color&0xff; + red = (color&0xff0000) >> 16; + if(red < 100 && blue > 100) + continue; + + if(pixelInsideSideArea(index)) + continue; + + if(red > 200) + color = arrowColor; + screen[index] = color; + } + } + } + + //draw up right arrow + start = xPos + r + (yPos-r)*768; + for(int i = 0; i < 20; i++) { + for(int j = 0; j < 20; j++) { + index = start + j + i*768; + if(index > 0 && index < 393216) { + color = smallArrowIcons[3][j+i*20]; + + blue = color&0xff; + red = (color&0xff0000) >> 16; + if(red < 100 && blue > 100) + continue; + + if(pixelInsideSideArea(index)) + continue; + + if(red > 200) + color = arrowColor; + screen[index] = color; + } + } + } + + //draw down right arrow + start = xPos + r + (yPos + r)*768; + for(int i = 0; i < 20; i++) { + for(int j = 0; j < 20; j++) { + index = start + j + i*768; + if(index > 0 && index < 393216) { + color = smallArrowIcons[0][j+i*20]; + + blue = color&0xff; + red = (color&0xff0000) >> 16; + if(red < 100 && blue > 100) + continue; + + if(pixelInsideSideArea(index)) + continue; + + if(red > 200) + color = arrowColor; + screen[index] = color; + } + } + } + + //draw down left arrow + start = xPos -r + (yPos + r)*768; + for(int i = 0; i < 20; i++) { + for(int j = 0; j < 20; j++) { + index = start + j + i*768; + if(index > 0 && index < 393216) { + color = smallArrowIcons[1][j+i*20]; + + blue = color&0xff; + red = (color&0xff0000) >> 16; + if(red < 100 && blue > 100) + continue; + + if(pixelInsideSideArea(index)) + continue; + + if(red > 200) + color = arrowColor; + screen[index] = color; + } + } + } + + } + + public boolean pixelInsideSideArea(int index){ + int x = index%768; + int y = index/768; + + if(x >=3 && x <=133 && y >= 378 && y <= 509) + return true; + + if(x >=635 && x <=765 && y >= 378 && y <= 509) + return true; + + return false; + } + + + + public void drawIcon(int[] icon, int xPos, int yPos) { + int color = 0; for(int i = 0; i < 24; i++) { for(int j = 0; j < 24; j++) { int x = xPos + j; @@ -143,7 +323,7 @@ public class gameCursor { if(y < 0 || y >= 512) continue; - int color = icon[j+i*24]; + color = icon[j+i*24]; int blue = color&0xff; int red = (color&0xff0000) >> 16; @@ -154,5 +334,208 @@ public class gameCursor { } } + + public void drawSelectionIcon(int xPos, int yPos) { + + + int r = (9 - (mainThread.gameFrame%18)/2) + 10; + int w = 8; + int index = 0; + int lightGray = 0xffffff; + int darkGray = 0x222222; + + //draw top left + int start = xPos - r + (yPos-r)*768; + for(int i = 0; i < w + 2; i++) { + index = start - 768 - 2 + i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w; i++) { + index = start + i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = lightGray; + } + + for(int i = 0; i < w; i++) { + index = start + 768 + i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < 3; i++) { + index = start + w - 768 + i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w + 1; i++) { + index = start - 2 + i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w; i++) { + index = start - 1 + i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = lightGray; + } + + for(int i = 0; i < w; i++) { + index = start + 768 + i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + index = start -1 + w*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = 0x0; + + //draw top right + start = xPos + r + (yPos-r)*768; + for(int i = 0; i < w + 2; i++) { + index = start - 768 + 2 - i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w; i++) { + index = start - i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = lightGray; + } + + for(int i = 0; i < w; i++) { + index = start + 768 - i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < 3; i++) { + index = start - w - 768 + i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w + 1; i++) { + index = start + 2 + i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w; i++) { + index = start + 1 + i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = lightGray; + } + + for(int i = 0; i < w; i++) { + index = start + 768 + i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + index = start +1 + w*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = 0x0; + + //draw bottom left + start = xPos - r + (yPos+r)*768; + for(int i = 0; i < w + 2; i++) { + index = start + 768 - 2 + i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w; i++) { + index = start + i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = lightGray; + } + + for(int i = 0; i < w; i++) { + index = start - 768 + i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < 3; i++) { + index = start + w + 768 - i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w + 1; i++) { + index = start - 2 - i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w; i++) { + index = start - 1 - i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = lightGray; + } + + for(int i = 0; i < w; i++) { + index = start - 768 - i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + index = start -1 - w*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = 0x0; + + //draw bottom right + start = xPos + r + (yPos+r)*768; + for(int i = 0; i < w + 2; i++) { + index = start + 768 + 2 - i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w; i++) { + index = start - i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = lightGray; + } + + for(int i = 0; i < w; i++) { + index = start - 768 - i; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < 3; i++) { + index = start - w + 768 - i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w + 1; i++) { + index = start + 2 - i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + for(int i = 0; i < w; i++) { + index = start + 1 - i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = lightGray; + } + + for(int i = 0; i < w; i++) { + index = start - 768 - i*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = darkGray; + } + + index = start +1 - w*768; + if(index > 0 && index < 393216 && !pixelInsideSideArea(index)) + screen[index] = 0x0; + + } } diff --git a/gui/gameMenu.java b/gui/gameMenu.java index 52a2c42..3bcc818 100644 --- a/gui/gameMenu.java +++ b/gui/gameMenu.java @@ -88,7 +88,7 @@ public class gameMenu { + "\"Left Click\" -- Select a unit. Left click + mouse drag can be used to select up to \n100 units at a time. Double left click on a unit will automatically select surrounding \nunits of the same type.\n\n" + "\"Right Click\" -- Issue a move or attack command to the selected unit(s). You can \nalso use right click to set rally point or cancel build progress.\n\n" + "\"a\" -- Force attack a unit. If no unit is under the cursor, then the selected units will \nbe set to attack move to the cursor location.\n\n" - + "\"h\" -- stop current action for the selected unit(s).\n\n" + + "\"s\" -- stop current action for the selected unit(s).\n\n" + "\"Ctrl + number\" -- Create a control group and assigned the number to the group.\n\n" + "\"Ctrl + Left Click\" -- Add/Remove a unit to/from the selected units.\n\n" + "\"Ctrl + Mouse Drag\" -- Add units in the dragging box to the selected units.\n\n\n" diff --git a/gui/inputHandler.java b/gui/inputHandler.java index c5b4d78..d90e13f 100644 --- a/gui/inputHandler.java +++ b/gui/inputHandler.java @@ -21,7 +21,7 @@ public class inputHandler { rightMouseButtonPressed, leftMouseButtonReleased, rightMouseButtonReleased, - H_pressed, + S_pressed, A_pressed, C_pressed, F_pressed, @@ -55,9 +55,9 @@ public class inputHandler { - if(c == 'h' || c == 'H'){ + if(c == 's' || c == 'S'){ - H_pressed = true; + S_pressed = true; } if(c == 'a' || c == 'A'){ @@ -90,8 +90,8 @@ public class inputHandler { char c = inputBuffer[inputBufferIndex]; - if(c == 'h' || c == 'H'){ - H_pressed = true; + if(c == 's' || c == 'S'){ + S_pressed = true; } if(c == 'a' || c == 'A'){ @@ -121,8 +121,8 @@ public class inputHandler { if(keyReleaseBufferIndex > theCounter){ while(keyReleaseBufferIndex < 1024){ char c = keyReleaseBuffer[keyReleaseBufferIndex]; - if(c == 'h' || c == 'H'){ - H_pressed = false; + if(c == 's' || c == 'S'){ + S_pressed = false; } if(c == 'a' || c == 'A'){ @@ -145,8 +145,8 @@ public class inputHandler { } while(keyReleaseBufferIndex < theCounter){ char c = keyReleaseBuffer[keyReleaseBufferIndex]; - if(c == 'h' || c == 'H'){ - H_pressed = false; + if(c == 's' || c == 'S'){ + S_pressed = false; } if(c == 'a' || c == 'A'){ @@ -277,7 +277,7 @@ public class inputHandler { } //handle hotheys - if(H_pressed){ + if(S_pressed){ mainThread.pc.holdKeyPressed = true; } @@ -364,7 +364,7 @@ public class inputHandler { A_pressed = false; - H_pressed = false; + S_pressed = false; C_pressed = false; F_pressed = false; numberTyped = 0; diff --git a/images/smallArrow0.png b/images/smallArrow0.png new file mode 100644 index 0000000..0e691ce Binary files /dev/null and b/images/smallArrow0.png differ diff --git a/images/smallArrow1.png b/images/smallArrow1.png new file mode 100644 index 0000000..8c0c2c0 Binary files /dev/null and b/images/smallArrow1.png differ diff --git a/images/smallArrow2.png b/images/smallArrow2.png new file mode 100644 index 0000000..69c2f65 Binary files /dev/null and b/images/smallArrow2.png differ diff --git a/images/smallArrow3.png b/images/smallArrow3.png new file mode 100644 index 0000000..99e681d Binary files /dev/null and b/images/smallArrow3.png differ