From 87266346026c50f4d12088a48499c80c77462b4c Mon Sep 17 00:00:00 2001 From: Chris Kearney <chris@kearneymail.com> Date: Wed, 3 Aug 2016 21:47:43 -0700 Subject: [PATCH] spellbooks --- .../com/comandante/creeper/ConfigureNpc.java | 4 +- .../comandante/creeper/Items/ItemType.java | 13 ++++- .../creeper/Items/ItemUseRegistry.java | 4 ++ .../use/LightningSpellBookUseAction.java | 50 +++++++++++++++++++ .../creeper/command/CastCommand.java | 6 +-- .../managers/NewUserRegistrationManager.java | 2 +- .../com/comandante/creeper/player/Player.java | 43 ++++++++++++---- .../creeper/player/PlayerMetadata.java | 32 +++++++++++- .../creeper/spells/LightningSpell.java | 2 +- .../com/comandante/creeper/spells/Spell.java | 1 - ...egistry.java => SpellTriggerRegistry.java} | 5 +- 11 files changed, 142 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/comandante/creeper/Items/use/LightningSpellBookUseAction.java rename src/main/java/com/comandante/creeper/spells/{SpellRegistry.java => SpellTriggerRegistry.java} (79%) diff --git a/src/main/java/com/comandante/creeper/ConfigureNpc.java b/src/main/java/com/comandante/creeper/ConfigureNpc.java index ea8febce..6d93d315 100755 --- a/src/main/java/com/comandante/creeper/ConfigureNpc.java +++ b/src/main/java/com/comandante/creeper/ConfigureNpc.java @@ -4,7 +4,6 @@ import com.comandante.creeper.Items.*; import com.comandante.creeper.entity.EntityManager; import com.comandante.creeper.managers.GameManager; import com.comandante.creeper.merchant.*; -import com.comandante.creeper.merchant.GrimulfWizard; import com.comandante.creeper.npc.Npc; import com.comandante.creeper.npc.NpcExporter; import com.comandante.creeper.spawner.ItemSpawner; @@ -72,6 +71,7 @@ public class ConfigureNpc { 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(7, new MerchantItemForSale(ItemType.LIGHTNING_SPELLBOOKNG, 1100)); Blacksmith blacksmith = new Blacksmith(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), blacksmithItems); gameManager.getRoomManager().addMerchant(66, blacksmith); @@ -96,6 +96,6 @@ public class ConfigureNpc { gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE2_ZONE, marijuanaForageBuilder); gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE1_ZONE, marijuanaForageBuilder); - SpellRegistry.addSpell(new LightningSpell(gameManager)); + SpellTriggerRegistry.addSpell(new LightningSpell(gameManager)); } } diff --git a/src/main/java/com/comandante/creeper/Items/ItemType.java b/src/main/java/com/comandante/creeper/Items/ItemType.java index baf315a9..38d9d96e 100755 --- a/src/main/java/com/comandante/creeper/Items/ItemType.java +++ b/src/main/java/com/comandante/creeper/Items/ItemType.java @@ -145,7 +145,18 @@ public enum ItemType { 60, true, Rarity.BASIC, - 3000, Sets.<TimeTracker.TimeOfDay>newHashSet()); + 3000, Sets.<TimeTracker.TimeOfDay>newHashSet()), + + LIGHTNING_SPELLBOOKNG(13, Arrays.asList("lightning book", "lightning spell book", "book", "spell book"), + "a " + Color.YELLOW + "lightning" + Color.RESET + " spell book." + Color.RESET, + "a " + Color.YELLOW + "lightning" + Color.RESET + " spell book." + Color.RESET, + "a " + Color.YELLOW + "lightning" + Color.RESET + " spell book." + Color.RESET, + true, + 0, + 60, + false, + Rarity.RARE, + 3000, Sets.<TimeTracker.TimeOfDay>newHashSet()),; private final Integer itemTypeCode; diff --git a/src/main/java/com/comandante/creeper/Items/ItemUseRegistry.java b/src/main/java/com/comandante/creeper/Items/ItemUseRegistry.java index 6e9871be..c8f89507 100644 --- a/src/main/java/com/comandante/creeper/Items/ItemUseRegistry.java +++ b/src/main/java/com/comandante/creeper/Items/ItemUseRegistry.java @@ -2,6 +2,7 @@ package com.comandante.creeper.Items; import com.comandante.creeper.Items.use.DefaultApplyStatsAction; import com.comandante.creeper.Items.use.DirtyBombUseAction; +import com.comandante.creeper.Items.use.LightningSpellBookUseAction; import com.comandante.creeper.Items.use.ResetAllEffectsUseAction; import com.comandante.creeper.managers.GameManager; import com.comandante.creeper.player.Player; @@ -38,6 +39,9 @@ public class ItemUseRegistry { //Marijuana addItemUseAction(new DefaultApplyStatsAction(ItemType.MARIJUANA, buildStats(500,500), Sets.<Effect>newHashSet())); + + //Lightning Spellbook + addItemUseAction(new LightningSpellBookUseAction(ItemType.LIGHTNING_SPELLBOOKNG)); } private static Stats buildStats(int health, int mana) { diff --git a/src/main/java/com/comandante/creeper/Items/use/LightningSpellBookUseAction.java b/src/main/java/com/comandante/creeper/Items/use/LightningSpellBookUseAction.java new file mode 100644 index 00000000..4d3c205c --- /dev/null +++ b/src/main/java/com/comandante/creeper/Items/use/LightningSpellBookUseAction.java @@ -0,0 +1,50 @@ +package com.comandante.creeper.Items.use; + +import com.comandante.creeper.Items.Item; +import com.comandante.creeper.Items.ItemType; +import com.comandante.creeper.Items.ItemUseAction; +import com.comandante.creeper.managers.GameManager; +import com.comandante.creeper.npc.Npc; +import com.comandante.creeper.npc.NpcStatsChangeBuilder; +import com.comandante.creeper.player.Player; +import com.comandante.creeper.server.Color; +import com.comandante.creeper.spells.Effect; +import com.comandante.creeper.spells.LightningSpell; +import com.comandante.creeper.stat.StatsBuilder; +import com.comandante.creeper.world.Room; + +import java.text.NumberFormat; +import java.util.Arrays; +import java.util.Locale; +import java.util.Set; + +public class LightningSpellBookUseAction implements ItemUseAction { + + private final ItemType itemType; + + public LightningSpellBookUseAction(ItemType itemType) { + this.itemType = itemType; + } + + @Override + public Integer getItemTypeId() { + return itemType.getItemTypeCode(); + } + + @Override + public void executeAction(GameManager gameManager, Player player, Item item) { + gameManager.writeToPlayerCurrentRoom(player.getPlayerId(), player.getPlayerName() + " reads a leatherbound aging spell book and gains knowledge about lightning spells."); + player.addLearnedSpellByName(LightningSpell.NAME); + } + + @Override + public void postExecuteAction(GameManager gameManager, Player player, Item item) { + player.removeInventoryId(item.getItemId()); + gameManager.getEntityManager().removeItem(item); + } + + @Override + public Set<Effect> getEffects() { + return null; + } +} diff --git a/src/main/java/com/comandante/creeper/command/CastCommand.java b/src/main/java/com/comandante/creeper/command/CastCommand.java index c8236f38..d2a68861 100644 --- a/src/main/java/com/comandante/creeper/command/CastCommand.java +++ b/src/main/java/com/comandante/creeper/command/CastCommand.java @@ -6,7 +6,7 @@ import com.comandante.creeper.npc.Npc; import com.comandante.creeper.player.CoolDownType; import com.comandante.creeper.player.Player; import com.comandante.creeper.spells.Spell; -import com.comandante.creeper.spells.SpellRegistry; +import com.comandante.creeper.spells.SpellTriggerRegistry; import com.google.common.base.Joiner; import com.google.common.collect.Sets; import org.jboss.netty.channel.ChannelHandlerContext; @@ -42,8 +42,8 @@ public class CastCommand extends Command { return; } String desiredSpellName = originalMessageParts.get(1); - Spell spell = SpellRegistry.getSpell(desiredSpellName); - if (spell == null) { + Spell spell = SpellTriggerRegistry.getSpell(desiredSpellName); + if (spell == null || !player.doesHaveSpellLearned(spell.getSpellName())) { write("No spell found with the name: " + desiredSpellName + "\r\n"); return; } diff --git a/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java b/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java index b2ef99bb..5e9e3d2a 100644 --- a/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java +++ b/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java @@ -63,7 +63,7 @@ public class NewUserRegistrationManager { return; } session.setPassword(Optional.of(password)); - PlayerMetadata playerMetadata = new PlayerMetadata(session.getUsername().get(), session.getPassword().get(), Main.createPlayerId(session.getUsername().get()), PlayerStats.DEFAULT_PLAYER.createStats(), 0, Sets.newHashSet(PlayerRole.MORTAL), new String[0], 0); + PlayerMetadata playerMetadata = new PlayerMetadata(session.getUsername().get(), session.getPassword().get(), Main.createPlayerId(session.getUsername().get()), PlayerStats.DEFAULT_PLAYER.createStats(), 0, Sets.newHashSet(PlayerRole.MORTAL), new String[0], 0, new String[0]); playerManager.savePlayerMetadata(playerMetadata); e.getChannel().write("User created.\r\n"); session.setState(CreeperSession.State.newUserRegCompleted); diff --git a/src/main/java/com/comandante/creeper/player/Player.java b/src/main/java/com/comandante/creeper/player/Player.java index a3ded404..7fb1b00f 100755 --- a/src/main/java/com/comandante/creeper/player/Player.java +++ b/src/main/java/com/comandante/creeper/player/Player.java @@ -290,8 +290,8 @@ public class Player extends CreeperEntity { } } - public void resetEffects(){ - synchronized (interner){ + public void resetEffects() { + synchronized (interner) { PlayerMetadata playerMetadata = getPlayerMetadata(); playerMetadata.resetEffects(); gameManager.getPlayerManager().savePlayerMetadata(playerMetadata); @@ -314,6 +314,31 @@ public class Player extends CreeperEntity { } } + public void addLearnedSpellByName(String spellName) { + synchronized (interner.intern(playerId)) { + PlayerMetadata playerMetadata = getPlayerMetadata(); + playerMetadata.addLearnedSpellByName(spellName); + savePlayerMetadata(playerMetadata); + } + } + + public boolean doesHaveSpellLearned(String spellName) { + PlayerMetadata playerMetadata = getPlayerMetadata(); + if (playerMetadata.getLearnedSpells() == null || playerMetadata.getLearnedSpells().length == 0) { + return false; + } + List<String> learnedSpells = Arrays.asList(playerMetadata.getLearnedSpells()); + return learnedSpells.contains(spellName); + } + + public void removeLearnedSpellByName(String spellName) { + synchronized (interner.intern(playerId)) { + PlayerMetadata playerMetadata = getPlayerMetadata(); + playerMetadata.removeLearnedSpellByName(spellName); + savePlayerMetadata(playerMetadata); + } + } + public void addEquipmentId(String equipmentId) { synchronized (interner.intern(playerId)) { PlayerMetadata playerMetadata = getPlayerMetadata(); @@ -936,18 +961,18 @@ public class Player extends CreeperEntity { } if (damageToVictim > 0) { if (randInt(0, 100) > 95) { - final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + Color.YELLOW + "The " + npc.getColorName() + " was caught off guard by the attack!" + "+" + NumberFormat.getNumberInstance(Locale.US).format(damageToVictim) + Color.RESET + Color.BOLD_ON + Color.RED + " DAMAGE" + Color.RESET + " done to " + npc.getColorName(); - npcStatsChangeBuilder.setStats(new StatsBuilder().setCurrentHealth(-(damageToVictim*3)).createStats()); - npcStatsChangeBuilder.setDamageStrings(Arrays.asList(fightMsg)); + final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + Color.YELLOW + "The " + npc.getColorName() + " was caught off guard by the attack!" + "+" + NumberFormat.getNumberInstance(Locale.US).format(damageToVictim) + Color.RESET + Color.BOLD_ON + Color.RED + " DAMAGE" + Color.RESET + " done to " + npc.getColorName(); + npcStatsChangeBuilder.setStats(new StatsBuilder().setCurrentHealth(-(damageToVictim * 3)).createStats()); + npcStatsChangeBuilder.setDamageStrings(Collections.singletonList(fightMsg)); } else { final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + Color.YELLOW + "+" + NumberFormat.getNumberInstance(Locale.US).format(damageToVictim) + Color.RESET + Color.BOLD_ON + Color.RED + " DAMAGE" + Color.RESET + " done to " + npc.getColorName(); npcStatsChangeBuilder.setStats(new StatsBuilder().setCurrentHealth(-damageToVictim).createStats()); - npcStatsChangeBuilder.setDamageStrings(Arrays.asList(fightMsg)); + npcStatsChangeBuilder.setDamageStrings(Collections.singletonList(fightMsg)); } } else { final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + "You MISS " + npc.getName() + "!"; npcStatsChangeBuilder.setStats(new StatsBuilder().setCurrentHealth(-damageToVictim).createStats()); - npcStatsChangeBuilder.setDamageStrings(Arrays.asList(fightMsg)); + npcStatsChangeBuilder.setDamageStrings(Collections.singletonList(fightMsg)); } } if (this.doesActiveFightExist(npc)) { @@ -956,12 +981,12 @@ public class Player extends CreeperEntity { if (randInt(0, 100) < chanceToHitBack) { final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + npc.getColorName() + Color.BOLD_ON + Color.RED + " DAMAGES" + Color.RESET + " you for " + Color.RED + "-" + NumberFormat.getNumberInstance(Locale.US).format(damageBack) + Color.RESET; npcStatsChangeBuilder.setPlayerStatsChange(new StatsBuilder().setCurrentHealth(-damageBack).createStats()); - npcStatsChangeBuilder.setPlayerDamageStrings(Arrays.asList(fightMsg)); + npcStatsChangeBuilder.setPlayerDamageStrings(Collections.singletonList(fightMsg)); } else { final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + npc.getColorName() + Color.BOLD_ON + Color.CYAN + " MISSES" + Color.RESET + " you!"; npcStatsChangeBuilder.setPlayerStatsChange(new StatsBuilder().setCurrentHealth(0).createStats()); - npcStatsChangeBuilder.setPlayerDamageStrings(Arrays.asList(fightMsg)); + npcStatsChangeBuilder.setPlayerDamageStrings(Collections.singletonList(fightMsg)); } npc.addNpcDamage(npcStatsChangeBuilder.createNpcStatsChange()); } diff --git a/src/main/java/com/comandante/creeper/player/PlayerMetadata.java b/src/main/java/com/comandante/creeper/player/PlayerMetadata.java index 44004e8a..8ed7a3b1 100644 --- a/src/main/java/com/comandante/creeper/player/PlayerMetadata.java +++ b/src/main/java/com/comandante/creeper/player/PlayerMetadata.java @@ -24,8 +24,9 @@ public class PlayerMetadata implements Serializable { private List<String> effects; private boolean isMarkedForDelete; private Map<String, String> playerSettings; + private String[] learnedSpells; - public PlayerMetadata(String playerName, String password, String playerId, Stats stats, int gold, Set<PlayerRole> playerRoleSet, String[] playerEquipment, int goldInBank) { + public PlayerMetadata(String playerName, String password, String playerId, Stats stats, int gold, Set<PlayerRole> playerRoleSet, String[] playerEquipment, int goldInBank, String[] learnedSpells) { this.playerName = playerName; this.password = password; this.playerId = playerId; @@ -34,6 +35,7 @@ public class PlayerMetadata implements Serializable { this.playerRoleSet = playerRoleSet; this.playerEquipment = playerEquipment; this.goldInBank = goldInBank; + this.learnedSpells = learnedSpells; } public PlayerMetadata(PlayerMetadata playerMetadata) { @@ -61,6 +63,9 @@ public class PlayerMetadata implements Serializable { if (playerMetadata.playerSettings != null) { this.playerSettings = new HashMap<String, String>(playerMetadata.getPlayerSettings()); } + if (playerMetadata.learnedSpells != null) { + this.learnedSpells = Arrays.copyOf(playerMetadata.learnedSpells, playerMetadata.learnedSpells.length); + } this.isMarkedForDelete = new Boolean(playerMetadata.isMarkedForDelete); } @@ -101,6 +106,27 @@ public class PlayerMetadata implements Serializable { inventory.remove(itemId); } + protected void addLearnedSpellByName(String spellName) { + if (learnedSpells == null) { + learnedSpells = new String[0]; + } + String[] result = Arrays.copyOf(learnedSpells, learnedSpells.length + 1); + result[learnedSpells.length] = spellName; + this.learnedSpells = result; + } + + protected void removeLearnedSpellByName(String spellName) { + List<String> learnedSpellsKeep = new ArrayList<String>(Arrays.asList(learnedSpells)); + learnedSpellsKeep.remove(spellName); + String[] newSpells = new String[learnedSpellsKeep.size()]; + int i = 0; + for (String id : learnedSpellsKeep) { + newSpells[i] = id; + i++; + } + this.learnedSpells = newSpells; + } + protected void addEquipmentEntityId(String equipmentItemId) { if (playerEquipment == null) { playerEquipment = new String[0]; @@ -161,6 +187,10 @@ public class PlayerMetadata implements Serializable { return goldInBank; } + public String[] getLearnedSpells() { + return learnedSpells; + } + protected void setGold(long amt) { this.gold = amt; } diff --git a/src/main/java/com/comandante/creeper/spells/LightningSpell.java b/src/main/java/com/comandante/creeper/spells/LightningSpell.java index b9fc556b..c2f5af11 100644 --- a/src/main/java/com/comandante/creeper/spells/LightningSpell.java +++ b/src/main/java/com/comandante/creeper/spells/LightningSpell.java @@ -18,7 +18,7 @@ import static com.comandante.creeper.server.Color.BOLD_ON; public class LightningSpell extends Spell { - private final static String NAME = BOLD_ON + Color.YELLOW + "lightning" + Color.RESET + " bolt"; + public final static String NAME = BOLD_ON + Color.YELLOW + "lightning" + Color.RESET + " bolt"; private final static String DESCRIPTION = "A powerful bolt of lightning."; private final static Set<String> validTriggers = new HashSet<String>(Arrays.asList(new String[] {"lightning", "lightning bolt", "l", NAME} diff --git a/src/main/java/com/comandante/creeper/spells/Spell.java b/src/main/java/com/comandante/creeper/spells/Spell.java index b89c3acd..f702e299 100644 --- a/src/main/java/com/comandante/creeper/spells/Spell.java +++ b/src/main/java/com/comandante/creeper/spells/Spell.java @@ -247,5 +247,4 @@ public abstract class Spell { interface SpellExecute { public void executeNpc(GameManager gameManager, Npc npc, Player player); } - } diff --git a/src/main/java/com/comandante/creeper/spells/SpellRegistry.java b/src/main/java/com/comandante/creeper/spells/SpellTriggerRegistry.java similarity index 79% rename from src/main/java/com/comandante/creeper/spells/SpellRegistry.java rename to src/main/java/com/comandante/creeper/spells/SpellTriggerRegistry.java index 1b4ad8b1..e393bc68 100644 --- a/src/main/java/com/comandante/creeper/spells/SpellRegistry.java +++ b/src/main/java/com/comandante/creeper/spells/SpellTriggerRegistry.java @@ -5,9 +5,11 @@ import com.google.common.collect.Maps; import java.util.Map; -public class SpellRegistry { +public class SpellTriggerRegistry { public static final Map<String, Spell> spellMap = Maps.newHashMap(); + public static final Map<String, Spell> spellNameMap = Maps.newHashMap(); + public static void addSpell(Spell spell) { for (String trigger : spell.getValidTriggers()) { @@ -18,4 +20,5 @@ public class SpellRegistry { public static Spell getSpell(String trigger) { return spellMap.get(trigger); } + } -- GitLab