diff --git a/src/main/java/com/comandante/creeper/ConfigureNpc.java b/src/main/java/com/comandante/creeper/ConfigureNpc.java index 428736e12f85d9a85ea4d4f6385b4c630aaf50f6..2907a39fadfd41b00c1e35f6a738cbc1fec17c2b 100755 --- a/src/main/java/com/comandante/creeper/ConfigureNpc.java +++ b/src/main/java/com/comandante/creeper/ConfigureNpc.java @@ -65,12 +65,12 @@ public class ConfigureNpc { gameManager.getRoomManager().addMerchant(377, nigelBartender); Map<Integer, MerchantItemForSale> blacksmithItems = Maps.newHashMap(); - blacksmithItems.put(1, new MerchantItemForSale(ItemType.BROAD_SWORD, 1000)); - blacksmithItems.put(2, new MerchantItemForSale(ItemType.IRON_BOOTS, 800)); - blacksmithItems.put(3, new MerchantItemForSale(ItemType.IRON_BRACERS, 400)); - blacksmithItems.put(4, new MerchantItemForSale(ItemType.IRON_HELMET, 500)); - blacksmithItems.put(5, new MerchantItemForSale(ItemType.IRON_CHEST_PLATE, 1500)); - blacksmithItems.put(6, new MerchantItemForSale(ItemType.IRON_LEGGINGS, 1100)); + blacksmithItems.put(1, new MerchantItemForSale(ItemType.BERSERKER_BATON, 1000)); + blacksmithItems.put(2, new MerchantItemForSale(ItemType.BERSEKER_BOOTS, 350)); + blacksmithItems.put(3, new MerchantItemForSale(ItemType.BERSERKER_BRACERS, 350)); + blacksmithItems.put(4, new MerchantItemForSale(ItemType.BERSEKER_HELM, 350)); + blacksmithItems.put(5, new MerchantItemForSale(ItemType.BERSERKER_CHEST, 700)); + blacksmithItems.put(6, new MerchantItemForSale(ItemType.BERSEKER_SHORTS, 850)); blacksmithItems.put(7, new MerchantItemForSale(ItemType.LEATHER_SATCHEL, 600)); Blacksmith blacksmith = new Blacksmith(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), blacksmithItems); diff --git a/src/main/java/com/comandante/creeper/Items/ItemType.java b/src/main/java/com/comandante/creeper/Items/ItemType.java index 075cc2fd08788c15d6eb343a45fb28351baa9b9e..4517d17efd7e1021a145454c6a8b822845ea7c44 100755 --- a/src/main/java/com/comandante/creeper/Items/ItemType.java +++ b/src/main/java/com/comandante/creeper/Items/ItemType.java @@ -37,10 +37,10 @@ public enum ItemType { Rarity.BASIC, 1, Sets.<TimeTracker.TimeOfDay>newHashSet()), - BROAD_SWORD(3, Arrays.asList("sword", "broad", "a broad sword", "the broad sword"), - Color.CYAN + "the broad sword" + Color.RESET, - "an iron broad sword rests upon the ground.", - "an iron broad sword", + BERSERKER_BATON(3, Arrays.asList("baton", "a berserker baton", "b"), + Color.CYAN + "a berserker baton" + Color.RESET, + "a berserker baton rests upon the ground.", + "a berserker baton", false, 0, 60, @@ -48,10 +48,10 @@ public enum ItemType { Rarity.BASIC, 100, Sets.<TimeTracker.TimeOfDay>newHashSet()), - IRON_BOOTS(4, Arrays.asList("boots", "boot", "iron boots"), - Color.CYAN + "iron boots" + Color.RESET, - "a pair of iron boots are here on the ground.", - "a pair of iron boots", + BERSEKER_BOOTS(4, Arrays.asList("boots", "boot", "berserker boots", "b"), + Color.CYAN + "berserker boots" + Color.RESET, + "a pair of berserker boots are here on the ground.", + "a pair of berserker boots", false, 0, 60, @@ -59,10 +59,10 @@ public enum ItemType { Rarity.BASIC, 50, Sets.<TimeTracker.TimeOfDay>newHashSet()), - IRON_CHEST_PLATE(5, Arrays.asList("chest", "iron chest plate", "plate"), - "iron chest plate", - "an iron ches tplate is on the ground.", - "an iron chest plate", + BERSERKER_CHEST(5, Arrays.asList("chest", "berserker chest", "c"), + Color.CYAN + "berserker chest" + Color.RESET, + "a berserker chest is on the ground.", + "a berserker chest", false, 0, 60, @@ -70,21 +70,21 @@ public enum ItemType { Rarity.BASIC, 70, Sets.<TimeTracker.TimeOfDay>newHashSet()), - IRON_LEGGINGS(6, Arrays.asList("leggings", "iron leggings"), - "iron leggings", - "an a pair of iron leggings are here on the ground.", - "an iron pair of leggings", + BERSEKER_SHORTS(6, Arrays.asList("shorts", "berserker shorts", "s"), + Color.CYAN + "berserker shorts" + Color.RESET, + "a pair of berserker shorts are here on the ground.", + "a pair of berserker shorts", false, 0, 60, true, - Rarity.BASIC, + Rarity.UNCOMMON, 80, Sets.<TimeTracker.TimeOfDay>newHashSet()), - IRON_BRACERS(7, Arrays.asList("bracers", "iron bracers"), - "iron bracers", - "an a pair of iron bracers are here on the ground.", - "an iron pair of bracers", + BERSERKER_BRACERS(7, Arrays.asList("bracers", "berserker bracers", "b"), + Color.CYAN + "berserker bracers" + Color.RESET, + "a pair of berserker bracers are here on the ground.", + "a pair of berserker bracers", false, 0, 60, @@ -92,10 +92,10 @@ public enum ItemType { Rarity.BASIC, 40, Sets.<TimeTracker.TimeOfDay>newHashSet()), - IRON_HELMET(8, Arrays.asList("helmet", "iron helmet"), - "iron helmet", - "an iron helmet is on the ground.", - "an iron helmet", + BERSEKER_HELM(8, Arrays.asList("helm", "berserker helm", "h"), + Color.CYAN + "berserker helm" + Color.RESET, + "a berserker helm is on the ground.", + "a berserker helm", false, 0, 60, @@ -128,7 +128,7 @@ public enum ItemType { LEATHER_SATCHEL(11, Arrays.asList("leather satchel", "satchel"), "a " + Color.GREEN + "leather satchel" + Color.RESET, "a " + Color.GREEN + "leather satchel" + Color.RESET, - "a " + Color.GREEN + "leather satchel" + Color.RESET + " with room to store an extra 15 items.", + "a " + Color.GREEN + "leather satchel" + Color.RESET + " (15 items)", false, 0, 60, diff --git a/src/main/java/com/comandante/creeper/Items/Rarity.java b/src/main/java/com/comandante/creeper/Items/Rarity.java index 1f2c737f24457e923c6f1ffbba1dd9238fe617d7..0c58b47ed50a5a6caeccfe0f5ee7061c75595116 100644 --- a/src/main/java/com/comandante/creeper/Items/Rarity.java +++ b/src/main/java/com/comandante/creeper/Items/Rarity.java @@ -3,11 +3,11 @@ package com.comandante.creeper.Items; public enum Rarity { - BASIC("basic", 100.0), - UNCOMMON("uncommon", 17.0), - RARE("rare", 9.0), - LEGENDARY("legendary", 2.0), - EXOTIC("exotic", .05); + BASIC("basic", 2.0), + UNCOMMON("uncommon", 1.2), + RARE("rare", .6), + LEGENDARY("legendary", .2), + EXOTIC("exotic", .01); private final String rarityTypeName; private final double percentToLoot; diff --git a/src/main/java/com/comandante/creeper/player/EquipmentBuilder.java b/src/main/java/com/comandante/creeper/player/EquipmentBuilder.java index 0f61c444a76655c27e163884220b7395107dea90..5ec8b97347f793c0cb51664bb9bb86f24ee59d09 100755 --- a/src/main/java/com/comandante/creeper/player/EquipmentBuilder.java +++ b/src/main/java/com/comandante/creeper/player/EquipmentBuilder.java @@ -3,16 +3,8 @@ package com.comandante.creeper.player; import com.comandante.creeper.Items.Item; import com.comandante.creeper.Items.ItemType; -import com.comandante.creeper.server.Color; -import com.comandante.creeper.spells.Effect; -import com.comandante.creeper.spells.EffectBuilder; import com.comandante.creeper.stat.Stats; import com.comandante.creeper.stat.StatsBuilder; -import com.google.api.client.util.Lists; -import com.google.api.client.util.Sets; - -import java.util.List; -import java.util.Set; public class EquipmentBuilder { @@ -20,18 +12,18 @@ public class EquipmentBuilder { ItemType itemType = ItemType.itemTypeFromCode(item.getItemTypeId()); if (itemType != null) { switch (itemType) { - case BROAD_SWORD: - return getBroadSword(item); - case IRON_BOOTS: - return getIronBoots(item); - case IRON_CHEST_PLATE: - return getIronChestPlate(item); - case IRON_LEGGINGS: - return getIronLeggings(item); - case IRON_BRACERS: - return getIronBracers(item); - case IRON_HELMET: - return getIronHelmet(item); + case BERSERKER_BATON: + return getBerserkerBaton(item); + case BERSEKER_BOOTS: + return getBerserkerBoots(item); + case BERSERKER_CHEST: + return getBerserkerChest(item); + case BERSEKER_SHORTS: + return getBerserkerShorts(item); + case BERSERKER_BRACERS: + return getBerserkerBracers(item); + case BERSEKER_HELM: + return getBerserkerHelm(item); case LEATHER_SATCHEL: return getLeatherSatchel(item); case BIGGERS_SKIN_SATCHEL: @@ -41,43 +33,43 @@ public class EquipmentBuilder { return null; } - public static Item getBroadSword(Item item) { - Stats stats = new StatsBuilder().setStrength(10).createStats(); + public static Item getBerserkerBaton(Item item) { + Stats stats = new StatsBuilder().setWeaponRatingMin(2).setWeaponRatingMax(3).createStats(); final Equipment equipment = new Equipment(EquipmentSlotType.HAND, stats); item.setEquipment(equipment); return item; } - public static Item getIronBoots(Item item) { - Stats stats = new StatsBuilder().setArmorRating(3).createStats(); + public static Item getBerserkerBoots(Item item) { + Stats stats = new StatsBuilder().setArmorRating(1).createStats(); final Equipment equipment = new Equipment(EquipmentSlotType.FEET, stats); item.setEquipment(equipment); return item; } - public static Item getIronChestPlate(Item item) { - Stats stats = new StatsBuilder().setArmorRating(7).createStats(); + public static Item getBerserkerChest(Item item) { + Stats stats = new StatsBuilder().setArmorRating(2).createStats(); final Equipment equipment = new Equipment(EquipmentSlotType.CHEST, stats); item.setEquipment(equipment); return item; } - public static Item getIronLeggings(Item item) { - Stats stats = new StatsBuilder().setArmorRating(5).createStats(); + public static Item getBerserkerShorts(Item item) { + Stats stats = new StatsBuilder().setArmorRating(3).createStats(); final Equipment equipment = new Equipment(EquipmentSlotType.LEGS, stats); item.setEquipment(equipment); return item; } - public static Item getIronBracers(Item item) { - Stats stats = new StatsBuilder().setArmorRating(2).createStats(); + public static Item getBerserkerBracers(Item item) { + Stats stats = new StatsBuilder().setArmorRating(1).createStats(); final Equipment equipment = new Equipment(EquipmentSlotType.WRISTS, stats); item.setEquipment(equipment); return item; } - public static Item getIronHelmet(Item item) { - Stats stats = new StatsBuilder().setArmorRating(4).createStats(); + public static Item getBerserkerHelm(Item item) { + Stats stats = new StatsBuilder().setArmorRating(1).createStats(); final Equipment equipment = new Equipment(EquipmentSlotType.HEAD, stats); item.setEquipment(equipment); return item; diff --git a/src/main/java/com/comandante/creeper/player/PlayerStats.java b/src/main/java/com/comandante/creeper/player/PlayerStats.java index 30b706ddeb80ac83339ea083cb3e4050e95a1f0d..f13ba40e5f2497b18318faa5c9d7d41cf85d1352 100644 --- a/src/main/java/com/comandante/creeper/player/PlayerStats.java +++ b/src/main/java/com/comandante/creeper/player/PlayerStats.java @@ -14,8 +14,8 @@ public class PlayerStats { .setMeleSkill(10) .setCurrentHealth(100) .setMaxHealth(100) - .setWeaponRatingMin(10) - .setWeaponRatingMax(20) + .setWeaponRatingMin(3) + .setWeaponRatingMax(5) .setNumberOfWeaponRolls(1) .setExperience(0) .setCurrentMana(100) diff --git a/src/test/com/comandante/creeper/player/NpcTestHarness.java b/src/test/com/comandante/creeper/player/NpcTestHarness.java index 2c573e1c570497b03c2362ceb7bbc4527bfc4ace..bed2d246ec6b59965d3e8b712e14496edc58547f 100644 --- a/src/test/com/comandante/creeper/player/NpcTestHarness.java +++ b/src/test/com/comandante/creeper/player/NpcTestHarness.java @@ -2,6 +2,8 @@ package com.comandante.creeper.player; import com.comandante.creeper.ConfigureCommands; import com.comandante.creeper.CreeperConfiguration; +import com.comandante.creeper.Items.Item; +import com.comandante.creeper.Items.ItemType; import com.comandante.creeper.Items.ItemUseRegistry; import com.comandante.creeper.Main; import com.comandante.creeper.entity.EntityManager; @@ -18,21 +20,29 @@ import com.comandante.creeper.stat.StatsHelper; import com.comandante.creeper.world.MapsManager; import com.comandante.creeper.world.RoomManager; import com.comandante.creeper.world.WorldExporter; +import com.google.common.collect.Interner; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import org.apache.commons.codec.language.Soundex; import org.apache.commons.configuration.MapConfiguration; import org.jboss.netty.channel.Channel; import org.junit.Before; import org.junit.Test; +import org.mapdb.Atomic; import org.mapdb.DB; import org.mapdb.DBMaker; +import org.nocrala.tools.texttablefmt.BorderStyle; +import org.nocrala.tools.texttablefmt.ShownBorders; +import org.nocrala.tools.texttablefmt.Table; import java.io.FileNotFoundException; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.function.Function; import java.util.stream.Collectors; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; public class NpcTestHarness { @@ -69,39 +79,84 @@ public class NpcTestHarness { public void testCombat() throws Exception { List<Npc> npcsFromFile = NpcExporter.getNpcsFromFile(gameManager); Npc treeBerseker = npcsFromFile.stream().filter(npc -> npc.getName().equals("tree berserker")).collect(Collectors.toList()).get(0); + int totalIterations = 100; + Player player; + Npc npc = null; + Table t = new Table(7, BorderStyle.BLANKS, + ShownBorders.NONE); + t.setColumnWidth(0, 20, 20); + t.setColumnWidth(1, 15, 20); + t.setColumnWidth(2, 16, 16); + t.setColumnWidth(3, 16, 16); + t.setColumnWidth(4, 16, 16); + t.setColumnWidth(5, 16, 16); + //t.setColumnWidth(6, 16, 16); - int playerWins = 0; - int npcWins = 0; + t.addCell("Npc"); + t.addCell("Player Level"); + t.addCell("Player Win Pct"); + t.addCell("Npc Win Pct"); + t.addCell("Avg Rounds"); + t.addCell("Avg Gold"); + t.addCell("Drops"); + //equipment.add(ItemType.BERSEKER_BOOTS.create()); + // equipment.add(ItemType.BERSERKER_BATON.create()); + //equipment.add(ItemType.BERSERKER_CHEST.create()); + //equipment.add(ItemType.BERSEKER_SHORTS.create()); - totalFightRounds = 0; - int totalIterations = 100; - Player player = null; - for (int i = 0; i < totalIterations; i++) { - String username = UUID.randomUUID().toString(); - player = createRandomPlayer(username); - Npc npc = new NpcBuilder(treeBerseker).createNpc(); - gameManager.getEntityManager().addEntity(npc); - player.getCurrentRoom().addPresentNpc(npc.getEntityId()); - player.addActiveFight(npc); - if (conductFight(player, npc)) { - playerWins++; - } else { - npcWins++; - } - player.getCurrentRoom().removePresentNpc(npc.getEntityId()); - entityManager.deleteNpcEntity(npc.getEntityId()); - player.getCurrentRoom().removePresentPlayer(player.getPlayerId()); - if (i%100==0) { - System.out.println("Fight iterations: " + i); + Map<String, AtomicInteger> drops = new HashMap<String, AtomicInteger>(); + int totalGold = 0; + for (int level = 0; level < 10; level++) { + Set<Item> equipment = Sets.newHashSet(); + int playerWins = 0; + int npcWins = 0; + totalFightRounds = 0; + for (int i = 0; i < 100; i++) { + String username = UUID.randomUUID().toString(); + player = createRandomPlayer(username, level); + equipArmor(player, equipment); + npc = new NpcBuilder(treeBerseker).createNpc(); + gameManager.getEntityManager().addEntity(npc); + player.getCurrentRoom().addPresentNpc(npc.getEntityId()); + player.addActiveFight(npc); + if (conductFight(player, npc)) { + playerWins++; + int gold = (int) gameManager.getLootManager().lootGoldAmountReturn(npc.getLoot()); + totalGold =+ gold; + Set<Item> items = gameManager.getLootManager().lootItemsReturn(npc.getLoot()); + items.forEach(item -> { + if (!drops.containsKey(item.getItemName())) { + drops.put(item.getItemName(), new AtomicInteger(1)); + } else { + drops.get(item.getItemName()).incrementAndGet(); + } + }); + } else { + npcWins++; + } + player.getCurrentRoom().removePresentNpc(npc.getEntityId()); + entityManager.deleteNpcEntity(npc.getEntityId()); + player.getCurrentRoom().removePresentPlayer(player.getPlayerId()); } + float playerWinPercent = (playerWins * 100.0f) / totalIterations; + float npcWinPercent = (npcWins * 100.0f) / totalIterations; + t.addCell(npc.getName()); + t.addCell(String.valueOf(level)); + t.addCell(String.valueOf(playerWinPercent)+"%"); + t.addCell(String.valueOf(npcWinPercent)+"%"); + t.addCell(String.valueOf(totalFightRounds / totalIterations)); + t.addCell(String.valueOf(totalGold / totalIterations)); + StringBuilder sb = new StringBuilder(); + drops.entrySet().stream().map(entry -> entry.getKey() + "(" + entry.getValue().get() + ")").forEach(s -> sb.append(s).append(",")); + t.addCell(sb.toString()); } - Stats difference = StatsHelper.getDifference(player.getPlayerStatsWithEquipmentAndLevel(), new PlayerStats().DEFAULT_PLAYER.createStats()); - String player1 = gameManager.buildLookString("player", player.getPlayerStatsWithEquipmentAndLevel(),difference ); - System.out.println(player1); - System.out.println(""); - System.out.println("Player Wins: " + playerWins); - System.out.println("Npc Wins: " + npcWins); - System.out.println("Average rounds: " + totalFightRounds / totalIterations); + System.out.println(t.render()); + + // Stats difference = StatsHelper.getDifference(player.getPlayerStatsWithEquipmentAndLevel(), new PlayerStats().DEFAULT_PLAYER.createStats()); + // String player1 = gameManager.buildLookString("player", player.getPlayerStatsWithEquipmentAndLevel(),difference ); + // System.out.println(player1); + // System.out.println(""); + } private boolean conductFight(Player player, Npc npc) { @@ -123,7 +178,7 @@ public class NpcTestHarness { } } - private Player createRandomPlayer(String username) throws FileNotFoundException { + private Player createRandomPlayer(String username, int level) throws FileNotFoundException { createUser(username, "3333333"); Player player = new Player(username, gameManager); Channel mockChannel = mock(Channel.class); @@ -133,10 +188,18 @@ public class NpcTestHarness { gameManager.getPlayerManager().addPlayer(player); gameManager.placePlayerInLobby(player); gameManager.getPlayerManager().getSessionManager().putSession(creeperSession); - player.addExperience(Levels.getXp(3)); + player.addExperience(Levels.getXp(level)); return player; } + private void equipArmor(Player player, Set<Item> equipment) { + equipment.forEach(item -> { + entityManager.saveItem(item); + gameManager.acquireItem(player, item.getItemId()); + player.equip(item); + }); + } + private void createUser(String username, String password) { PlayerMetadata playerMetadata = new PlayerMetadata(username, password, Main.createPlayerId(username), PlayerStats.DEFAULT_PLAYER.createStats(), 0, Sets.newHashSet(PlayerRole.MORTAL), new String[0], 0, new String[0]); gameManager.getPlayerManager().savePlayerMetadata(playerMetadata); diff --git a/world/npcs/treeberserker.json b/world/npcs/treeberserker.json index 6622f7fe56eea4bce01c5e4d3d985b0e0510486d..cc986f29240845d282a84ed5ada24c727aba3254 100755 --- a/world/npcs/treeberserker.json +++ b/world/npcs/treeberserker.json @@ -6,33 +6,33 @@ "loot": { "lootGoldMin": 7, "lootGoldMax": 14, - "lootItems": [] + "lootItems": [4,6] }, "roamAreas": [ "north1_zone" ], "stats": { - "agile": 2, + "agile": 1, "aim": 1, - "armorRating": 17, - "currentHealth": 100, - "currentMana": 100, + "armorRating": 3, + "currentHealth": 90, + "currentMana": 90, "experience": 22600, - "maxHealth": 150, - "maxMana": 100, + "maxHealth": 90, + "maxMana": 90, "meleSkill": 12, "numberOfWeaponRolls": 1, "strength": 10, - "weaponRatingMax": 15, - "weaponRatingMin": 9, + "weaponRatingMax": 12, + "weaponRatingMin": 7, "willPower": 1 }, "spawnAreas": { "north1_zone": { "randomChance": 100, - "maxPerRoom": 3, + "maxPerRoom": 6, "spawnIntervalTicks": 600, - "maxInstances": 12 + "maxInstances": 24 } }, "validTriggers": [