package space.m0e.quga.oop.lab56maven.entities.micro; import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.control.Label; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.*; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.util.Duration; import space.m0e.quga.oop.lab56maven.dialogs.ChangeDialog; import space.m0e.quga.oop.lab56maven.Main; import space.m0e.quga.oop.lab56maven.entities.common.Ability; import space.m0e.quga.oop.lab56maven.entities.common.Coordinates; import space.m0e.quga.oop.lab56maven.entities.common.Item; import space.m0e.quga.oop.lab56maven.entities.macro.Fortress; import space.m0e.quga.oop.lab56maven.handlers.ImmigrantHandler; import java.io.IOException; import java.util.*; import java.util.stream.Collectors; public class Immigrant implements Comparable, Cloneable { private String firstName; private String lastName; private int age; private double x; private double y; private Ability ability; public HashMap getItems() { return items; } public void setItems(HashMap items) { this.items = items; } private HashMap items = new HashMap(); // private static final String[] availableItems = new String[]{"axe", "pickaxe", "shovel", "piece of coal", "wood log"}; private double hp; private double maxHp; private static final double hpCap; private boolean isActive = false; private final VBox vBox = new VBox(); private final Label label; private final ImageView sprite; private final Rectangle hpBar; private static final Image spriteImage = new Image(Objects.requireNonNull(Immigrant.class.getResourceAsStream("immigrant.png"))); public Timeline getTimeline() { return timeline; } public void setTimeline(Timeline timeline) { this.timeline = timeline; } public EventHandler getHandler() { return handler; } public void setHandler(EventHandler handler) { this.handler = handler; } private EventHandler handler = new ImmigrantHandler(this); private Timeline timeline = new Timeline(new KeyFrame(Duration.millis(20), this.handler)); public Immigrant(String firstName, String lastName, int age, double x, double y, Ability ability) { this.firstName = firstName; this.lastName = lastName; this.age = age; this.x = x; this.y = y; this.ability = ability; this.label = new Label(firstName + " " + lastName); this.label.setStyle("-fx-text-fill: white; -fx-font-size: 16px; -fx-background-color: grey"); this.sprite = new ImageView(spriteImage); this.hpBar = new Rectangle(50, 10); this.hpBar.widthProperty().multiply(this.hp/this.maxHp); this.hpBar.setFill(Color.LIME); this.vBox.setSpacing(5); this.vBox.setLayoutX(this.x); this.vBox.setLayoutY(this.y); this.vBox.getChildren().addAll(label, sprite, hpBar); this.vBox.setAlignment(Pos.CENTER); this.vBox.setOnMouseClicked(event -> { switch (event.getButton()) { case PRIMARY -> { this.setActive(!this.isActive); } case SECONDARY -> { try { ChangeDialog.display(this); } catch (IOException e) { e.printStackTrace(); } } } }); getTimeline().setCycleCount(Animation.INDEFINITE); Main.root.getChildren().add(this.getGroup()); } public Immigrant() { this("Edzul", "Èrithbesmar", 35, 0, 0, Ability.values()[new Random().nextInt(Ability.values().length)]); } public Immigrant(String serializedData) { this(); String[] params = serializedData.split(","); this.setFirstName(params[1].split(" ")[0]); this.setLastName(params[1].split(" ")[1]); this.setX(Double.parseDouble(params[2])); this.setY(Double.parseDouble(params[3])); this.age = Integer.parseInt(params[4]); this.setHp(Double.parseDouble(params[5])); this.setMaxHp(Double.parseDouble(params[6])); Arrays.stream(params[7].split(";")).forEach(rawItem -> { String[] item = rawItem.split("="); items.put(Item.valueOf(item[0]), Integer.parseInt(item[1])); }); this.ability = Ability.valueOf(params[8]); } public boolean isActive() { return isActive; } public VBox getGroup() { return vBox; } public ImageView getSprite() { return sprite; } public Ability getAbility() { return ability; } public void setAbility(Ability ability) { this.ability = ability; } static { hpCap = 100 + new Random().nextInt(50); } { maxHp = 50 + new Random().nextInt(100); hp = maxHp; List tools = new ArrayList<>(List.of(Item.AXE, Item.PICKAXE, Item.SWORD)); int itemCount = new Random().nextInt(1, tools.size()); Collections.shuffle(tools); tools.stream().limit(itemCount).forEach(tool -> items.put(tool, 1)); } public String getFullName() { return this.firstName + " " + this.lastName; } public String getFirstName() { return this.firstName; } public String getLastName() { return this.lastName; } public int getAge() { return this.age; } public double getX() { return this.x; } public double getY() { return this.y; } public double getHp() { return this.hp; } public double getMaxHp() { return this.maxHp; } public double getHpCap() { return Immigrant.hpCap; } public void setFirstName(String firstName) { this.firstName = firstName; this.label.setText(firstName + " " + this.lastName); } public void setLastName(String lastName) { this.lastName = lastName; this.label.setText(firstName + " " + this.lastName); } public void setAge(int age) { this.age = age; } public void setX(double x) { this.x = x; this.vBox.setLayoutX(this.x); } public void setY(double y) { this.y = y; this.vBox.setLayoutY(this.y); } public void setHp(double hp) { this.hp = hp; this.hpBar.widthProperty().multiply(this.hp / this.maxHp); } public void setMaxHp(double maxHp) { this.maxHp = maxHp; if (this.maxHp > Immigrant.hpCap) { this.maxHp = Immigrant.hpCap; } this.hpBar.widthProperty().multiply(this.hp / this.maxHp); } @Override public String toString() { return String.format("%s{Name=%s, Age=%d, Ability=%s, HP: %f/%f, Items: [%s], Position=(%f,%f)}", this.getClass().getSimpleName(), this.getFullName(), this.age, this.ability, this.hp, this.maxHp, items.entrySet().stream().map(item -> String.format("%s (%d)", item.getKey().toString(), item.getValue())).collect(Collectors.joining(", ")), getX(), getY()); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Immigrant immigrant = (Immigrant) o; return Objects.equals(this.firstName, immigrant.firstName) && Objects.equals(this.lastName, immigrant.lastName); } public void setActive(boolean active) { this.isActive = active; if (this.isActive) { this.vBox.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(3)))); } else { this.vBox.setBorder(null); } Main.processImmigrants(); } public void print() { System.out.println(this); } public void grow() { this.age++; if (age > 24) { this.maxHp--; if (this.hp > this.maxHp) { this.hp = this.maxHp; } } else { this.maxHp++; this.hp++; } } public void hurt(double deltaHp) { this.hp -= deltaHp; if (this.hp < 0) { this.hp = 0; } } public void heal(double deltaHp) { this.hp += deltaHp; if (this.hp > this.maxHp) { this.hp = this.maxHp; } } public void attack(Immigrant immigrant) { double deltaHp = new Random().nextDouble(maxHp); immigrant.hurt(deltaHp); System.out.printf(""" %s attacked %s (%f HP) %s HP: %f/%f """, this.getFullName(), immigrant.getFullName(), deltaHp, immigrant.getFullName(), immigrant.getHp(), immigrant.getMaxHp()); } public Coordinates getCoordinatesToFortress(Fortress fortress) { int dwarvesCount = fortress.getDwarves().size(); double fortressX = fortress.getX() + fortress.getGroup().getBoundsInParent().getWidth() / 2 - this.getGroup().getWidth() / 2; double fortressY = fortress.getY() + fortress.getGroup().getBoundsInParent().getHeight() / 2 - this.getGroup().getHeight() / 2; return new Coordinates(fortressX, fortressY); } public Fortress findNearestFortress() { ArrayList searchFortresses = (ArrayList) Main.fortresses.clone(); searchFortresses.sort((o1, o2) -> { return (int) ((Math.abs(o1.getX() - this.x) + Math.abs(o1.getY() - this.y)) - (Math.abs(o2.getX() - this.x) + Math.abs(o2.getY() - this.y))); }); return searchFortresses.stream().filter(f -> f.getDwarves().size() < 9).findFirst().orElse(null); } public void moveAI() { Fortress searchFortress = findNearestFortress(); Coordinates fortressToMove = this.getCoordinatesToFortress(searchFortress); } public void move(Coordinates coordinates) { if (!coordinates.isThere(this)) { double pointX = coordinates.getX(); double pointY = coordinates.getY(); if (pointX > this.getX()) { this.setX(this.getX() + 2); } if (pointX < this.getX()) { this.setX(this.getX() - 2); } if (pointY > this.getY()) { this.setY(this.getY() + 2); } if (pointY < this.getY()) { this.setY(this.getY() - 2); } } } @Override public int compareTo(Immigrant o) { return (int) (this.hp - o.hp); } @Override public Immigrant clone() throws CloneNotSupportedException { Immigrant immigrant = (Immigrant) super.clone(); immigrant.setItems(new HashMap<>(this.getItems())); return immigrant; } public String serialize() { return String.join(",", new String[]{ this.getClass().getSimpleName(), this.getFullName(), String.valueOf(this.getX()), String.valueOf(this.getY()), String.valueOf(this.getAge()), String.valueOf(this.getHp()), String.valueOf(this.getMaxHp()), this.getItems().entrySet().stream().map(item -> String.format("%s=%d", item.getKey(), item.getValue())).collect(Collectors.joining(";")), this.ability.toString() }); } }