diff --git a/src/main/java/com/comandante/creeper/ConfigureNpc.java b/src/main/java/com/comandante/creeper/ConfigureNpc.java index ea8febce132b3f6268e82445ad01873cac0a9a6a..6d93d315850b15847d1eebacfcce43bb05d64325 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 baf315a9bf3f08339ad1483fdbfd987c65057178..38d9d96e40ca58ca5fac051850933b7aeca1935b 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 6e9871be3994e7f6a964163209fe5d14c5760e81..c8f89507e9d53921eff29b9e76b37564746f3682 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 0000000000000000000000000000000000000000..4d3c205c1bcf24c1a29ed320b8dee48ca929f968 --- /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 c8236f38cf651d5f7c95bdbba3af87907e73be5a..d2a688618d5ae74bf5bcc1b6f23ea4808a602461 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 b2ef99bb5c92ffecbb50271cbb3537e74f79e166..5e9e3d2ac985cafe2cef852247509c925935c8ca 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 a3ded4048fddac62355cbdb929982a320504198b..7fb1b00f930b669dd871860d2e4d43b7005524c2 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 44004e8ad0f3137e8a051dea1ac6b4c2288150b7..8ed7a3b16b8690e58ff8c083b1622d77a4f91554 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 b9fc556bf337c1cb1f70c6d188b9d2cbc3f30412..c2f5af11a67abb5e6637abbb64e7b10d5caa0bde 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 b89c3acd7c13ad7595d16aee9013033673a88468..f702e299525961f3dacdadf8a4a2247c8eeddd60 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 1b4ad8b1189653c20adfa7700b67ae735139a5ac..e393bc683287f06c14f1def2ee410ebe16004107 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); } + }