664 lines
24 KiB
Java
664 lines
24 KiB
Java
package de.miaurizius.jgame2d.entity;
|
|
|
|
import de.miaurizius.jgame2d.core.Boot;
|
|
import de.miaurizius.jgame2d.core.enums.Direction;
|
|
import de.miaurizius.jgame2d.core.GamePanel;
|
|
import de.miaurizius.jgame2d.core.Utility;
|
|
import de.miaurizius.jgame2d.core.enums.EntityType;
|
|
import de.miaurizius.jgame2d.core.enums.GameState;
|
|
import de.miaurizius.jgame2d.entity.particle.Particle;
|
|
import de.miaurizius.jgame2d.entity.projectile.Projectile;
|
|
|
|
import javax.imageio.ImageIO;
|
|
import java.awt.*;
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
import java.util.logging.Level;
|
|
|
|
public class Entity {
|
|
|
|
protected GamePanel panel;
|
|
public BufferedImage up1, up2, down1, down2, left1, left2, right1, right2;
|
|
public BufferedImage attackUp1, attackUp2, attackDown1, attackDown2, attackLeft1, attackLeft2, attackRight1, attackRight2;
|
|
public BufferedImage guardUp, guardDown, guardLeft, guardRight;
|
|
public BufferedImage image, image2, image3;
|
|
public Rectangle solidArea = new Rectangle(0, 0, 48, 48);
|
|
public Rectangle attackArea = new Rectangle(0, 0, 0, 0);
|
|
public Entity attacker;
|
|
public int solidAreaDefaultX, solidAreaDefaultY;
|
|
public boolean collision;
|
|
public String[][] dialogue = new String[20][20];
|
|
public Entity linkedEntity;
|
|
|
|
// STATE
|
|
public int worldX, worldY;
|
|
public Direction direction = Direction.DOWN;
|
|
public int spriteNum = 1;
|
|
public int dialogueSet;
|
|
public int dialogueIndex;
|
|
public boolean collisionOn;
|
|
public boolean invincible;
|
|
public boolean transparent;
|
|
public boolean attacking;
|
|
public boolean alive = true;
|
|
public boolean dying;
|
|
public boolean hpBarOn;
|
|
public boolean consumable;
|
|
public boolean onPath;
|
|
public boolean knockback;
|
|
public boolean guarding;
|
|
public boolean rage;
|
|
public Direction knockbackDirection;
|
|
|
|
// COUNTER
|
|
public int spriteCount;
|
|
public int actionLock;
|
|
public int invincibleCount;
|
|
public int shotAvailableCount;
|
|
int dyingCount;
|
|
int hpBarCount;
|
|
int knockbackCount;
|
|
|
|
// CHARACTER ATTRIBUTES
|
|
public EntityType type;
|
|
public int defaultSpeed;
|
|
public String name;
|
|
public int speed;
|
|
public int maxLife;
|
|
public int life;
|
|
public int level;
|
|
public int strength;
|
|
public int dexterity;
|
|
public int attack;
|
|
public int defense;
|
|
public int exp;
|
|
public int nextLevelExp;
|
|
public int coins;
|
|
public int maxMana;
|
|
public int mana;
|
|
public Entity currentWeapon;
|
|
public Entity currentShield;
|
|
public Entity currentLight;
|
|
public Projectile projectile;
|
|
public List<Entity> inventory = new ArrayList<>();
|
|
public final int maxInvSize = 20;
|
|
|
|
// ITEM ATTRIBUTES
|
|
public EntityType.WeaponType weaponType;
|
|
public int attackValue;
|
|
public int defenseValue;
|
|
public String description;
|
|
public int useCost;
|
|
public int value;
|
|
public int price;
|
|
public int knockbackVal;
|
|
public boolean stackable;
|
|
public int amt = 1;
|
|
public float lightRadius;
|
|
public boolean opened;
|
|
public Entity loot;
|
|
|
|
public Entity(GamePanel panel) {
|
|
this.panel = panel;
|
|
}
|
|
|
|
// DEFAULT
|
|
public void update() {
|
|
if(knockback) {
|
|
checkCollision();
|
|
if(collisionOn) {
|
|
knockbackCount = 0;
|
|
knockback = false;
|
|
speed = defaultSpeed;
|
|
invincibleCounting();
|
|
return;
|
|
}
|
|
|
|
switch(knockbackDirection) {
|
|
case UP -> worldY -= speed;
|
|
case DOWN -> worldY += speed;
|
|
case LEFT ->worldX -= speed;
|
|
case RIGHT -> worldX += speed;
|
|
}
|
|
|
|
knockbackCount++;
|
|
if(knockbackCount != 10) {
|
|
invincibleCounting();
|
|
return;
|
|
}
|
|
|
|
knockback = false;
|
|
knockbackCount = 0;
|
|
speed = defaultSpeed;
|
|
} else if(attacking) attacking();
|
|
else {
|
|
setAction();
|
|
checkCollision();
|
|
|
|
if(!collisionOn) {
|
|
switch (direction) {
|
|
case UP -> worldY -= speed;
|
|
case DOWN -> worldY += speed;
|
|
case LEFT ->worldX -= speed;
|
|
case RIGHT -> worldX += speed;
|
|
}
|
|
}
|
|
|
|
spriteCount++;
|
|
if(spriteCount > 24) {
|
|
if(spriteNum == 1) spriteNum = 2;
|
|
else if(spriteNum == 2) spriteNum = 1;
|
|
else spriteNum = 0;
|
|
spriteCount = 0;
|
|
}
|
|
}
|
|
invincibleCounting();
|
|
}
|
|
public void draw(Graphics2D graphics2d) {
|
|
int screenX = worldX - panel.player.worldX + panel.player.screenX;
|
|
int screenY = worldY - panel.player.worldY + panel.player.screenY;
|
|
|
|
if(worldX + panel.tileSize*5 > panel.player.worldX - panel.player.screenX &&
|
|
worldX - panel.tileSize < panel.player.worldX + panel.player.screenX &&
|
|
worldY + panel.tileSize*5 > panel.player.worldY - panel.player.screenY &&
|
|
worldY - panel.tileSize < panel.player.worldY + panel.player.screenY
|
|
) {
|
|
|
|
// MONSTER HP-BAR
|
|
if(this.type == EntityType.MONSTER && hpBarOn) {
|
|
graphics2d.setColor(new Color(35, 35, 35));
|
|
graphics2d.fillRect(screenX-1, screenY-6, panel.tileSize+2, 12);
|
|
|
|
graphics2d.setColor(new Color(255, 0, 30));
|
|
graphics2d.fillRect(screenX, screenY-5, (int) ((double) panel.tileSize/maxLife)*life, 10);
|
|
|
|
hpBarCount++;
|
|
if(hpBarCount > 600) { //bar disappears after 10 seconds
|
|
hpBarCount = 0;
|
|
hpBarOn = false;
|
|
}
|
|
}
|
|
|
|
// DRAW ENTITY
|
|
if(invincible) {
|
|
hpBarOn = true;
|
|
hpBarCount = 0;
|
|
if(transparent) changeOpacity(graphics2d, 0.4f);
|
|
}
|
|
if(dying) dyingAnimation(graphics2d);
|
|
if(type == EntityType.PLAYER || name.equals("orc")) { // only modify sprite render position for player because I dont know yet how monster attack sprite are gonna look
|
|
if(attacking) graphics2d.drawImage(parseSpriteATK(),
|
|
(direction == Direction.LEFT) ? screenX - left1.getWidth() : screenX,
|
|
(direction == Direction.UP) ? screenY - up1.getHeight() : screenY, null);
|
|
else if(guarding) graphics2d.drawImage(parseSpriteGRD(), screenX, screenY, null);
|
|
else graphics2d.drawImage(parseSprite(), screenX, screenY, null);
|
|
} else graphics2d.drawImage(parseSprite(), screenX, screenY, null);
|
|
changeOpacity(graphics2d, 1f);
|
|
}
|
|
|
|
if(panel.keyH.debug) {
|
|
graphics2d.setColor(new Color(255, 0, 0, 70));
|
|
graphics2d.fillRect(worldX - panel.player.worldX + panel.player.screenX, worldY - panel.player.worldY + panel.player.screenY, panel.tileSize, panel.tileSize);
|
|
}
|
|
}
|
|
|
|
// INTERACTION
|
|
public void setAction() {}
|
|
public void moveTowardPlayer(int interval) {
|
|
actionLock++;
|
|
if(actionLock > interval) {
|
|
if(dX(panel.player) > dY(panel.player)) {
|
|
if(panel.player.getCenterX() < getCenterX()) direction = Direction.LEFT;
|
|
else direction = Direction.RIGHT;
|
|
} else if(dX(panel.player) < dY(panel.player)) {
|
|
if(panel.player.getCenterY() < getCenterY()) direction = Direction.UP;
|
|
else direction = Direction.DOWN;
|
|
}
|
|
actionLock = 0;
|
|
}
|
|
}
|
|
public void move(Direction direction) {}
|
|
public void damageReaction() {}
|
|
public void attacking() {
|
|
if(panel.player.attackCancel && type == EntityType.PLAYER) return;
|
|
spriteCount++;
|
|
if(spriteCount <= 5) spriteNum = 1;
|
|
if(spriteCount > 5 && spriteCount <= 25) {
|
|
spriteNum = 2;
|
|
int currentWorldX = worldX;
|
|
int currentWorldY = worldY;
|
|
int solidAreaWidth = solidArea.width;
|
|
int solidAreaHeight = solidArea.height;
|
|
|
|
switch(direction) {
|
|
case UP -> worldY -= attackArea.height;
|
|
case DOWN -> worldY += attackArea.height;
|
|
case LEFT -> worldX -= attackArea.width;
|
|
case RIGHT -> worldX += attackArea.width;
|
|
}
|
|
solidArea.width = attackArea.width;
|
|
solidArea.height = attackArea.height;
|
|
|
|
if(type == EntityType.MONSTER) if(panel.collisionH.checkPlayer(this)) damagePlayer(attack);
|
|
|
|
if(type == EntityType.PLAYER) {
|
|
int monsterIndex = panel.collisionH.checkEntity(this, panel.monster[panel.currentMap.getIndex()]);
|
|
panel.player.damageMonster(monsterIndex, this, attack, currentWeapon.knockbackVal);
|
|
|
|
int iTileIndex = panel.collisionH.checkEntity(this, panel.iTile[panel.currentMap.getIndex()]);
|
|
panel.player.interactTile(iTileIndex);
|
|
}
|
|
|
|
worldX = currentWorldX;
|
|
worldY = currentWorldY;
|
|
solidArea.width = solidAreaWidth;
|
|
solidArea.height = solidAreaHeight;
|
|
|
|
}
|
|
if(spriteCount > 25) {
|
|
spriteNum = 1;
|
|
spriteCount = 0;
|
|
attacking = false;
|
|
}
|
|
}
|
|
public void damagePlayer(int attack) {
|
|
if(panel.player.invincible) return;
|
|
|
|
boolean block = panel.player.guarding && panel.player.direction == this.direction.getOpposite();
|
|
int damage = attack - panel.player.defense;
|
|
|
|
if(block) {
|
|
panel.playSE(15);
|
|
damage = 0;
|
|
} else panel.playSE(6);
|
|
|
|
panel.player.life -= Math.max(damage, (block ? 0 : 1));
|
|
|
|
if(damage != 0) {
|
|
setKnockback(panel.player, this, knockbackVal);
|
|
panel.player.transparent = true;
|
|
}
|
|
panel.player.invincible = true;
|
|
}
|
|
public void speak() {
|
|
|
|
}
|
|
public void facePlayer() {
|
|
switch(panel.player.direction) {
|
|
case UP -> direction = Direction.DOWN;
|
|
case DOWN -> direction = Direction.UP;
|
|
case LEFT -> direction = Direction.RIGHT;
|
|
case RIGHT -> direction = Direction.LEFT;
|
|
}
|
|
}
|
|
public void startDialogue(Entity entity, int setNum) {
|
|
panel.gameState = GameState.DIALOGUE;
|
|
panel.ui.tradingNPC = entity;
|
|
dialogueSet = setNum;
|
|
}
|
|
public void dyingAnimation(Graphics2D graphics2d) {
|
|
dyingCount++;
|
|
int incr = 5;
|
|
if(dyingCount <= incr) changeOpacity(graphics2d, 0f);
|
|
if(dyingCount > incr && dyingCount <= incr*2) changeOpacity(graphics2d, 1f);
|
|
if(dyingCount > incr*2 && dyingCount <= incr*3) changeOpacity(graphics2d, 0f);
|
|
if(dyingCount > incr*3 && dyingCount <= incr*4) changeOpacity(graphics2d, 1f);
|
|
if(dyingCount > incr*4 && dyingCount <= incr*5) changeOpacity(graphics2d, 0f);
|
|
if(dyingCount > incr*5 && dyingCount <= incr*6) changeOpacity(graphics2d, 1f);
|
|
if(dyingCount > incr*6 && dyingCount <= incr*7) changeOpacity(graphics2d, 0f);
|
|
if(dyingCount > incr*7 && dyingCount <= incr*8) changeOpacity(graphics2d, 1f);
|
|
if(dyingCount > incr*8) {
|
|
alive = false;
|
|
}
|
|
}
|
|
public boolean use(Entity entity) {
|
|
return false;
|
|
} //If entity is consumable
|
|
public void checkDrop() {
|
|
|
|
}
|
|
public void checkCollision() {
|
|
collisionOn = false;
|
|
panel.collisionH.checkTile(this);
|
|
panel.collisionH.checkObject(this, false);
|
|
panel.collisionH.checkEntity(this, panel.npc[panel.currentMap.getIndex()]);
|
|
panel.collisionH.checkEntity(this, panel.monster[panel.currentMap.getIndex()]);
|
|
panel.collisionH.checkEntity(this, panel.iTile[panel.currentMap.getIndex()]);
|
|
boolean contactPlayer = panel.collisionH.checkPlayer(this);
|
|
|
|
if(this.type == EntityType.MONSTER && contactPlayer) damagePlayer(attack);
|
|
}
|
|
public void dropItem(Entity droppedItem) {
|
|
for(int i = 0; i < panel.obj[panel.currentMap.getIndex()].length; i++) {
|
|
if(panel.obj[panel.currentMap.getIndex()][i] == null) {
|
|
panel.obj[panel.currentMap.getIndex()][i] = droppedItem;
|
|
panel.obj[panel.currentMap.getIndex()][i].worldX = worldX;
|
|
panel.obj[panel.currentMap.getIndex()][i].worldY = worldY;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
public void interact() {
|
|
|
|
}
|
|
public int getDetected(Entity user, Entity[][] target, String targetName) {
|
|
int index = 999;
|
|
int nextWorldX = user.getLeftX();
|
|
int nextWorldY = user.getTopY();
|
|
|
|
switch(user.direction) {
|
|
case UP -> nextWorldY = user.getTopY()-panel.player.speed;
|
|
case DOWN -> nextWorldY = user.getBottomY()+panel.player.speed;
|
|
case LEFT -> nextWorldX = user.getLeftX()-panel.player.speed;
|
|
case RIGHT -> nextWorldX = user.getRightX()+panel.player.speed;
|
|
}
|
|
int col = nextWorldX / panel.tileSize;
|
|
int row = nextWorldY / panel.tileSize;
|
|
|
|
for(int i = 0; i < target[panel.currentMap.getIndex()].length; i++) {
|
|
if(target[panel.currentMap.getIndex()][i] == null) continue;
|
|
if(
|
|
target[panel.currentMap.getIndex()][i].getCol() == col &&
|
|
target[panel.currentMap.getIndex()][i].getRow() == row &&
|
|
target[panel.currentMap.getIndex()][i].name.equalsIgnoreCase(targetName)
|
|
) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return index;
|
|
}
|
|
public void setKnockback(Entity target, Entity attacker, int knockbackVal) {
|
|
this.attacker = attacker;
|
|
target.knockbackDirection = attacker.direction;
|
|
target.speed += knockbackVal;
|
|
target.knockback = true;
|
|
}
|
|
public void setLoot(Entity loot) {}
|
|
|
|
// PARTICLE SETUP
|
|
public Color getParticleColor() {
|
|
return null;
|
|
}
|
|
public int getParticleSize() {
|
|
return -1;
|
|
}
|
|
public int getParticleSpeed() {
|
|
return -1;
|
|
}
|
|
public int getParticleMaxLife() {
|
|
return -1;
|
|
}
|
|
public void generateParticle(Entity generator, Entity target) {
|
|
Color color = generator.getParticleColor();
|
|
int size = generator.getParticleSize();
|
|
int speed = generator.getParticleSpeed();
|
|
int maxLife = generator.getParticleMaxLife();
|
|
|
|
Particle p1 = new Particle(panel, target, color, size, speed, maxLife, -2, -1);
|
|
Particle p2 = new Particle(panel, target, color, size, speed, maxLife, 2, -1);
|
|
Particle p3 = new Particle(panel, target, color, size, speed, maxLife, -2, 1);
|
|
Particle p4 = new Particle(panel, target, color, size, speed, maxLife, 2, 1);
|
|
panel.particleList.add(p1);
|
|
panel.particleList.add(p2);
|
|
panel.particleList.add(p3);
|
|
panel.particleList.add(p4);
|
|
}
|
|
|
|
// GETTERS
|
|
public int getLeftX() {
|
|
return worldX + solidArea.x;
|
|
}
|
|
public int getRightX() {
|
|
return worldX + solidArea.x + solidArea.width;
|
|
}
|
|
public int getTopY() {
|
|
return worldY + solidArea.y;
|
|
}
|
|
public int getBottomY() {
|
|
return worldY + solidArea.y + solidArea.height;
|
|
}
|
|
public int getCol() {
|
|
return (worldX + solidArea.x) / panel.tileSize;
|
|
}
|
|
public int getRow() {
|
|
return (worldY + solidArea.y) / panel.tileSize;
|
|
}
|
|
public int dX(Entity target) {
|
|
return Math.abs(getCenterX() - target.getCenterX());
|
|
}
|
|
public int dY(Entity target) {
|
|
return Math.abs(getCenterY() - target.getCenterY());
|
|
}
|
|
public int getCenterX() {
|
|
return worldX + left1.getWidth()/2;
|
|
}
|
|
public int getCenterY() {
|
|
return worldY + up1.getHeight()/2;
|
|
}
|
|
public int dTile(Entity target) {
|
|
//if(Objects.equals(name, "orc")) System.out.println("dX: " + dX(target) + " dY: " + dY(target));
|
|
return (dX(target) + dY(target)) / panel.tileSize;
|
|
}
|
|
public int getGoalCol(Entity target) {
|
|
return (target.worldX+target.solidArea.x)/panel.tileSize;
|
|
}
|
|
public int getGoalRow(Entity target) {
|
|
return (target.worldY+target.solidArea.y)/panel.tileSize;
|
|
}
|
|
|
|
// SETTING THINGS UP
|
|
BufferedImage parseSprite() {
|
|
return switch (direction) {
|
|
case UP -> (spriteNum == 1) ? up1 : up2;
|
|
case DOWN -> (spriteNum == 1) ? down1 : down2;
|
|
case LEFT -> (spriteNum == 1) ? left1 : left2;
|
|
case RIGHT -> (spriteNum == 1) ? right1 : right2;
|
|
};
|
|
}
|
|
BufferedImage parseSpriteATK() {
|
|
return switch (direction) {
|
|
case UP -> (spriteNum == 1) ? attackUp1 : attackUp2;
|
|
case DOWN -> (spriteNum == 1) ? attackDown1 : attackDown2;
|
|
case LEFT -> (spriteNum == 1) ? attackLeft1 : attackLeft2;
|
|
case RIGHT -> (spriteNum == 1) ? attackRight1 : attackRight2;
|
|
};
|
|
}
|
|
BufferedImage parseSpriteGRD() {
|
|
return switch (direction) {
|
|
case UP -> guardUp;
|
|
case DOWN -> guardDown;
|
|
case LEFT -> guardLeft;
|
|
case RIGHT -> guardRight;
|
|
};
|
|
}
|
|
public BufferedImage initEntitySprites(String name) {
|
|
try {
|
|
return Utility.scaleImage(ImageIO.read(new FileInputStream("assets/" + name + ".png")), panel.tileSize, panel.tileSize);
|
|
} catch (IOException e) {
|
|
Boot.logger.log(Level.SEVERE, "Could not load entity-image", e);
|
|
}
|
|
return null;
|
|
}
|
|
public BufferedImage initEntitySprites(String name, int width, int height) {
|
|
try {
|
|
return Utility.scaleImage(ImageIO.read(new FileInputStream("assets/" + name + ".png")), width, height);
|
|
} catch (IOException e) {
|
|
Boot.logger.log(Level.SEVERE, "Could not load entity-image", e);
|
|
}
|
|
return null;
|
|
}
|
|
public void setDialogue() {}
|
|
public void changeOpacity(Graphics2D graphics2d, float opacity) {
|
|
graphics2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
|
|
}
|
|
public void searchPath(int goalCol, int goalRow) {
|
|
int startCol = (worldX + solidArea.x) / panel.tileSize;
|
|
int startRow = (worldY + solidArea.y) / panel.tileSize;
|
|
|
|
panel.pFinder.setNodes(startCol, startRow, goalCol, goalRow);
|
|
|
|
if (panel.pFinder.search()) {
|
|
int nextCol = panel.pFinder.pathList.getFirst().col;
|
|
int nextRow = panel.pFinder.pathList.getFirst().row;
|
|
|
|
int enLeftX = worldX + solidArea.x;
|
|
int enTopY = worldY + solidArea.y;
|
|
|
|
int targetX = nextCol * panel.tileSize;
|
|
int targetY = nextRow * panel.tileSize;
|
|
|
|
// UP
|
|
if (nextRow < startRow) {
|
|
if (enLeftX < targetX) direction = Direction.RIGHT;
|
|
else if (enLeftX > targetX) direction = Direction.LEFT;
|
|
else direction = Direction.UP;
|
|
}
|
|
// DOWN
|
|
else if (nextRow > startRow) {
|
|
if (enLeftX < targetX) direction = Direction.RIGHT;
|
|
else if (enLeftX > targetX) direction = Direction.LEFT;
|
|
else direction = Direction.DOWN;
|
|
|
|
}
|
|
else if (nextCol < startCol) { // DOWN LEFT
|
|
if (enTopY < targetY) direction = Direction.DOWN;
|
|
else if (enTopY > targetY) direction = Direction.UP;
|
|
else direction = Direction.LEFT;
|
|
}
|
|
else if (nextCol > startCol) { // RIGHT
|
|
if (enTopY < targetY) direction = Direction.DOWN;
|
|
else if (enTopY > targetY) direction = Direction.UP;
|
|
else direction = Direction.RIGHT;
|
|
}
|
|
} else onPath = false;
|
|
}
|
|
public void followPlayer() {
|
|
int goalCol = panel.player.getCol();
|
|
int goalRow = panel.player.getRow();
|
|
|
|
int startCol = (worldX + solidArea.x) / panel.tileSize;
|
|
int startRow = (worldY + solidArea.y) / panel.tileSize;
|
|
|
|
panel.pFinder.setNodes(startCol, startRow, goalCol, goalRow);
|
|
|
|
if (panel.pFinder.search()) {
|
|
int nextCol = panel.pFinder.pathList.getFirst().col;
|
|
int nextRow = panel.pFinder.pathList.getFirst().row;
|
|
|
|
int enLeftX = worldX + solidArea.x;
|
|
int enTopY = worldY + solidArea.y;
|
|
|
|
int targetX = nextCol * panel.tileSize;
|
|
int targetY = nextRow * panel.tileSize;
|
|
|
|
// UP
|
|
if (nextRow < startRow) {
|
|
if (enLeftX < targetX) direction = Direction.RIGHT;
|
|
else if (enLeftX > targetX) direction = Direction.LEFT;
|
|
else direction = Direction.UP;
|
|
}
|
|
// DOWN
|
|
else if (nextRow > startRow) {
|
|
if (enLeftX < targetX) direction = Direction.RIGHT;
|
|
else if (enLeftX > targetX) direction = Direction.LEFT;
|
|
else direction = Direction.DOWN;
|
|
|
|
}
|
|
else if (nextCol < startCol) { // DOWN LEFT
|
|
if (enTopY < targetY) direction = Direction.DOWN;
|
|
else if (enTopY > targetY) direction = Direction.UP;
|
|
else direction = Direction.LEFT;
|
|
}
|
|
else if (nextCol > startCol) { // RIGHT
|
|
if (enTopY < targetY) direction = Direction.DOWN;
|
|
else if (enTopY > targetY) direction = Direction.UP;
|
|
else direction = Direction.RIGHT;
|
|
}
|
|
}
|
|
}
|
|
public void checkStopChasing(Entity target, int distance, int rate) {
|
|
//if(Objects.equals(name, "orc")) System.out.println("dTile: " + dTile(target) + " distance: " + distance);
|
|
if(dTile(target) > distance) onPath = false;
|
|
}
|
|
public void checkStartChasing(Entity target, int distance, int rate) {
|
|
if(dTile(target) < distance) onPath = true;
|
|
}
|
|
public void checkShooting(int rate, int shotInterval) {
|
|
if(new Random().nextInt(rate) == 0 && projectile.alive == false && shotAvailableCount == shotInterval) {
|
|
projectile.set(worldX, worldY, direction, true, this);
|
|
|
|
// CHECK VACANCY
|
|
for(int ii = 0; ii < panel.projectileList.size(); ii++) {
|
|
if(panel.projectileList.get(ii) == null) {
|
|
panel.projectileList.set(ii, projectile);
|
|
break;
|
|
}
|
|
}
|
|
shotAvailableCount = 0;
|
|
}
|
|
}
|
|
public void checkAttack(int rate, int straight, int horizontal) {
|
|
boolean targetInRange = false;
|
|
int xDist = dX(panel.player);
|
|
int yDist = dY(panel.player);
|
|
|
|
switch(direction) {
|
|
case UP -> {
|
|
if(panel.player.getCenterY() < getCenterY() && yDist < straight && xDist < horizontal) targetInRange = true;
|
|
}
|
|
case DOWN -> {
|
|
if(panel.player.getCenterY() > getCenterY() && yDist < straight && xDist < horizontal) targetInRange = true;
|
|
}
|
|
case LEFT -> {
|
|
if(panel.player.getCenterX() < getCenterX() && xDist < straight && yDist < horizontal) targetInRange = true;
|
|
}
|
|
case RIGHT -> {
|
|
if(panel.player.getCenterX() > getCenterX() && xDist < straight && yDist < horizontal) targetInRange = true;
|
|
}
|
|
}
|
|
|
|
if(targetInRange)
|
|
if (new Random().nextInt(rate) == 0) {
|
|
attacking = true;
|
|
spriteNum = 1;
|
|
spriteCount = 0;
|
|
shotAvailableCount = 0;
|
|
}
|
|
}
|
|
public void setRandomDirection(int interval) {
|
|
actionLock++;
|
|
if(actionLock > interval) { //lock action for x frames
|
|
Random rand = new Random();
|
|
int i = rand.nextInt(100)+1; //Generate number between 1 and 100
|
|
if(i <= 25) direction = Direction.UP;
|
|
if(i > 25 && i <= 50) direction = Direction.DOWN;
|
|
if(i > 50 && i <= 75) direction = Direction.LEFT;
|
|
if(i > 75) direction = Direction.RIGHT;
|
|
actionLock = 0;
|
|
}
|
|
}
|
|
public void invincibleCounting() {
|
|
if(!invincible) return;
|
|
invincibleCount++;
|
|
if(invincibleCount > 40) {
|
|
invincible = false;
|
|
invincibleCount = 0;
|
|
}
|
|
}
|
|
public void resetCounter() {
|
|
spriteCount = 0;
|
|
actionLock = 0;
|
|
invincibleCount = 0;
|
|
shotAvailableCount = 0;
|
|
dyingCount = 0;
|
|
hpBarCount = 0;
|
|
knockbackCount = 0;
|
|
}
|
|
|
|
}
|