From c967562498040d2fc37f6c97c919ef3dbf2d227a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Fri, 2 Sep 2022 22:10:00 +0200 Subject: [PATCH] Improve enemy loot generation --- .../bartlomiejpluta/demo/entity/Enemy.java | 35 +--------- .../demo/util/LootGenerator.java | 65 +++++++++++++++++++ 2 files changed, 67 insertions(+), 33 deletions(-) create mode 100644 src/main/java/com/bartlomiejpluta/demo/util/LootGenerator.java diff --git a/src/main/java/com/bartlomiejpluta/demo/entity/Enemy.java b/src/main/java/com/bartlomiejpluta/demo/entity/Enemy.java index 83487d0..b803de3 100644 --- a/src/main/java/com/bartlomiejpluta/demo/entity/Enemy.java +++ b/src/main/java/com/bartlomiejpluta/demo/entity/Enemy.java @@ -1,7 +1,5 @@ package com.bartlomiejpluta.demo.entity; -import DB.EnemyDropDAO; -import DB.dao; import com.bartlomiejpluta.base.api.ai.AI; import com.bartlomiejpluta.base.api.ai.NPC; import com.bartlomiejpluta.base.api.context.ContextHolder; @@ -9,13 +7,12 @@ import com.bartlomiejpluta.base.api.move.MoveEvent; import com.bartlomiejpluta.base.lib.ai.NoopAI; import com.bartlomiejpluta.base.lib.animation.AnimationRunner; import com.bartlomiejpluta.base.lib.animation.SimpleAnimationRunner; -import com.bartlomiejpluta.base.lib.db.Relop; import com.bartlomiejpluta.base.util.random.DiceRoller; import com.bartlomiejpluta.demo.ai.*; import com.bartlomiejpluta.demo.event.EnemyDiedEvent; import com.bartlomiejpluta.demo.runner.DemoRunner; +import com.bartlomiejpluta.demo.util.LootGenerator; import com.bartlomiejpluta.demo.world.item.Item; -import com.bartlomiejpluta.demo.world.junk.Junk; import com.bartlomiejpluta.demo.world.weapon.Ammunition; import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon; import com.bartlomiejpluta.demo.world.weapon.RangedWeapon; @@ -24,8 +21,6 @@ import lombok.NonNull; import java.util.Random; -import static com.bartlomiejpluta.demo.util.ListUtil.randomIntSequence; - public class Enemy extends Creature implements NPC { public static final int MAX_LOOT = 4 * 4; @@ -99,35 +94,9 @@ public class Enemy extends Creature implements NPC { context.playSound(A.sounds.get(template.getDieSound()).uid); context.fireEvent(new EnemyDiedEvent(this)); - drawLoot(); + LootGenerator.generate(template.getId(), loot); } - private void drawLoot() { - var def = dao.enemy_drop.query() - .where(EnemyDropDAO.Column.ENEMY, Relop.EQ, template.getId()) - .orderBy("rand()") - .find(); - - var indexesIterator = randomIntSequence(0, loot.length).iterator(); - for (var d : def) { - if (!indexesIterator.hasNext()) { - break; - } - - var index = indexesIterator.next(); - - var split = d.getItem().split(":"); - loot[index] = switch (split[0]) { - case "melee_weapon" -> new MeleeWeapon(split[1]); - case "ranged_weapon" -> new RangedWeapon(split[1]); - case "ammo" -> new Ammunition(split[1], DiceRoller.roll(d.getAmount())); - case "junk" -> new Junk(split[1]); - default -> throw new IllegalArgumentException("Unsupported item type"); - }; - } - } - - public Enemy followAndAttack(Creature target, int range) { var ai = new SimpleEnemyAI(this, target, range); diff --git a/src/main/java/com/bartlomiejpluta/demo/util/LootGenerator.java b/src/main/java/com/bartlomiejpluta/demo/util/LootGenerator.java new file mode 100644 index 0000000..e1347a5 --- /dev/null +++ b/src/main/java/com/bartlomiejpluta/demo/util/LootGenerator.java @@ -0,0 +1,65 @@ +package com.bartlomiejpluta.demo.util; + +import DB.EnemyDropDAO; +import DB.dao; +import com.bartlomiejpluta.base.lib.db.Relop; +import com.bartlomiejpluta.demo.world.item.Item; +import com.bartlomiejpluta.demo.world.item.ItemStack; +import com.bartlomiejpluta.demo.world.junk.Junk; +import com.bartlomiejpluta.demo.world.potion.Medicament; +import com.bartlomiejpluta.demo.world.weapon.Ammunition; +import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon; +import com.bartlomiejpluta.demo.world.weapon.RangedWeapon; +import lombok.NonNull; + +import java.util.Map; +import java.util.Random; +import java.util.function.BiFunction; +import java.util.function.Function; + +import static com.bartlomiejpluta.base.util.random.DiceRoller.roll; +import static com.bartlomiejpluta.demo.util.ListUtil.randomIntSequence; + +public class LootGenerator { + private static final Random rand = new Random(); + private static final Map> itemGenerators = Map.of( + "melee", MeleeWeapon::new, + "ranged", RangedWeapon::new, + "junk", Junk::new + ); + private static final Map> stackableGenerator = Map.of( + "ammo", Ammunition::new, + "med", Medicament::new + ); + + public static void generate(@NonNull String enemy, @NonNull Item[] loot) { + var def = dao.enemy_drop.query() + .where(EnemyDropDAO.Column.ENEMY, Relop.EQ, enemy) + .orderBy("rand()") + .find(); + + var index = randomIntSequence(0, loot.length).iterator(); + + for (var template : def) { + var parts = template.getItem().split(":"); + + var item = itemGenerators.get(parts[0]); + if (item != null) { + for (int i = 0; i < roll(template.getAmount()) && index.hasNext(); ++i) { + if (rand.nextFloat() <= template.getChance()) { + loot[index.next()] = item.apply(parts[1]); + } + } + + continue; + } + + var stack = stackableGenerator.get(parts[0]); + if (stack != null && index.hasNext()) { + if (rand.nextFloat() <= template.getChance()) { + loot[index.next()] = stack.apply(parts[1], roll(template.getAmount())); + } + } + } + } +}