diff --git a/data.mv.db b/data.mv.db index 94b5f36..ca2bddc 100644 Binary files a/data.mv.db and b/data.mv.db differ diff --git a/maps/f845355e-b9ad-4884-a217-dd3a4c18a3fa.dat b/maps/f845355e-b9ad-4884-a217-dd3a4c18a3fa.dat index 0688ac6..647f985 100644 Binary files a/maps/f845355e-b9ad-4884-a217-dd3a4c18a3fa.dat and b/maps/f845355e-b9ad-4884-a217-dd3a4c18a3fa.dat differ diff --git a/src/main/java/com/bartlomiejpluta/demo/ai/SimpleEnemyAI.java b/src/main/java/com/bartlomiejpluta/demo/ai/SimpleEnemyAI.java new file mode 100644 index 0000000..7bc2a1a --- /dev/null +++ b/src/main/java/com/bartlomiejpluta/demo/ai/SimpleEnemyAI.java @@ -0,0 +1,43 @@ +package com.bartlomiejpluta.demo.ai; + +import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer; + +import com.bartlomiejpluta.base.util.pathfinder.*; +import com.bartlomiejpluta.base.api.ai.*; +import com.bartlomiejpluta.base.lib.ai.*; + +import com.bartlomiejpluta.demo.entity.Enemy; +import com.bartlomiejpluta.demo.entity.Character; + +public class SimpleEnemyAI extends FollowEntityAI { + private static final int ASTAR_MAX_NODES = 100; + private static final int IDLE_MOVEMENT_INTERVAL = 4; + private final AI idle; + private final int range; + + public SimpleEnemyAI(Enemy enemy, Character target, int range) { + super(new AstarPathFinder(ASTAR_MAX_NODES), enemy, target); + this.range = range; + this.idle = new RandomMovementAI(enemy, IDLE_MOVEMENT_INTERVAL); + } + + @Override + protected boolean sees(Enemy enemy, Character target, ObjectLayer layer, int distance) { + return distance < range; + } + + @Override + protected void interact(Enemy enemy, Character target, ObjectLayer layer, float dt) { + enemy.attack(); + } + + @Override + protected void follow(Enemy enemy, Character target, ObjectLayer layer, float dt) { + // noop + } + + @Override + protected void idle(Enemy enemy, Character target, ObjectLayer layer, float dt) { + idle.nextActivity(layer, dt); + } +} \ No newline at end of file diff --git a/src/main/java/com/bartlomiejpluta/demo/entity/Enemy.java b/src/main/java/com/bartlomiejpluta/demo/entity/Enemy.java index 6dd0cf3..b54d25f 100644 --- a/src/main/java/com/bartlomiejpluta/demo/entity/Enemy.java +++ b/src/main/java/com/bartlomiejpluta/demo/entity/Enemy.java @@ -1,17 +1,21 @@ package com.bartlomiejpluta.demo.entity; import lombok.*; + import com.bartlomiejpluta.base.api.context.Context; import com.bartlomiejpluta.base.api.entity.Entity; import com.bartlomiejpluta.base.api.ai.AI; import com.bartlomiejpluta.base.api.ai.NPC; +import com.bartlomiejpluta.base.api.move.MoveEvent; import com.bartlomiejpluta.base.lib.ai.NoopAI; import com.bartlomiejpluta.demo.runner.DemoRunner; import com.bartlomiejpluta.demo.database.model.EnemyModel; - import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon; +import com.bartlomiejpluta.demo.event.EnemyDiedEvent; +import com.bartlomiejpluta.demo.ai.*; + public class Enemy extends Character implements NPC { private final EnemyModel template; @@ -41,10 +45,23 @@ public class Enemy extends Character implements NPC { setZIndex(-1); ai = NoopAI.INSTANCE; + + getLayer().handleEvent(new EnemyDiedEvent(this)); } @Override public String toString() { return template.getName() + "@" + hashCode(); } + + public Enemy followAndAttack(Character target, int range) { + var ai = new SimpleEnemyAI(this, target, range); + + addEventListener(MoveEvent.TYPE, e -> ai.recomputePath()); + addEventListener(EnemyDiedEvent.TYPE, e -> ai.recomputePath()); + + this.ai = ai; + + return this; + } } \ No newline at end of file diff --git a/src/main/java/com/bartlomiejpluta/demo/event/EnemyDiedEvent.java b/src/main/java/com/bartlomiejpluta/demo/event/EnemyDiedEvent.java new file mode 100644 index 0000000..16412b8 --- /dev/null +++ b/src/main/java/com/bartlomiejpluta/demo/event/EnemyDiedEvent.java @@ -0,0 +1,20 @@ +package com.bartlomiejpluta.demo.event; + +import lombok.*; + +import com.bartlomiejpluta.base.api.event.*; +import com.bartlomiejpluta.base.lib.event.*; +import com.bartlomiejpluta.demo.entity.Enemy; + +@Getter +@RequiredArgsConstructor +public class EnemyDiedEvent extends BaseEvent { + public static final EventType TYPE = new EventType<>("ENEMY_DIED_EVENT"); + + private final Enemy enemy; + + @Override + public EventType getType() { + return TYPE; + } +} \ No newline at end of file diff --git a/src/main/java/com/bartlomiejpluta/demo/map/BaseMapHandler.java b/src/main/java/com/bartlomiejpluta/demo/map/BaseMapHandler.java index 667d001..283f41d 100644 --- a/src/main/java/com/bartlomiejpluta/demo/map/BaseMapHandler.java +++ b/src/main/java/com/bartlomiejpluta/demo/map/BaseMapHandler.java @@ -75,9 +75,10 @@ public abstract class BaseMapHandler implements MapHandler { cameraController.update(); } - public void enemy(int x, int y, @NonNull String id) { + public Enemy enemy(int x, int y, @NonNull String id) { var enemy = new Enemy(context, runner.getEnemyDAO().get(id)); enemy.setCoordinates(x, y); mainLayer.addEntity(enemy); + return enemy; } } \ No newline at end of file