diff --git a/Server/src/main/content/global/bots/FletchingBankstander.kt b/Server/src/main/content/global/bots/FletchingBankstander.kt index 201dd6f00..dd60a4e3c 100644 --- a/Server/src/main/content/global/bots/FletchingBankstander.kt +++ b/Server/src/main/content/global/bots/FletchingBankstander.kt @@ -1,12 +1,12 @@ package content.global.bots +import content.global.skill.fletching.log.LogCraftInfo +import content.global.skill.fletching.log.CraftItemWithLogScript +import core.game.bots.Script +import core.game.bots.SkillingBotAssembler import core.game.node.entity.skill.Skills -import content.global.skill.fletching.Fletching -import content.global.skill.fletching.FletchingPulse import core.game.node.item.Item import org.rs09.consts.Items -import core.game.bots.SkillingBotAssembler -import core.game.bots.Script class FletchingBankstander : Script(){ var state = State.FLETCHING @@ -17,7 +17,7 @@ class FletchingBankstander : Script(){ State.FLETCHING -> { bot.inventory.add(Item(Items.KNIFE_946)) bot.inventory.add(Item(Items.LOGS_1511,27)) - bot.pulseManager.run(FletchingPulse(bot, Item(Items.LOGS_1511),27, Fletching.FletchingItems.ARROW_SHAFT)) + CraftItemWithLogScript(bot, LogCraftInfo.ARROW_SHAFT, 27).invoke() State.BANKING } diff --git a/Server/src/main/content/global/skill/crafting/PotteryPlugin.java b/Server/src/main/content/global/skill/crafting/PotteryPlugin.java index f7fa44e3a..23ddac860 100644 --- a/Server/src/main/content/global/skill/crafting/PotteryPlugin.java +++ b/Server/src/main/content/global/skill/crafting/PotteryPlugin.java @@ -56,7 +56,7 @@ public final class PotteryPlugin extends UseWithHandler { @Override public boolean handle(final NodeUsageEvent event) { final Player player = event.getPlayer(); - new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getPottery(false)) { + new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, getPottery(false)) { @Override public void create(final int amount, int index) { @@ -145,7 +145,7 @@ public final class PotteryPlugin extends UseWithHandler { * @return the dialogue handler. */ public SkillDialogueHandler getSkillHandler(final Player player) { - return new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getPottery(true)) { + return new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, getPottery(true)) { @Override public void create(final int amount, final int index) { diff --git a/Server/src/main/content/global/skill/crafting/SnakeSkinPlugin.java b/Server/src/main/content/global/skill/crafting/SnakeSkinPlugin.java index f4929248e..09c2ed605 100644 --- a/Server/src/main/content/global/skill/crafting/SnakeSkinPlugin.java +++ b/Server/src/main/content/global/skill/crafting/SnakeSkinPlugin.java @@ -34,7 +34,7 @@ public class SnakeSkinPlugin extends UseWithHandler { @Override public boolean handle(final NodeUsageEvent event) { final Player player = event.getPlayer(); - new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getSkins()) { + new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, getSkins()) { @Override public void create(final int amount, int index) { diff --git a/Server/src/main/content/global/skill/fletching/AchievementDiaryAttributeKeys.kt b/Server/src/main/content/global/skill/fletching/AchievementDiaryAttributeKeys.kt new file mode 100644 index 000000000..8e3d7fe33 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/AchievementDiaryAttributeKeys.kt @@ -0,0 +1,8 @@ +package content.global.skill.fletching + +object AchievementDiaryAttributeKeys { + /** + * This attribute signifies that the fletch of the magic shortbow is complete which is the first stage of getting the achievement + */ + const val FLETCHED_UNSTRUNG_MAGIC_SHORTBOW = "diary:seers:fletch-magic-short-bow" +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/Feathers.kt b/Server/src/main/content/global/skill/fletching/Feathers.kt new file mode 100644 index 000000000..f76b00a72 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/Feathers.kt @@ -0,0 +1,16 @@ +package content.global.skill.fletching + +import org.rs09.consts.Items + +object Feathers { + val all = intArrayOf( + Items.FEATHER_314, + Items.STRIPY_FEATHER_10087, + Items.RED_FEATHER_10088, + Items.BLUE_FEATHER_10089, + Items.YELLOW_FEATHER_10090, + Items.ORANGE_FEATHER_10091 + ) + + const val STANDARD = Items.FEATHER_314 +} diff --git a/Server/src/main/content/global/skill/fletching/Fletching.java b/Server/src/main/content/global/skill/fletching/Fletching.java deleted file mode 100644 index 3a6c6906e..000000000 --- a/Server/src/main/content/global/skill/fletching/Fletching.java +++ /dev/null @@ -1,355 +0,0 @@ -package content.global.skill.fletching; - -import core.game.node.item.Item; -import core.game.world.update.flag.context.Animation; - -import java.util.HashMap; -public class Fletching { - public static HashMaplogMap = new HashMap<>(); - public static HashMap boltMap = new HashMap<>(); - public static HashMap dartMap = new HashMap<>(); - public static HashMap arrowHeadMap = new HashMap<>(); - public static HashMap gemMap = new HashMap<>(); - public static HashMap tipMap = new HashMap<>(); - public static HashMap stringMap = new HashMap<>(); - public static HashMap limbMap = new HashMap<>(); - static{ - Items[] itemsArray = Items.values(); - int thisLength = itemsArray.length; - for(int x = 0; x < thisLength; x++){ - Items item = itemsArray[x]; - logMap.putIfAbsent(item.id, item.items); - } - Bolts[] boltArray = Bolts.values(); - thisLength = boltArray.length; - for(int x = 0; x < thisLength; x++){ - Bolts bolt = boltArray[x]; - boltMap.putIfAbsent(bolt.unfinished,bolt); - } - Darts[] dartArray = Darts.values(); - thisLength = dartArray.length; - for(int x = 0; x < thisLength; x++){ - Darts dart = dartArray[x]; - dartMap.putIfAbsent(dart.unfinished,dart); - } - ArrowHeads[] ahArray = ArrowHeads.values(); - thisLength = ahArray.length; - for(int x = 0; x < thisLength; x++){ - ArrowHeads arrowhead = ahArray[x]; - arrowHeadMap.putIfAbsent(arrowhead.unfinished,arrowhead); - } - GemBolts[] gbArray = GemBolts.values(); - thisLength = gbArray.length; - for(int x = 0; x < thisLength; x++){ - GemBolts gem = gbArray[x]; - gemMap.putIfAbsent(gem.gem,gem); - tipMap.putIfAbsent(gem.tip,gem); - } - String[] stringArray = String.values(); - thisLength = stringArray.length; - for(int x = 0; x < thisLength; x++){ - String bow = stringArray[x]; - stringMap.putIfAbsent(bow.unfinished,bow); - } - Limb[] limbsArray = Limb.values(); - thisLength = limbsArray.length; - for(int x = 0; x < thisLength; x++){ - Limb limb = limbsArray[x]; - limbMap.putIfAbsent(limb.stock, limb); - } - } - public static FletchingItems[] getEntries(int id){ - return logMap.get(id); - } - public static boolean isLog(int id){ - return logMap.get(id) != null; - } - public static boolean isBolt(int id){ - return boltMap.get(id) != null; - } - public static boolean isDart(int id){ - return dartMap.get(id) != null; - } - public static boolean isArrowHead(int id){ - return arrowHeadMap.get(id) != null; - } - public static boolean isGemTip(int id){ - return tipMap.get(id) != null; - } - public static Item[] getItems(int id){ - FletchingItems[] entry = getEntries(id); - Item items[] = {}; - switch(entry.length){ - case 1: - items = new Item[] {new Item(entry[0].id)}; - break; - case 2: - items = new Item[] {new Item(entry[0].id), new Item(entry[1].id)}; - break; - case 3: - items = new Item[] {new Item(entry[0].id), new Item(entry[1].id), new Item(entry[2].id)}; - break; - case 4: - items = new Item[] {new Item(entry[0].id), new Item(entry[1].id), new Item(entry[2].id), new Item(entry[3].id)}; - break; - } - return items; - } - public enum Limb { - WOODEN_STOCK(9440,9420,9454,9, 12, new Animation(4436)), - OAK_STOCK(9442,9422,9456,24, 32, new Animation(4437)), - WILLOW_STOCK(9444,9423,9457,39, 44, new Animation(4438)), - TEAK_STOCK(9446,9425,9459,46, 54, new Animation(4439)), - MAPLE_STOCK(9448,9427,9461,54, 64, new Animation(4440)), - MAHOGANY_STOCK(9450,9429,9463,61, 82, new Animation(4441)), - YEW_STOCK(9452,9431,9465,69, 100, new Animation(4442)); - - - public int stock, limb, product,level; - public double experience; - public Animation animation; - - Limb(int stock, int limb, int product, int level, double experience, Animation animation) { - this.stock = stock; - this.limb = limb; - this.product = product; - this.level = level; - this.experience = experience; - this.animation = animation; - } - } - public enum String{ - //Bows - SHORT_BOW((byte) 1,50,841,5, 5, new Animation(6678)), - LONG_BOW((byte) 1,48,839,10, 10, new Animation(6684)), - OAK_SHORTBOW((byte) 1,54,843,20, 16.5, new Animation(6679)), - OAK_LONGBOW((byte) 1,56,845,25, 25, new Animation(6685)), - WILLOW_SHORTBOW((byte) 1,60,849,35, 33.3, new Animation(6680)), - WILLOW_LONGBOW((byte) 1,58,847,40, 41.5, new Animation(6686)), - MAPLE_SHORTBOW((byte) 1,64,853,50, 50, new Animation(6681)), - MAPLE_LONGBOW((byte) 1,62,851,55, 58.3, new Animation(6687)), - YEW_SHORTBOW((byte) 1,68,857,65, 67.5, new Animation(6682)), - YEW_LONGBOW((byte) 1,66,855,70, 75, new Animation(6688)), - MAGIC_SHORTBOW((byte) 1,72,861,80, 83.3, new Animation(6683)), - MAGIC_LONGBOW((byte) 1,70,859,85, 91.5, new Animation(6689)), - OGRE_COMP_BOW((byte) 1,4825,4827,30, 45, new Animation(-1)), - - //crossbows - BRONZE_CBOW((byte) 2,9454,9174,9, 6, new Animation(6671)), - BLURITE_CBOW((byte) 2,9456,9176,24, 16, new Animation(6672)), - IRON_CBOW((byte) 2,9457,9177,39, 22, new Animation(6673)), - STEEL_CBOW((byte) 2,9459,9179,46, 27, new Animation(6674)), - MITHIRIL_CBOW((byte) 2,9461,9181,54, 32, new Animation(6675)), - ADAMANT_CBOW((byte) 2,9463,9183,61, 41, new Animation(6676)), - RUNITE_CBOW((byte) 2,9465,9185,69, 50, new Animation(6677)); - - - public int unfinished,product,string,level; - public final double experience; - public final Animation animation; - String(byte indicator, final int unfinished, final int product, final int level, final double experience, final Animation animation) { - this.unfinished = unfinished; - this.product = product; - this.level = level; - this.experience = experience; - this.animation = animation; - switch(indicator & 0xFF){ - case 1: - this.string = org.rs09.consts.Items.BOW_STRING_1777; - break; - case 2: - this.string = org.rs09.consts.Items.CROSSBOW_STRING_9438; - break; - default: - break; - } - } - } - public enum GemBolts { - OPAL(877, org.rs09.consts.Items.OPAL_1609, 45, 879, 11, 1.6), - PEARL(9140, org.rs09.consts.Items.OYSTER_PEARL_411, 46, 880, 41, 3.2), - PEARLS(9140, org.rs09.consts.Items.OYSTER_PEARLS_413, 46, 880, 41, 3.2), - JADE(9139, org.rs09.consts.Items.JADE_1611, 9187, 9335, 26, 2.4), - RED_TOPAZ(9141, org.rs09.consts.Items.RED_TOPAZ_1613, 9188, 9336, 48, 3.9), - SAPPHIRE(9142, org.rs09.consts.Items.SAPPHIRE_1607, 9189, 9337, 56, 4.7), - EMERALD(9142, org.rs09.consts.Items.EMERALD_1605, 9190, 9338, 58, 5.5), - RUBY(9143, org.rs09.consts.Items.RUBY_1603, 9191, 9339, 63, 6.3), - DIAMOND(9143, org.rs09.consts.Items.DIAMOND_1601, 9192, 9340, 65, 7), - DRAGONSTONE(9144, org.rs09.consts.Items.DRAGONSTONE_1615, 9193, 9341, 71, 8.2), - ONYX(9144, org.rs09.consts.Items.ONYX_6573, 9194, 9342, 73, 9.4); - - public int gem,tip,base,product,level; - public double experience; - GemBolts(int base, int gem, int tip, int product, int level, double experience){ - this.gem = gem; - this.tip = tip; - this.base = base; - this.product = product; - this.level = level; - this.experience = experience; - } - - } - public enum ArrowHeads { - BRONZE_ARROW(39, 882, 1, 1.3), - IRON_ARROW(40, 884, 15, 2.5), - STEEL_ARROW(41, 886, 30, 5), - MITHRIL_ARROW(42, 888, 45, 7.5), - ADAMANT_ARROW(43, 890, 60, 10), - RUNE_ARROW(44, 892, 75, 12.5), - DRAGON_ARROW(11237, 11212, 90, 15), - BROAD_ARROW(13278, 4160, 52, 15); - - public int unfinished,finished,level; - public double experience; - ArrowHeads(int unfinished, int finished, int level, double experience){ - this.unfinished = unfinished; - this.finished = finished; - this.level = level; - this.experience = experience; - } - public Item getFinished(){ - return new Item(finished); - } - public Item getUnfinished(){ - return new Item(unfinished); - } - } - public enum Darts{ - BRONZE_DART(819, 806, 1, 1.8), - IRON_DART(820, 807, 22, 3.8), - STEEL_DART(821, 808, 37, 7.5), - MITHRIL_DART(822, 809, 52, 11.2), - ADAMANT_DART(823, 810, 67, 15), - RUNE_DART(824, 811, 81, 18.8), - DRAGON_DART(11232, 11230, 95, 25); - - public int unfinished, finished, level; - public double experience; - Darts(int unfinished, int finished, int level, double experience){ - this.unfinished = unfinished; - this.finished = finished; - this.level = level; - this.experience = experience; - } - public Item getFinished(){ - return new Item(finished); - } - public Item getUnfinished(){ - return new Item(unfinished); - } - } - public enum Bolts{ - BRONZE_BOLT(9375, 877, 9, 0.5), - BLURITE_BOLT(9376, 9139, 24, 1), - IRON_BOLT(9377, 9140, 39, 1.5), - SILVER_BOLT(9382, 9145, 43, 2.5), - STEEL_BOLT(9378, 9141, 46, 3.5), - MITHRIL_BOLT(9379, 9142, 54, 5), - ADAMANTITE_BOLT(9380, 9143, 61, 7), - RUNITE_BOLT(9381, 9144, 69, 10), - BROAD_BOLT(13279, 13280, 55, 3); - - public int unfinished, finished, level; - public double experience; - Bolts(int unfinished, int finished, int level, double experience){ - this.unfinished = unfinished; - this.finished = finished; - this.level = level; - this.experience = experience; - } - public Item getFinished(){ - return new Item(finished); - } - public Item getUnfinished(){ - return new Item(unfinished); - } - } - private enum Items{ - STANDARD(1511,FletchingItems.ARROW_SHAFT, FletchingItems.SHORT_BOW, FletchingItems.LONG_BOW, FletchingItems.WOODEN_STOCK), - ACHEY(2862, FletchingItems.OGRE_ARROW_SHAFT, FletchingItems.OGRE_COMP_BOW), - OAK(1521, FletchingItems.OAK_SHORTBOW, FletchingItems.OAK_LONGBOW, FletchingItems.OAK_STOCK), - WILLOW(1519, FletchingItems.WILLOW_SHORTBOW, FletchingItems.WILLOW_LONGBOW, FletchingItems.WILLOW_STOCK), - MAPLE(1517, FletchingItems.MAPLE_SHORTOW, FletchingItems.MAPLE_LONGBOW, FletchingItems.MAPLE_STOCK), - YEW(1515, FletchingItems.YEW_SHORTBOW, FletchingItems.YEW_LONGBOW, FletchingItems.YEW_STOCK), - MAGIC(1513, FletchingItems.MAGIC_SHORTBOW, FletchingItems.MAGIC_LONGBOW), - TEAK(6333, FletchingItems.TEAK_STOCK), - MAHOGANY(6332, FletchingItems.MAHOGANY_STOCK); - - - FletchingItems[] items; - int id; - Items(int id, FletchingItems item_1, FletchingItems item_2, FletchingItems item_3, FletchingItems item_4){ - items = new FletchingItems[] {item_1, item_2, item_3, item_4}; - this.id = id; - } - Items(int id, FletchingItems item_1, FletchingItems item_2, FletchingItems item_3){ - items = new FletchingItems[] {item_1, item_2, item_3}; - this.id = id; - } - Items(int id, FletchingItems item_1, FletchingItems item_2){ - items = new FletchingItems[] {item_1, item_2}; - this.id = id; - } - Items(int id, FletchingItems item_1){ - items = new FletchingItems[] {item_1}; - this.id = id; - } - } - public enum FletchingItems { - //Standard logs - ARROW_SHAFT(52, 5, 1, 15), - SHORT_BOW(50, 5, 5, 1), - LONG_BOW(48, 10, 10, 1), - WOODEN_STOCK(9440, 6, 9, 1), - - //Achey logs - OGRE_ARROW_SHAFT(2864, 6.4, 5, 4), - OGRE_COMP_BOW(4825, 45, 30, 1), - - //Oak logs - OAK_SHORTBOW(54, 16.5, 20, 1), - OAK_LONGBOW(56,25,25,1), - OAK_STOCK(9442, 16, 24, 1), - - //Willow logs - WILLOW_SHORTBOW(60, 33.3, 35, 1), - WILLOW_LONGBOW(58, 41.5, 40, 1), - WILLOW_STOCK(9444, 22, 39, 1), - - //Maple logs - MAPLE_SHORTOW(64, 50, 50, 1), - MAPLE_LONGBOW(62, 58.3, 55, 1), - MAPLE_STOCK(9448, 32, 54, 1), - - //Yew logs - YEW_SHORTBOW(68, 67.5, 65, 1), - YEW_LONGBOW(66, 75, 70, 1), - YEW_STOCK(9452, 50, 69, 1), - - //Magic logs - MAGIC_SHORTBOW(72, 83.3, 80,1), - MAGIC_LONGBOW(70, 91.5, 85, 1), - - //Teak - TEAK_STOCK(9446, 27, 46,1), - - //Mahogany - MAHOGANY_STOCK(9450, 41.0, 61, 1); - - - int id,level,amount,logId; - double experience; - FletchingItems(int id, double experience, int level, int amount){ - this.id = id; - this.level = level; - this.amount = amount; - this.experience = experience; - } - - public Item getItem(){ - return new Item(id); - } - } - -} diff --git a/Server/src/main/content/global/skill/fletching/FletchingListeners.kt b/Server/src/main/content/global/skill/fletching/FletchingListeners.kt deleted file mode 100644 index 464a0b6ff..000000000 --- a/Server/src/main/content/global/skill/fletching/FletchingListeners.kt +++ /dev/null @@ -1,197 +0,0 @@ -package content.global.skill.fletching - -import content.data.Quests -import content.global.skill.fletching.items.arrow.ArrowHeadPulse -import content.global.skill.fletching.items.arrow.HeadlessArrowPulse -import content.global.skill.fletching.items.arrow.HeadlessOgreArrowPulse -import content.global.skill.fletching.items.bow.StringPulse -import content.global.skill.fletching.items.crossbow.LimbPulse -import core.api.* -import core.game.node.entity.skill.Skills -import core.game.node.item.Item -import core.net.packet.PacketRepository -import core.net.packet.context.ChildPositionContext -import core.net.packet.out.RepositionChild -import org.rs09.consts.Components -import org.rs09.consts.Items -import org.rs09.consts.Items.BLUE_FEATHER_10089 -import org.rs09.consts.Items.FEATHER_314 -import org.rs09.consts.Items.ORANGE_FEATHER_10091 -import org.rs09.consts.Items.RED_FEATHER_10088 -import org.rs09.consts.Items.STRIPY_FEATHER_10087 -import org.rs09.consts.Items.YELLOW_FEATHER_10090 -import core.game.dialogue.SkillDialogueHandler -import core.game.interaction.InteractionListener -import core.game.interaction.IntType -import core.game.node.entity.player.Player - -class FletchingListeners : InteractionListener { - - val LIMBIDs = Fletching.Limb.values().map(Fletching.Limb::limb).toIntArray() - val STOCKIDs = Fletching.Limb.values().map(Fletching.Limb::stock).toIntArray() - val MITHRIL_BOLT = Items.MITHRIL_BOLTS_9142 - val MITH_GRAPPLE_TIP = Items.MITH_GRAPPLE_TIP_9416 - val ROPE = Items.ROPE_954 - val MITH_GRAPPLE = Items.MITH_GRAPPLE_9418 - val ROPE_GRAPPLE = Items.MITH_GRAPPLE_9419 - val ARROW_SHAFT = Items.ARROW_SHAFT_52 - val OGRE_ARROW_SHAFT = Items.OGRE_ARROW_SHAFT_2864 - val FLETCHED_SHAFT = Items.HEADLESS_ARROW_53 - val FLIGHTED_OGRE_ARROW = Items.FLIGHTED_OGRE_ARROW_2865 - val UNFINISHED_ARROWS = Fletching.ArrowHeads.values().map(Fletching.ArrowHeads::unfinished).toIntArray() - val FEATHERS = intArrayOf(FEATHER_314,STRIPY_FEATHER_10087,RED_FEATHER_10088,BLUE_FEATHER_10089,YELLOW_FEATHER_10090,ORANGE_FEATHER_10091) - val UNSTRUNG_BOWS = Fletching.String.values().map(Fletching.String::unfinished).toIntArray() - val STRINGS = intArrayOf(Items.BOW_STRING_1777,Items.CROSSBOW_STRING_9438) - - override fun defineListeners() { - - onUseWith(IntType.ITEM,STRINGS,*UNSTRUNG_BOWS){ player, string, bow -> - val enum = Fletching.stringMap[bow.id] ?: return@onUseWith false - - if (bow.id == Items.UNSTRUNG_COMP_BOW_4825) { - // You shouldn't be able to string a bow - if (getQuestStage(player, Quests.ZOGRE_FLESH_EATERS) < 8) { - player.packetDispatch.sendMessage("You must have started Zogre Flesh Eaters and asked Grish to string this.") - return@onUseWith true - } - } - if(enum.string != string.id){ - player.sendMessage("That's not the right kind of string for this.") - return@onUseWith true - } - val handler: SkillDialogueHandler = - object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(enum.product)) { - override fun create(amount: Int, index: Int) { - player.pulseManager.run(StringPulse(player, string.asItem(), enum, amount)) - } - - override fun getAll(index: Int): Int { - return player.inventory.getAmount(string.asItem()) - } - } - handler.open() - PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 215, 10)) - return@onUseWith true - } - - onUseWith(IntType.ITEM,ARROW_SHAFT,*FEATHERS){ player, shaft, feather -> - val handler: SkillDialogueHandler = - object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(FLETCHED_SHAFT)) { - override fun create(amount: Int, index: Int) { - player.pulseManager.run(HeadlessArrowPulse(player, shaft.asItem(), Item(feather.id), amount)) - } - - override fun getAll(index: Int): Int { - return player.inventory.getAmount(FLETCHED_SHAFT) - } - } - handler.open() - return@onUseWith true - } - - onUseWith(IntType.ITEM,OGRE_ARROW_SHAFT,*FEATHERS){ player, shaft, feather -> - val handler: SkillDialogueHandler = - object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(FLIGHTED_OGRE_ARROW)) { - override fun create(amount: Int, index: Int) { - player.pulseManager.run(HeadlessOgreArrowPulse(player, shaft.asItem(), Item(feather.id, 4), amount)) - } - - override fun getAll(index: Int): Int { - return player.inventory.getAmount(FLIGHTED_OGRE_ARROW) - } - } - handler.open() - return@onUseWith true - } - - onUseWith(IntType.ITEM,FLETCHED_SHAFT,*UNFINISHED_ARROWS){ player, shaft, unfinished -> - val head = Fletching.arrowHeadMap[unfinished.id] ?: return@onUseWith false - val handler: SkillDialogueHandler = - object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, head.getFinished()) { - override fun create(amount: Int, index: Int) { - player.pulseManager.run(ArrowHeadPulse(player, shaft.asItem(), head, amount)) - } - - override fun getAll(index: Int): Int { - return player.inventory.getAmount(head.getUnfinished()) - } - } - handler.open() - return@onUseWith true - } - - onUseWith(IntType.ITEM,MITHRIL_BOLT,MITH_GRAPPLE_TIP){ player, bolt, tip -> - if(player.skills.getLevel(Skills.FLETCHING) < 59){ - player.sendMessage("You need a fletching level of 59 to make this.") - return@onUseWith true - } - if(player.inventory.remove(Item(MITHRIL_BOLT,1),tip.asItem())){ - player.inventory.add(Item(MITH_GRAPPLE)) - } - return@onUseWith true - } - - onUseWith(IntType.ITEM,ROPE,MITH_GRAPPLE){ player, rope, grapple -> - if(player.skills.getLevel(Skills.FLETCHING) < 59){ - player.sendMessage("You need a fletching level of 59 to make this.") - return@onUseWith true - } - if(player.inventory.remove(rope.asItem(),grapple.asItem())){ - player.inventory.add(Item(ROPE_GRAPPLE)) - } - return@onUseWith true - } - - onUseWith(IntType.ITEM,LIMBIDs,*STOCKIDs){ player, limb, stock -> - val limbEnum = Fletching.limbMap[stock.id] ?: return@onUseWith false - if(limbEnum.limb != limb.id){ - player.sendMessage("That's not the right limb to attach to that stock.") - return@onUseWith true - } - val handler: SkillDialogueHandler = object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(limbEnum.product)){ - override fun create(amount: Int, index: Int) { - player.pulseManager.run(LimbPulse(player, stock.asItem(), limbEnum, amount)) - } - - override fun getAll(index: Int): Int { - return player.inventory.getAmount(stock.asItem()) - } - } - handler.open() - PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 210, 10)) - return@onUseWith true - } - - /** - * (Long) Kebbit bolts don't need feathers and go 6 at a time so use their own interaction - */ - fun makeKebbitBolt(player : Player, ingredient : Item) : Boolean{ - val longBolts = when(ingredient.id){ - Items.KEBBIT_SPIKE_10105 -> false - Items.LONG_KEBBIT_SPIKE_10107 -> true - else -> return false - } - val level = if(longBolts) 42 else 26 - if (getDynLevel(player, Skills.FLETCHING) < level){ - sendMessage(player, "You need a fletching level of $level to create ${if (longBolts) "long " else ""}kebbit bolts.") - return true - } - val finalProduct = if(longBolts) Items.LONG_KEBBIT_BOLTS_10159 else Items.KEBBIT_BOLTS_10158 - val xp = if(longBolts) 47.7 else 28.6 // source https://runescape.wiki/w/Fletching?oldid=1069981#Bolts_2 - if(removeItem(player, ingredient.id)){ - addItem(player, finalProduct, 6) - player.skills.addExperience(Skills.FLETCHING, xp) - animate(player, 885) - } - return true - } - onUseWith(IntType.ITEM, Items.CHISEL_1755, Items.KEBBIT_SPIKE_10105) { player, used, with -> - return@onUseWith makeKebbitBolt(player, with as Item) - } - - onUseWith(IntType.ITEM, Items.CHISEL_1755, Items.LONG_KEBBIT_SPIKE_10107) { player, used, with -> - return@onUseWith makeKebbitBolt(player, with as Item) - } - } - -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/FletchingPlugin.java b/Server/src/main/content/global/skill/fletching/FletchingPlugin.java deleted file mode 100644 index 3ec122866..000000000 --- a/Server/src/main/content/global/skill/fletching/FletchingPlugin.java +++ /dev/null @@ -1,131 +0,0 @@ -package content.global.skill.fletching; - -import content.global.skill.fletching.items.bolts.BoltPulse; -import content.global.skill.fletching.items.darts.DartPulse; -import org.rs09.consts.Items; -import core.game.dialogue.SkillDialogueHandler; -import core.game.dialogue.SkillDialogueHandler.SkillDialogue; -import core.game.interaction.NodeUsageEvent; -import core.game.interaction.UseWithHandler; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.net.packet.PacketRepository; -import core.net.packet.context.ChildPositionContext; -import core.net.packet.out.RepositionChild; -import core.plugin.Initializable; -import core.plugin.Plugin; - -/** - * Represents the plugin used to open the fletching dialogue. - * @author Ceikry - */ -@Initializable -public class FletchingPlugin extends UseWithHandler { - - public FletchingPlugin() { - super(819,820,821,822,823,824,11232,9375,9376,9377,9382,9378,9379,9380,9381,13279,1511,1521,1519,1517,1515,1513,2862,6332,6333, Items.MAHOGANY_LOGS_6332); - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - // Knife - addHandler(946, ITEM_TYPE, this); - - // Feathers plus colored feathers - addHandler(314, ITEM_TYPE,this); - addHandler(10087, ITEM_TYPE, this); - addHandler(10088, ITEM_TYPE, this); - addHandler(10089, ITEM_TYPE, this); - addHandler(10090, ITEM_TYPE, this); - addHandler(10091, ITEM_TYPE, this); - - return this; - } - - @Override - public boolean handle(final NodeUsageEvent event) { - final Player player = event.getPlayer(); - - //handle darts - if(Fletching.isDart(event.getUsedItem().getId())){ - final Fletching.Darts dart = Fletching.dartMap.get(event.getUsedItem().getId()); - SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, dart.getFinished()) { - @Override - public void create(final int amount, int index) { - player.getPulseManager().run(new DartPulse(player, event.getUsedItem(), dart, amount)); - } - @Override - public int getAll(int index) { - return player.getInventory().getAmount(event.getUsedItem()); - } - }; - handler.open(); - return true; - } - - //handle bolts - if(Fletching.isBolt(event.getUsedItem().getId()) || Fletching.isBolt(event.getUsedWith().getId())){ - // figure out which of the used items is a bolt, and which is potentially a feather - final Fletching.Bolts bolt - = Fletching.isBolt(event.getUsedItem().getId()) - ? Fletching.boltMap.get(event.getUsedItem().getId()) - : Fletching.boltMap.get(event.getUsedWith().getId()); - final int featherId - = Fletching.isBolt(event.getUsedItem().getId()) - ? event.getUsedWith().getId() - : event.getUsedItem().getId(); - final boolean hasFeather = (featherId == 314 || (featherId >= 10087 && featherId <= 10091)); - - if (hasFeather) { - SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, bolt.getFinished()) { - @Override - public void create(final int amount, int index) { - player.getPulseManager().run(new BoltPulse(player, event.getUsedItem(), bolt, new Item(featherId), amount)); - } - @Override - public int getAll(int index) { - return player.getInventory().getAmount(event.getUsedItem()); - } - }; - handler.open(); - return true; - } - return false; - } - - //handle logs - if(Fletching.isLog(event.getUsedItem().getId()) && event.getUsedWith().getId() == 946) { - final Item log = event.getUsedItem(); - Item[] items = Fletching.getItems(log.getId()); - SkillDialogue dialLength = SkillDialogue.ONE_OPTION; - switch (items.length) { - case 2: - dialLength = SkillDialogue.TWO_OPTION; - break; - case 3: - dialLength = SkillDialogue.THREE_OPTION; - break; - case 4: - dialLength = SkillDialogue.FOUR_OPTION; - break; - } - SkillDialogueHandler handler = new SkillDialogueHandler(player, dialLength, items) { - - @Override - public void create(final int amount, int index) { - final Fletching.FletchingItems item = Fletching.getEntries(log.getId())[index]; - player.getPulseManager().run(new FletchingPulse(player, log, amount, item)); - } - - @Override - public int getAll(int index) { - return player.getInventory().getAmount(log); - } - - }; - handler.open(); - return true; - } - return false; - } -} diff --git a/Server/src/main/content/global/skill/fletching/FletchingPulse.java b/Server/src/main/content/global/skill/fletching/FletchingPulse.java deleted file mode 100644 index b02e40572..000000000 --- a/Server/src/main/content/global/skill/fletching/FletchingPulse.java +++ /dev/null @@ -1,145 +0,0 @@ -package content.global.skill.fletching; - -import core.tools.RandomFunction; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.world.map.zone.ZoneBorders; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; -import core.game.world.update.flag.context.Animation; -import core.tools.StringUtils; -import content.data.Quests; - -/** - * fletching skill pulse - * @author ceik - */ -public final class FletchingPulse extends SkillPulse { - - /** - * Seers bank zone borders for the diary task - */ - private static final ZoneBorders bankZone = new ZoneBorders(2721,3493,2730,3487); - - /** - * Represents the animation used in this generic pulse. - */ - private static final Animation ANIMATION = new Animation(1248); - - /** - * Represents the item we are fletching. - */ - private Fletching.FletchingItems fletch; - - /** - * Represents the amount to fletch. - */ - private int amount = 0; - - /** - * Represents the amount to arrows fletched (for ogre arrow shafts which is a random number from 2-6). - */ - private int finalAmount = 0; - - /** - * Constructs a new {@code FletchingPulse.java} {@code Object}. - * @param player - * @param node - */ - public FletchingPulse(final Player player, final Item node, final int amount, final Fletching.FletchingItems fletch) { - super(player, node); - this.amount = amount; - this.fletch = fletch; - } - - @Override - public boolean checkRequirements() { - if (player.getSkills().getLevel(Skills.FLETCHING) < fletch.level) { - player.getDialogueInterpreter().sendDialogue("You need a Fletching skill of " + fletch.level + " or above to make " + (StringUtils.isPlusN(fletch.getItem().getName().replace("(u)", "").trim()) ? "an" : "a") + " " + fletch.getItem().getName().replace("(u)", "").trim()); - return false; - } - if (amount > player.getInventory().getAmount(node)) { - amount = player.getInventory().getAmount(node); - } - if (fletch == Fletching.FletchingItems.OGRE_ARROW_SHAFT) { - if (player.getQuestRepository().getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING).getStage(player) == 0) { - player.getPacketDispatch().sendMessage("You must have started Big Chompy Bird Hunting to make those."); - return false; - } - } - if (fletch == Fletching.FletchingItems.OGRE_COMP_BOW) { - // Technically, this isn't supposed to show up till you've asked Grish. - if (player.getQuestRepository().getQuest(Quests.ZOGRE_FLESH_EATERS).getStage(player) < 8) { - player.getPacketDispatch().sendMessage("You must have started Zogre Flesh Eaters and asked Grish to make this."); - return false; - } - if (!player.getInventory().contains(2859, 1)) { - player.getPacketDispatch().sendMessage("You need to have Wolf Bones in order to make this."); - return false; - } - } - return true; - } - - @Override - public void animate() { - player.animate(ANIMATION); - } - - @Override - public boolean reward() { - if(bankZone.insideBorder(player) && fletch == Fletching.FletchingItems.MAGIC_SHORTBOW) { - player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 2); - } - if (getDelay() == 1) { - super.setDelay(4); - return false; - } - if (player.getInventory().remove(node)) { - final Item item = new Item(fletch.id,fletch.amount); - if ( fletch == Fletching.FletchingItems.OGRE_ARROW_SHAFT ) { - // The amount of shafts given is random; between two and six will be made. - finalAmount = RandomFunction.random(2,6); - item.setAmount(finalAmount); - } - if ( fletch == Fletching.FletchingItems.OGRE_COMP_BOW ) { - if (!player.getInventory().contains(2859, 1)) { - return false; - } else { - player.getInventory().remove(new Item(2859)); - } - } - player.getInventory().add(item); - player.getSkills().addExperience(Skills.FLETCHING, fletch.experience, true); - String message = getMessage(); - player.getPacketDispatch().sendMessage(message); - - if (fletch.id == Fletching.FletchingItems.MAGIC_SHORTBOW.id - && (new ZoneBorders(2721, 3489, 2724, 3493, 0).insideBorder(player) - || new ZoneBorders(2727, 3487, 2730, 3490, 0).insideBorder(player)) - && !player.getAchievementDiaryManager().hasCompletedTask(DiaryType.SEERS_VILLAGE, 2, 2)) { - player.setAttribute("/save:diary:seers:fletch-magic-short-bow", true); - } - } else { - return true; - } - amount--; - return amount == 0; - } - - /** - * Method used to get the message of the fletch. - * @return the message. - */ - public String getMessage() { - switch (fletch) { - case ARROW_SHAFT: - return "You carefully cut the wood into 15 arrow shafts."; - case OGRE_ARROW_SHAFT: - return "You carefully cut the wood into " + finalAmount + " arrow shafts."; - default: - return "You carefully cut the wood into " + (StringUtils.isPlusN(fletch.getItem().getName()) ? "an" : "a") + " " + fletch.getItem().getName().replace("(u)", "").trim() + "."; - } - } -} diff --git a/Server/src/main/content/global/skill/fletching/GemBoltListener.kt b/Server/src/main/content/global/skill/fletching/GemBoltListener.kt deleted file mode 100644 index 94c09c65b..000000000 --- a/Server/src/main/content/global/skill/fletching/GemBoltListener.kt +++ /dev/null @@ -1,69 +0,0 @@ -package content.global.skill.fletching - -import content.global.skill.fletching.Fletching.GemBolts -import content.global.skill.fletching.items.gem.GemBoltCutPulse -import content.global.skill.fletching.items.gem.GemBoltPulse -import core.api.amountInInventory -import core.game.dialogue.SkillDialogueHandler -import core.game.interaction.IntType -import core.game.interaction.InteractionListener -import core.game.node.item.Item -import core.net.packet.PacketRepository -import core.net.packet.context.ChildPositionContext -import core.net.packet.out.RepositionChild -import org.rs09.consts.Items -import kotlin.math.min - -class GemBoltListener : InteractionListener { - val gems = intArrayOf( - Items.OYSTER_PEARL_411, - Items.OYSTER_PEARLS_413, - Items.OPAL_1609, - Items.JADE_1611, - Items.RED_TOPAZ_1613, - Items.SAPPHIRE_1607, - Items.EMERALD_1605, - Items.RUBY_1603, - Items.DIAMOND_1601, - Items.DRAGONSTONE_1615, - Items.ONYX_6573 - ) - val boltBases = GemBolts.values().map { it.base }.toIntArray() - val boltTips = GemBolts.values().map { it.tip }.toIntArray() - - override fun defineListeners() { - onUseWith(IntType.ITEM, Items.CHISEL_1755, *gems) { player, used, with -> - val gem = Fletching.gemMap[with.id] ?: return@onUseWith true - - object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(gem.gem)) { - override fun create(amount: Int, index: Int) { - player.pulseManager.run(GemBoltCutPulse(player, used as? Item, gem, amount)) - } - - override fun getAll(index: Int): Int { - return player.inventory.getAmount(gem.gem) - } - }.open() - return@onUseWith true - } - - onUseWith(IntType.ITEM, boltBases, *boltTips) {player, used, with -> - val bolt = Fletching.tipMap[with.id] ?: return@onUseWith true - if (used.id != bolt.base || with.id != bolt.tip) return@onUseWith true - - - val handler: SkillDialogueHandler = - object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(bolt.product)) { - override fun create(amount: Int, index: Int) { - player.pulseManager.run(GemBoltPulse(player, used as? Item, bolt, amount)) - } - - override fun getAll(index: Int): Int { - return min(amountInInventory(player, used.id), amountInInventory(player, with.id)) - } - } - handler.open() - return@onUseWith true - } - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/Zones.kt b/Server/src/main/content/global/skill/fletching/Zones.kt new file mode 100644 index 000000000..8c10f0c4f --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/Zones.kt @@ -0,0 +1,21 @@ +package content.global.skill.fletching + +import core.game.node.Node +import core.game.world.map.zone.ZoneBorders + +object Zones { + val seersMagicShortbowAchievementZones = arrayOf( + ZoneBorders(2721, 3489, 2724, 3493, 0), + ZoneBorders(2727, 3487, 2730, 3490, 0), + ZoneBorders(2721, 3493, 2730, 3487) + ) + + fun inAnyZone(node: Node, zones: Array): Boolean { + for (zone in zones) { + if (zone.insideBorder(node)) { + return true + } + } + return false + } +} diff --git a/Server/src/main/content/global/skill/fletching/arrow/ArrowCraftInfo.kt b/Server/src/main/content/global/skill/fletching/arrow/ArrowCraftInfo.kt new file mode 100644 index 000000000..087c688a9 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/arrow/ArrowCraftInfo.kt @@ -0,0 +1,24 @@ +package content.global.skill.fletching.arrow + +import org.rs09.consts.Items + +enum class ArrowCraftInfo(val tipItemId: Int, val arrowItemId: Int, val level: Int, val experience: Double) { + BRONZE_ARROW(Items.BRONZE_ARROWTIPS_39, Items.BRONZE_ARROW_882, 1, 1.3), + IRON_ARROW(Items.IRON_ARROWTIPS_40, Items.IRON_ARROW_884, 15, 2.5), + STEEL_ARROW(Items.STEEL_ARROWTIPS_41, Items.STEEL_ARROW_886, 30, 5.0), + MITHRIL_ARROW(Items.MITHRIL_ARROWTIPS_42, Items.MITHRIL_ARROW_888, 45, 7.5), + ADAMANT_ARROW(Items.ADAMANT_ARROWTIPS_43, Items.ADAMANT_ARROW_890, 60, 10.0), + RUNE_ARROW(Items.RUNE_ARROWTIPS_44, Items.RUNE_ARROW_892, 75, 12.5), + DRAGON_ARROW(Items.DRAGON_ARROWTIPS_11237,Items.DRAGON_ARROW_11212, 90, 15.0), + BROAD_ARROW(Items.BROAD_ARROW_HEADS_13278, Items.BROAD_ARROW_4160, 52, 15.0); + + companion object { + private val arrowCraftInfoByTipId = values().associateBy { it.tipItemId } + + val arrowTipIds: IntArray = values().map { arrowCraftInfo: ArrowCraftInfo -> arrowCraftInfo.tipItemId }.toIntArray() + + fun fromTipId(tipId: Int) : ArrowCraftInfo? { + return arrowCraftInfoByTipId[tipId] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/arrow/ArrowListeners.kt b/Server/src/main/content/global/skill/fletching/arrow/ArrowListeners.kt new file mode 100644 index 000000000..2c061b3cb --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/arrow/ArrowListeners.kt @@ -0,0 +1,112 @@ +package content.global.skill.fletching.arrow + +import content.global.skill.fletching.Feathers +import core.api.* +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items + +@Suppress("unused") // Reflectively loaded +class ArrowListeners : InteractionListener { + private val arrowShaft = Items.ARROW_SHAFT_52 + val headlessArrow = Items.HEADLESS_ARROW_53 + + companion object { + const val FLIGHTED_OGRE_ARROW_LEVEL = 5 + fun sendLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue( + player, + "You need a fletching level of $level to do this." + ) + } + } + + override fun defineListeners() { + onUseWith(IntType.ITEM, arrowShaft, *Feathers.all) { player, shaft, feather -> + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(headlessArrow)) { + override fun create(amount: Int, index: Int) { + if (!hasSpaceFor(player, Item(headlessArrow))) { + sendDialogue(player, "You do not have enough inventory space.") + return + } + HeadlessArrowCraftScript(player, feather.id, amount).invoke() + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, headlessArrow) + } + } + handler.open() + return@onUseWith true + } + + onUseWith(IntType.ITEM, headlessArrow, *ArrowCraftInfo.arrowTipIds) { player, headlessArrow, arrowTip -> + val arrowCraftInfo = ArrowCraftInfo.fromTipId(arrowTip.id) ?: return@onUseWith false + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(arrowCraftInfo.arrowItemId)) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + TippedArrowCraftScript(player, arrowCraftInfo, amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (arrowCraftInfo == ArrowCraftInfo.BROAD_ARROW && !getSlayerFlags(player).isBroadsUnlocked()) { + sendDialogue(player, "You need to unlock the ability to create broad arrows.") + return false + } + + if (getDynLevel(player, Skills.FLETCHING) < arrowCraftInfo.level) { + sendLevelCheckFailDialog(player, arrowCraftInfo.level) + return false + } + + if (!hasSpaceFor(player, Item(arrowCraftInfo.arrowItemId))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + return true + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, arrowTip.id) + } + } + handler.open() + return@onUseWith true + } + + onUseWith(IntType.ITEM, Items.OGRE_ARROW_SHAFT_2864, *Feathers.all) { player, ogreArrowShaft, feather -> + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(Items.FLIGHTED_OGRE_ARROW_2865)) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + FlightedOgreArrowCraftScript(player, feather.id, amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (getDynLevel(player, Skills.FLETCHING) < FLIGHTED_OGRE_ARROW_LEVEL) { + sendLevelCheckFailDialog(player, FLIGHTED_OGRE_ARROW_LEVEL) + return false + } + + if (!hasSpaceFor(player, Item(Items.FLIGHTED_OGRE_ARROW_2865))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + return true + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, Items.OGRE_ARROW_SHAFT_2864) + } + } + handler.open() + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/arrow/FlightedOgreArrowCraftScript.kt b/Server/src/main/content/global/skill/fletching/arrow/FlightedOgreArrowCraftScript.kt new file mode 100644 index 000000000..126b72aee --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/arrow/FlightedOgreArrowCraftScript.kt @@ -0,0 +1,88 @@ +package content.global.skill.fletching.arrow + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import kotlin.math.min + +/** + * Defines the queueScript for creating a flighted ogre arrow + * @author 'Vexia + * @param player the player. + * @param idOfFeatherUsed the feather to attach to the shaft. + * @param sets the amount of sets to complete. + */ +class FlightedOgreArrowCraftScript( + private val player: Player, + private val idOfFeatherUsed: Int, + private val sets: Int +) { + + private val flightedOgreArrow = Items.FLIGHTED_OGRE_ARROW_2865 + private val ogreArrowShaft = Items.OGRE_ARROW_SHAFT_2864 + private val maximumFlightedOgreArrowsCraftableInOneStage = 6 + + private val feathersPerArrow = 4 + + private val initialDelay = 1 + private val subsequentDelay = 3 + + private fun getAmountToCraftForThisStage(shaftsInInventory: Int, feathersInInventory: Int): Int { + val limitOfCraftableArrowsDueToFeathers = feathersInInventory / feathersPerArrow + + val totalCraftableArrows = min(shaftsInInventory, limitOfCraftableArrowsDueToFeathers) + return if (totalCraftableArrows > maximumFlightedOgreArrowsCraftableInOneStage) { + maximumFlightedOgreArrowsCraftableInOneStage + } else { + totalCraftableArrows + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < ArrowListeners.FLIGHTED_OGRE_ARROW_LEVEL) { + ArrowListeners.sendLevelCheckFailDialog(player, ArrowListeners.FLIGHTED_OGRE_ARROW_LEVEL) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val featherAmount = amountInInventory(player, idOfFeatherUsed) + val shaftAmount = amountInInventory(player, ogreArrowShaft) + + val amountToCraft = getAmountToCraftForThisStage(shaftAmount, featherAmount) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(ogreArrowShaft, amountToCraft), + Item(idOfFeatherUsed, amountToCraft * feathersPerArrow) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach $feathersPerArrow feathers to a shaft.") + else -> { + sendMessage( + player, + "You attach ${amountToCraft * feathersPerArrow} feathers to $amountToCraft arrow shafts." + ) + } + } + + rewardXP(player, Skills.FLETCHING, amountToCraft.toDouble()) + addItem(player, flightedOgreArrow, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/arrow/HeadlessArrowCraftScript.kt b/Server/src/main/content/global/skill/fletching/arrow/HeadlessArrowCraftScript.kt new file mode 100644 index 000000000..40ef4c235 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/arrow/HeadlessArrowCraftScript.kt @@ -0,0 +1,76 @@ +package content.global.skill.fletching.arrow + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import kotlin.math.min + +/** + * Defines the queueScript for creating a headless arrow + * @author 'Vexia + * @param player the player. + * @param idOfFeatherUsed the feather to attach to the shaft. + * @param sets the amount of sets to complete. + */ +class HeadlessArrowCraftScript( + private val player: Player, + private val idOfFeatherUsed: Int, + private val sets: Int +) { + + private val headlessArrow = Items.HEADLESS_ARROW_53 + private val arrowShaft = Items.ARROW_SHAFT_52 + private val maximumHeadlessArrowsCraftableInOneStage = 15 + + private val initialDelay = 1 + private val subsequentDelay = 3 + + private fun getAmountToCraftForThisStage(shaftsInInventory: Int, feathersInInventory: Int): Int { + val smallerItemAmount = min(shaftsInInventory, feathersInInventory) + return if (smallerItemAmount > maximumHeadlessArrowsCraftableInOneStage) { + maximumHeadlessArrowsCraftableInOneStage + } else { + smallerItemAmount + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + val featherAmount = amountInInventory(player, idOfFeatherUsed) + val shaftAmount = amountInInventory(player, arrowShaft) + + val amountToCraft = getAmountToCraftForThisStage(shaftAmount, featherAmount) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(arrowShaft, amountToCraft), + Item(idOfFeatherUsed, amountToCraft) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach a feather to a shaft.") + else -> { + sendMessage(player, "You attach feathers to $amountToCraft arrow shafts.") + } + } + + rewardXP(player, Skills.FLETCHING, amountToCraft.toDouble()) + addItem(player, headlessArrow, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/arrow/TippedArrowCraftScript.kt b/Server/src/main/content/global/skill/fletching/arrow/TippedArrowCraftScript.kt new file mode 100644 index 000000000..d4249b660 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/arrow/TippedArrowCraftScript.kt @@ -0,0 +1,79 @@ +package content.global.skill.fletching.arrow + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import kotlin.math.min + +/** + * Represents the arrow head pulse to complete the headless arrow. + * @author 'Vexia + * @param player the player. + * @param arrowCraftInfo provides information about the arrow we're crafting. + * @param sets the amount of sets to complete. + */ +class TippedArrowCraftScript( + private val player: Player, + private val arrowCraftInfo: ArrowCraftInfo, + private val sets: Int +) { + + private val headlessArrow = Items.HEADLESS_ARROW_53 + private val maximumArrowsCraftableInOneStage = 15 + private val initialDelay = 1 + private val subsequentDelay = 3 + + private fun getAmountToCraftForThisStage(headlessArrowsInInventory: Int, tipsInInventory: Int): Int { + val smallerItemAmount = min(headlessArrowsInInventory, tipsInInventory) + return if (smallerItemAmount > maximumArrowsCraftableInOneStage) { + maximumArrowsCraftableInOneStage + } else { + smallerItemAmount + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < arrowCraftInfo.level) { + ArrowListeners.sendLevelCheckFailDialog(player, arrowCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val tipsInInventory = amountInInventory(player, arrowCraftInfo.tipItemId) + val headlessArrowsInInventory = amountInInventory(player, headlessArrow) + + val amountToCraft = getAmountToCraftForThisStage(headlessArrowsInInventory, tipsInInventory) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(headlessArrow, amountToCraft), + Item(arrowCraftInfo.tipItemId, amountToCraft) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach an arrow head to an arrow shaft.") + else -> { + sendMessage(player, "You attach arrow heads to $amountToCraft arrow shafts.") + } + } + + rewardXP(player, Skills.FLETCHING, arrowCraftInfo.experience * amountToCraft) + addItem(player, arrowCraftInfo.arrowItemId, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/bolts/BoltCraftInfo.kt b/Server/src/main/content/global/skill/fletching/bolts/BoltCraftInfo.kt new file mode 100644 index 000000000..497332a59 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/bolts/BoltCraftInfo.kt @@ -0,0 +1,39 @@ +package content.global.skill.fletching.bolts + +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different bolts + * @property unfinishedBoltItemId the unfinished bolt (unf) Item id used to craft the dart. + * @property finishedItemId the resulting finished bolt Item id. + * @property level the level required to craft. + * @property experience the experience gained by crafting. + */ +enum class BoltCraftInfo( + val unfinishedBoltItemId: Int, + val finishedItemId: Int, + val level: Int, + val experience: Double +) { + BRONZE_BOLT(Items.BRONZE_BOLTS_UNF_9375, Items.BRONZE_BOLTS_877, 9, 0.5), + BLURITE_BOLT(Items.BLURITE_BOLTS_UNF_9376, Items.BLURITE_BOLTS_9139, 24, 1.0), + IRON_BOLT(Items.IRON_BOLTS_UNF_9377, Items.IRON_BOLTS_9140, 39, 1.5), + SILVER_BOLT(Items.SILVER_BOLTS_UNF_9382, Items.SILVER_BOLTS_9145, 43, 2.5), + STEEL_BOLT(Items.STEEL_BOLTS_UNF_9378, Items.STEEL_BOLTS_9141, 46, 3.5), + MITHRIL_BOLT(Items.MITHRIL_BOLTS_UNF_9379, Items.MITHRIL_BOLTS_9142, 54, 5.0), + ADAMANTITE_BOLT(Items.ADAMANT_BOLTSUNF_9380, Items.ADAMANT_BOLTS_9143, 61, 7.0), + RUNITE_BOLT(Items.RUNITE_BOLTS_UNF_9381, Items.RUNE_BOLTS_9144, 69, 10.0), + BROAD_BOLT(Items.UNFINISHED_BROAD_BOLTS_13279, Items.BROAD_TIPPED_BOLTS_13280, 55, 3.0); + + companion object { + private val boltCraftInfoByUnfinishedBoltIds = values().associateBy { it.unfinishedBoltItemId } + + val unfinishedBoltIds: IntArray = BoltCraftInfo.values() + .map { unfinishedBoltToBoltMapping: BoltCraftInfo -> unfinishedBoltToBoltMapping.unfinishedBoltItemId } + .toIntArray() + + fun fromUnfinishedBoltId(unfinishedBoltId: Int): BoltCraftInfo? { + return boltCraftInfoByUnfinishedBoltIds[unfinishedBoltId] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/bolts/BoltCraftScript.kt b/Server/src/main/content/global/skill/fletching/bolts/BoltCraftScript.kt new file mode 100644 index 000000000..e525e7055 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/bolts/BoltCraftScript.kt @@ -0,0 +1,79 @@ +package content.global.skill.fletching.bolts + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import kotlin.math.min + +/** + * Represents the bolt pulse class to make bolts. + * @author ceik + * @param player the player. + * @param boltCraftInfo contains information about what bolt we're crafting + * @param feather the feather we're using to craft + * @param sets the amount of sets to craft + */ +class BoltCraftScript( + private val player: Player, + private val boltCraftInfo: BoltCraftInfo, + private val feather: Item, + private val sets: Int +) { + + private val maximumBoltsCraftableInOneStage = 10 + private val initialDelay = 1 + private val subsequentDelay = 3 + + private fun getAmountToCraftForThisSet(feathersInInventory: Int, unfinishedBoltsInInventory: Int): Int { + val smallerItemAmount = min(feathersInInventory, unfinishedBoltsInInventory) + return if (smallerItemAmount > maximumBoltsCraftableInOneStage) { + maximumBoltsCraftableInOneStage + } else { + smallerItemAmount + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < boltCraftInfo.level) { + BoltListeners.sendLevelCheckFailDialog(player, boltCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val featherAmount = amountInInventory(player, feather.id) + val unfinishedBoltAmount = amountInInventory(player, boltCraftInfo.unfinishedBoltItemId) + + val amountToCraft = getAmountToCraftForThisSet(featherAmount, unfinishedBoltAmount) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(feather.id, amountToCraft), + Item(boltCraftInfo.unfinishedBoltItemId, amountToCraft) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach a feather to a bolt.") + else -> { + sendMessage(player, "You fletch $amountToCraft bolts") + } + } + + rewardXP(player, Skills.FLETCHING, boltCraftInfo.experience * amountToCraft) + addItem(player, boltCraftInfo.finishedItemId, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/bolts/BoltListeners.kt b/Server/src/main/content/global/skill/fletching/bolts/BoltListeners.kt new file mode 100644 index 000000000..ad9d806d8 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/bolts/BoltListeners.kt @@ -0,0 +1,65 @@ +package content.global.skill.fletching.bolts + +import content.global.skill.fletching.Feathers +import core.api.* +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import kotlin.math.min + +@Suppress("unused") // Reflectively loaded +class BoltListeners : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.ITEM, Feathers.all, *BoltCraftInfo.unfinishedBoltIds) { player, feather, unfinishedBolt -> + val boltCraftInfo = BoltCraftInfo.fromUnfinishedBoltId(unfinishedBolt.id) ?: return@onUseWith false + val handler: SkillDialogueHandler = + object : SkillDialogueHandler( + player, + SkillDialogue.MAKE_SET_ONE_OPTION, + Item(boltCraftInfo.finishedItemId) + ) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + BoltCraftScript(player, boltCraftInfo, feather.asItem(), amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (boltCraftInfo == BoltCraftInfo.BROAD_BOLT && !getSlayerFlags(player).isBroadsUnlocked()) { + sendDialogue(player, "You need to unlock the ability to create broad bolts.") + return false + } + if (getDynLevel(player, Skills.FLETCHING) < boltCraftInfo.level) { + sendLevelCheckFailDialog(player, boltCraftInfo.level) + return false + } + if (!hasSpaceFor(player, Item(boltCraftInfo.finishedItemId))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + + return true + } + + override fun getAll(index: Int): Int { + return min( + amountInInventory(player, feather.id), + amountInInventory(player, unfinishedBolt.id) + ) + } + } + handler.open() + return@onUseWith true + } + } + companion object { + fun sendLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue( + player, + "You need a fletching level of $level in order to do this." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/crossbow/LimbingListener.kt b/Server/src/main/content/global/skill/fletching/crossbow/LimbingListener.kt new file mode 100644 index 000000000..0876d54c1 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/crossbow/LimbingListener.kt @@ -0,0 +1,80 @@ +package content.global.skill.fletching.crossbow + +import core.api.getDynLevel +import core.api.hasSpaceFor +import core.api.sendDialogue +import core.api.sendMessage +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.net.packet.PacketRepository +import core.net.packet.context.ChildPositionContext +import core.net.packet.out.RepositionChild +import org.rs09.consts.Components + +@Suppress("unused") // Reflectively loaded +class LimbingListener : InteractionListener { + override fun defineListeners() { + onUseWith( + IntType.ITEM, + UnfinishedCrossbowCraftInfo.limbIds, + *UnfinishedCrossbowCraftInfo.stockIds + ) { player, limb, stock -> + val unfinishedCrossbowCraftInfo = UnfinishedCrossbowCraftInfo.forStockId(stock.id) ?: return@onUseWith false + if (unfinishedCrossbowCraftInfo.limbItemId != limb.id) { + sendMessage(player, "That's not the right limb to attach to that stock.") + return@onUseWith true + } + val handler: SkillDialogueHandler = object : SkillDialogueHandler( + player, + SkillDialogue.ONE_OPTION, + Item(unfinishedCrossbowCraftInfo.unstrungCrossbowItemId) + ) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + LimbingScript(player, unfinishedCrossbowCraftInfo, amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (getDynLevel(player, Skills.FLETCHING) < unfinishedCrossbowCraftInfo.level) { + sendLevelCheckFailDialog(player, unfinishedCrossbowCraftInfo.level) + return false + } + if (!hasSpaceFor(player, Item(unfinishedCrossbowCraftInfo.unstrungCrossbowItemId))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + + return true + } + + override fun getAll(index: Int): Int { + return player.inventory.getAmount(stock.asItem()) + } + } + handler.open() + fixTextOverlappingTheCrossbowIcon(player) + return@onUseWith true + } + } + + + private fun fixTextOverlappingTheCrossbowIcon(player: Player) { + PacketRepository.send( + RepositionChild::class.java, + ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 210, 10) + ) + } + + companion object { + fun sendLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue( + player, + "You need a fletching level of $level to attach these limbs." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/crossbow/LimbingScript.kt b/Server/src/main/content/global/skill/fletching/crossbow/LimbingScript.kt new file mode 100644 index 000000000..07fb8ac43 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/crossbow/LimbingScript.kt @@ -0,0 +1,56 @@ +package content.global.skill.fletching.crossbow + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item + +/** + * The queue script for attaching limbs. + * @author Ceikry + * @param player The player + * @param unfinishedCrossbowCraftInfo info about the unfinished (unstrung) crossbow we're crafting + * @param amount to create + */ +class LimbingScript( + private val player: Player, + private val unfinishedCrossbowCraftInfo: UnfinishedCrossbowCraftInfo, + private val amount: Int +) { + + private val initialDelay = 1 + private val subsequentDelay = 6 + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < unfinishedCrossbowCraftInfo.level) { + LimbingListener.sendLevelCheckFailDialog(player, unfinishedCrossbowCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(unfinishedCrossbowCraftInfo.stockItemId), + Item(unfinishedCrossbowCraftInfo.limbItemId) + ) + ) { + addItem(player, unfinishedCrossbowCraftInfo.unstrungCrossbowItemId, 1) + rewardXP(player, Skills.FLETCHING, unfinishedCrossbowCraftInfo.experience) + sendMessage(player, "You attach the metal limbs to the stock.") + animate(player, unfinishedCrossbowCraftInfo.animation) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= amount - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/crossbow/UnfinishedCrossbowCraftInfo.kt b/Server/src/main/content/global/skill/fletching/crossbow/UnfinishedCrossbowCraftInfo.kt new file mode 100644 index 000000000..7250b02e4 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/crossbow/UnfinishedCrossbowCraftInfo.kt @@ -0,0 +1,55 @@ +package content.global.skill.fletching.crossbow + +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different unfinished (unstrung) crossbows + * @author 'Vexia + * @param stockItemId item id of the stock. + * @param limbItemId item id of the limb. + * @param unstrungCrossbowItemId item id of the product. + * @param level the level. + * @param experience the experience. + * @param animation the animation. + */ +enum class UnfinishedCrossbowCraftInfo + ( + val stockItemId: Int, + val limbItemId: Int, + val unstrungCrossbowItemId: Int, + val level: Int, + val experience: Double, + val animation: Animation +) { + WOODEN_STOCK(Items.WOODEN_STOCK_9440, Items.BRONZE_LIMBS_9420, Items.BRONZE_CBOW_U_9454, 9, 12.0, Animation(4436)), + OAK_STOCK(Items.OAK_STOCK_9442, Items.BLURITE_LIMBS_9422, Items.BLURITE_CROSSBOW_9176, 24, 32.0, Animation(4437)), + WILLOW_STOCK(Items.WILLOW_STOCK_9444, Items.IRON_LIMBS_9423, Items.IRON_CBOW_U_9457, 39, 44.0, Animation(4438)), + TEAK_STOCK(Items.TEAK_STOCK_9446, Items.STEEL_LIMBS_9425, Items.STEEL_CBOW_U_9459, 46, 54.0, Animation(4439)), + MAPLE_STOCK(Items.MAPLE_STOCK_9448, Items.MITHRIL_LIMBS_9427, Items.MITHRIL_CBOW_U_9461, 54, 64.0, Animation(4440)), + MAHOGANY_STOCK( + Items.MAHOGANY_STOCK_9450, + Items.ADAMANTITE_LIMBS_9429, + Items.ADAMANT_CBOW_U_9463, + 61, + 82.0, + Animation(4441) + ), + YEW_STOCK(Items.YEW_STOCK_9452, Items.RUNITE_LIMBS_9431, Items.RUNITE_CBOW_U_9465, 69, 100.0, Animation(4442)); + + companion object { + private val unfinishedCrossbowCraftInfoByStockId = values().associateBy { it.stockItemId } + + val limbIds: IntArray = + values().map { unfinishedCrossbowCraftInfo: UnfinishedCrossbowCraftInfo -> unfinishedCrossbowCraftInfo.limbItemId } + .toIntArray() + + val stockIds: IntArray = + values().map { unfinishedCrossbowCraftInfo: UnfinishedCrossbowCraftInfo -> unfinishedCrossbowCraftInfo.stockItemId } + .toIntArray() + + fun forStockId(stockId: Int): UnfinishedCrossbowCraftInfo? { + return unfinishedCrossbowCraftInfoByStockId[stockId] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/darts/DartCraftInfo.kt b/Server/src/main/content/global/skill/fletching/darts/DartCraftInfo.kt new file mode 100644 index 000000000..488075b80 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/darts/DartCraftInfo.kt @@ -0,0 +1,36 @@ +package content.global.skill.fletching.darts + +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different darts + * @author 'Vexia + * @property tipItemId the tip Item id used to craft the dart. + * @property dartItemId the resulting dart Item id. + * @property level the level required to craft. + * @property experience the experience gained by crafting. + */ +enum class DartCraftInfo( + val tipItemId: Int, + val dartItemId: Int, + val level: Int, + val experience: Double) { + + BRONZE_DART(Items.BRONZE_DART_TIP_819, Items.BRONZE_DART_806, 1, 1.8), + IRON_DART(Items.IRON_DART_TIP_820, Items.IRON_DART_807, 22, 3.8), + STEEL_DART(Items.STEEL_DART_TIP_821, Items.STEEL_DART_808, 37, 7.5), + MITHRIL_DART(Items.MITHRIL_DART_TIP_822, Items.MITHRIL_DART_809, 52, 11.2), + ADAMANT_DART(Items.ADAMANT_DART_TIP_823, Items.ADAMANT_DART_810, 67, 15.0), + RUNE_DART(Items.RUNE_DART_TIP_824, Items.RUNE_DART_811, 81, 18.8), + DRAGON_DART(Items.DRAGON_DART_TIP_11232, Items.DRAGON_DART_11230, 95, 25.0); + + companion object { + private val dartCraftInfoByTipIds = values().associateBy { it.tipItemId } + + val tipIDs: IntArray = values().map { dartCraftInfo: DartCraftInfo -> dartCraftInfo.tipItemId }.toIntArray() + + fun fromTipID(dartTipId: Int): DartCraftInfo? { + return dartCraftInfoByTipIds[dartTipId] + } + } +} diff --git a/Server/src/main/content/global/skill/fletching/darts/DartCraftScript.kt b/Server/src/main/content/global/skill/fletching/darts/DartCraftScript.kt new file mode 100644 index 000000000..baecff08c --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/darts/DartCraftScript.kt @@ -0,0 +1,78 @@ +package content.global.skill.fletching.darts + +import content.global.skill.fletching.Feathers +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import kotlin.math.min + +/** + * Represents the queueScript to craft a dart. + * @author ceikry + * @param player the player. + * @param dartCraftInfo contains info about the dart we're crafting. + * @param sets count of sets to make + */ +class DartCraftScript( + private val player: Player, + private val dartCraftInfo: DartCraftInfo, + private var sets: Int +) { + + private val initialDelay = 1 + private val subsequentDelay = 3 + private val maximumDartsCraftableInOneStage = 10 + + private fun getAmountToCraftForThisStage(feathersInInventory: Int, dartTipsInInventory: Int): Int { + val smallerItemAmount = min(feathersInInventory, dartTipsInInventory) + return if (smallerItemAmount > maximumDartsCraftableInOneStage) { + maximumDartsCraftableInOneStage + } else { + smallerItemAmount + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < dartCraftInfo.level) { + DartListeners.sendLevelCheckFailDialog(player, dartCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val dartTipsInInventory = amountInInventory(player, dartCraftInfo.tipItemId) + val feathersInInventory = amountInInventory(player, Feathers.STANDARD) + + val amountToCraft = getAmountToCraftForThisStage(feathersInInventory, dartTipsInInventory) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(Feathers.STANDARD, amountToCraft), + Item(dartCraftInfo.tipItemId, amountToCraft) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach a feather to a dart.") + else -> { + sendMessage(player, "You attach feathers to $amountToCraft darts.") + } + } + + rewardXP(player, Skills.FLETCHING, dartCraftInfo.experience * amountToCraft) + addItem(player, dartCraftInfo.dartItemId, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/darts/DartListeners.kt b/Server/src/main/content/global/skill/fletching/darts/DartListeners.kt new file mode 100644 index 000000000..93b96d2ab --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/darts/DartListeners.kt @@ -0,0 +1,59 @@ +package content.global.skill.fletching.darts + +import content.data.Quests +import content.global.skill.fletching.Feathers +import core.api.* +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import kotlin.math.min + +@Suppress("unused") // Reflectively loaded +class DartListeners : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.ITEM, Feathers.STANDARD, *DartCraftInfo.tipIDs) { player, feather, dartTip -> + val dartCraftInfo = DartCraftInfo.fromTipID(dartTip.id) ?: return@onUseWith false + val handler: SkillDialogueHandler = + object : + SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(dartCraftInfo.dartItemId)) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + DartCraftScript(player, dartCraftInfo, amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (getDynLevel(player, Skills.FLETCHING) < dartCraftInfo.level) { + sendLevelCheckFailDialog(player, dartCraftInfo.level) + return false + } + if (!isQuestComplete(player, Quests.THE_TOURIST_TRAP)) { + sendDialogue(player, "You need to have completed Tourist Trap to fletch darts.") + return false + } + if (!hasSpaceFor(player, Item(dartCraftInfo.dartItemId))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + return true + } + + override fun getAll(index: Int): Int { + return min( + amountInInventory(player, feather.id), + amountInInventory(player, dartTip.id) + ) + } + } + handler.open() + return@onUseWith true + } + } + companion object { + fun sendLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue(player, "You need a fletching level of $level to do this.") + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/gem/AttachGemTipToBoltScript.kt b/Server/src/main/content/global/skill/fletching/gem/AttachGemTipToBoltScript.kt new file mode 100644 index 000000000..c6b1cfdfd --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/gem/AttachGemTipToBoltScript.kt @@ -0,0 +1,77 @@ +package content.global.skill.fletching.gem + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import kotlin.math.min + +/** + * Represents the attaching of a gem tip to a premade bolt. + * @author Ceikry + * @param player the player. + * @param gemBoltCraftInfo crafting info for adding the gem to the bolt + * @param sets the number of sets to craft. + */ +class AttachGemTipToBoltScript( + private val player: Player, + private val gemBoltCraftInfo: GemBoltsCraftInfo, + private val sets: Int +) { + + private val initialDelay = 1 + private val subsequentDelay = 3 + private val maximumGemBoltsCraftableInOneStage = 10 + + private fun getAmountToCraftForThisPulse(untippedBoltsInInventory: Int, tipsInInventory: Int): Int { + val smallerItemAmount = min(untippedBoltsInInventory, tipsInInventory) + return if (smallerItemAmount > maximumGemBoltsCraftableInOneStage) { + maximumGemBoltsCraftableInOneStage + } else { + smallerItemAmount + } + } + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < gemBoltCraftInfo.level) { + GemBoltListeners.sendGemTipAttachLevelCheckFailDialog(player, gemBoltCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val untippedBoltsInInventory = amountInInventory(player, gemBoltCraftInfo.untippedBoltItemId) + val tipsInInventory = amountInInventory(player, gemBoltCraftInfo.tipItemId) + + val amountToCraft = getAmountToCraftForThisPulse(untippedBoltsInInventory, tipsInInventory) + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(gemBoltCraftInfo.untippedBoltItemId, amountToCraft), + Item(gemBoltCraftInfo.tipItemId, amountToCraft) + ) + ) { + when (amountToCraft) { + 1 -> sendMessage(player, "You attach the tip to the bolt.") + else -> { + sendMessage(player, "You fletch $amountToCraft bolts.") + } + } + + rewardXP(player, Skills.FLETCHING, gemBoltCraftInfo.experience * amountToCraft) + addItem(player, gemBoltCraftInfo.tippedBoltItemId, amountToCraft) + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= sets - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/gem/CutGemsIntoBoltTipsScript.kt b/Server/src/main/content/global/skill/fletching/gem/CutGemsIntoBoltTipsScript.kt new file mode 100644 index 000000000..55ea058d0 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/gem/CutGemsIntoBoltTipsScript.kt @@ -0,0 +1,79 @@ +package content.global.skill.fletching.gem + +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item + +/** + * Represents the queue script for cutting gems into bolt tips + * @author Ceikry + * @param player the player. + * @param gemBoltCraftInfo represents the crafting info for the gem we're cutting. + * @param amount the amount to make. + */ +class CutGemsIntoBoltTipsScript( + private val player: Player, + private val gemBoltCraftInfo: GemBoltsCraftInfo, + private val amount: Int +) { + + private val initialDelay = 1 + private val craftDelay = 5 + private val animationDelay = 6 + + private var craftingFinished = false + + private fun invokeAnimationLoop() { + queueScript(player, 0) { + if (craftingFinished) { + return@queueScript stopExecuting(player) + } + animate(player, gemBoltCraftInfo.gemCutAnimationId) + return@queueScript delayScript(player, animationDelay) + } + } + + private fun invokeCraftLoop() { + queueScript(player, 0) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < gemBoltCraftInfo.level) { + craftingFinished = true + GemBoltListeners.sendGemTipCutLevelCheckFailDialog(player, gemBoltCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + val amountOfTipsToCraft = when (gemBoltCraftInfo) { + GemBoltsCraftInfo.PEARLS -> 24 + GemBoltsCraftInfo.PEARL -> 6 + GemBoltsCraftInfo.ONYX -> 24 + else -> 12 + } + + if (removeItem(player, Item(gemBoltCraftInfo.gemItemId))) { + addItem(player, gemBoltCraftInfo.tipItemId, amountOfTipsToCraft) + rewardXP(player, Skills.FLETCHING, gemBoltCraftInfo.experience) + } else { + craftingFinished = true + return@queueScript stopExecuting(player) + } + + if (stage >= amount - 1) { + craftingFinished = true + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, craftDelay, true) + } + } + + fun invoke() { + queueScript(player, initialDelay) { + invokeAnimationLoop() + invokeCraftLoop() + return@queueScript stopExecuting(player) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/gem/GemBoltListeners.kt b/Server/src/main/content/global/skill/fletching/gem/GemBoltListeners.kt new file mode 100644 index 000000000..15ef1d38f --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/gem/GemBoltListeners.kt @@ -0,0 +1,90 @@ +package content.global.skill.fletching.gem + +import core.api.amountInInventory +import core.api.getDynLevel +import core.api.hasSpaceFor +import core.api.sendDialogue +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import kotlin.math.min + +@Suppress("unused") // Reflectively loaded +class GemBoltListeners : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.CHISEL_1755, *GemBoltsCraftInfo.gemIds) { player, _, gem -> + val gemBoltCraftInfo = GemBoltsCraftInfo.forGemId(gem.id) ?: return@onUseWith true + + object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(gemBoltCraftInfo.gemItemId)) { + override fun create(amount: Int, index: Int) { + if (getDynLevel(player, Skills.FLETCHING) < gemBoltCraftInfo.level) { + sendGemTipCutLevelCheckFailDialog(player, gemBoltCraftInfo.level) + return + } + CutGemsIntoBoltTipsScript(player, gemBoltCraftInfo, amount).invoke() + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, gemBoltCraftInfo.gemItemId) + } + }.open() + return@onUseWith true + } + + onUseWith( + IntType.ITEM, + GemBoltsCraftInfo.untippedBoltIds, + *GemBoltsCraftInfo.boltTipIds + ) { player, untippedBolt, boltTip -> + val bolt = GemBoltsCraftInfo.forTipId(boltTip.id) ?: return@onUseWith false + if (untippedBolt.id != bolt.untippedBoltItemId) return@onUseWith false + + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(bolt.tippedBoltItemId)) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements()) return + AttachGemTipToBoltScript(player, bolt, amount).invoke() + } + + private fun playerMeetsInitialRequirements(): Boolean { + if (getDynLevel(player, Skills.FLETCHING) < bolt.level) { + sendGemTipAttachLevelCheckFailDialog(player, bolt.level) + return false + } + if (!hasSpaceFor(player, Item(bolt.tippedBoltItemId))) { + sendDialogue(player, "You do not have enough inventory space.") + return false + } + return true + } + + override fun getAll(index: Int): Int { + return min(amountInInventory(player, untippedBolt.id), amountInInventory(player, boltTip.id)) + } + } + handler.open() + return@onUseWith true + } + } + + companion object { + fun sendGemTipCutLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue( + player, + "You need a Fletching level of $level or above to do that." + ) + } + + fun sendGemTipAttachLevelCheckFailDialog(player: Player, level: Int) { + sendDialogue( + player, + "You need a Fletching level of $level or above to do that." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/gem/GemBoltsCraftInfo.kt b/Server/src/main/content/global/skill/fletching/gem/GemBoltsCraftInfo.kt new file mode 100644 index 000000000..d0e2b0f11 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/gem/GemBoltsCraftInfo.kt @@ -0,0 +1,106 @@ +package content.global.skill.fletching.gem + +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different gem tipped bolts + * @property untippedBoltItemId the base untipped bolt item id + * @property gemItemId the gem item id used to craft the bolt tips + * @property gemCutAnimationId the animation to play when the player cuts the gem + * @property tipItemId the item id of the resulting bolt tips + * @property tippedBoltItemId the item id of the finished gem-tipped bolt + * @property level the required level to craft the gem tipped bolt or tips themselves + * @property experience gained creating one set of gem tips, or per bolt tipped + */ +enum class GemBoltsCraftInfo( + var untippedBoltItemId: Int, + var gemItemId: Int, + var gemCutAnimationId: Int, + var tipItemId: Int, + var tippedBoltItemId: Int, + var level: Int, + var experience: Double +) { + OPAL(Items.BRONZE_BOLTS_877, Items.OPAL_1609, 890, Items.OPAL_BOLT_TIPS_45, Items.OPAL_BOLTS_879, 11, 1.6), + JADE(Items.BLURITE_BOLTS_9139, Items.JADE_1611, 891, Items.JADE_BOLT_TIPS_9187, Items.JADE_BOLTS_9335, 26, 2.4), + PEARL(Items.IRON_BOLTS_9140, Items.OYSTER_PEARL_411, 4470, Items.PEARL_BOLT_TIPS_46, Items.PEARL_BOLTS_880, 41, 3.2), + PEARLS( + Items.IRON_BOLTS_9140, + Items.OYSTER_PEARLS_413, + 4470, + Items.PEARL_BOLT_TIPS_46, + Items.PEARL_BOLTS_880, + 41, + 3.2 + ), + RED_TOPAZ( + Items.STEEL_BOLTS_9141, + Items.RED_TOPAZ_1613, + 892, + Items.TOPAZ_BOLT_TIPS_9188, + Items.TOPAZ_BOLTS_9336, + 48, + 3.9 + ), + SAPPHIRE( + Items.MITHRIL_BOLTS_9142, + Items.SAPPHIRE_1607, + 888, + Items.SAPPHIRE_BOLT_TIPS_9189, + Items.SAPPHIRE_BOLTS_9337, + 56, + 4.7 + ), + EMERALD( + Items.MITHRIL_BOLTS_9142, + Items.EMERALD_1605, + 889, + Items.EMERALD_BOLT_TIPS_9190, + Items.EMERALD_BOLTS_9338, + 58, + 5.5 + ), + RUBY(Items.ADAMANT_BOLTS_9143, Items.RUBY_1603, 887, Items.RUBY_BOLT_TIPS_9191, Items.RUBY_BOLTS_9339, 63, 6.3), + DIAMOND( + Items.ADAMANT_BOLTS_9143, + Items.DIAMOND_1601, + 886, + Items.DIAMOND_BOLT_TIPS_9192, + Items.DIAMOND_BOLTS_9340, + 65, + 7.0 + ), + DRAGONSTONE( + Items.RUNE_BOLTS_9144, + Items.DRAGONSTONE_1615, + 885, + Items.DRAGON_BOLT_TIPS_9193, + Items.DRAGON_BOLTS_9341, + 71, + 8.2 + ), + ONYX(Items.RUNE_BOLTS_9144, Items.ONYX_6573, 2717, Items.ONYX_BOLT_TIPS_9194, Items.ONYX_BOLTS_9342, 73, 9.4); + + companion object { + private val gemBoltCraftInfoByGemId = values().associateBy { it.gemItemId } + private val gemBoltCraftInfoByBoltTipId = values().associateBy { it.tipItemId } + + val untippedBoltIds: IntArray = + values().map { gemBoltsCraftInfo: GemBoltsCraftInfo -> gemBoltsCraftInfo.untippedBoltItemId }.distinct() + .toIntArray() + + val gemIds: IntArray = + values().map { gemBoltsCraftInfo: GemBoltsCraftInfo -> gemBoltsCraftInfo.gemItemId }.toIntArray() + + val boltTipIds: IntArray = + values().map { gemBoltsCraftInfo: GemBoltsCraftInfo -> gemBoltsCraftInfo.tipItemId }.toIntArray() + + fun forGemId(gemId: Int): GemBoltsCraftInfo? { + return gemBoltCraftInfoByGemId[gemId] + } + + fun forTipId(tipId: Int): GemBoltsCraftInfo? { + return gemBoltCraftInfoByBoltTipId[tipId] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/grapple/GrappleListeners.kt b/Server/src/main/content/global/skill/fletching/grapple/GrappleListeners.kt new file mode 100644 index 000000000..46373cda0 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/grapple/GrappleListeners.kt @@ -0,0 +1,67 @@ +package content.global.skill.fletching.grapple + +import core.api.* +import core.game.interaction.Clocks +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items + +@Suppress("unused") // Reflectively loaded +class GrappleListeners : InteractionListener { + private val mithrilBolt = Items.MITHRIL_BOLTS_9142 + private val mithrilGrappleTip = Items.MITH_GRAPPLE_TIP_9416 + private val rope = Items.ROPE_954 + private val mithrilGrapple = Items.MITH_GRAPPLE_9418 + private val mithrilGrappleWithRope = Items.MITH_GRAPPLE_9419 + + override fun defineListeners() { + onUseWith(IntType.ITEM, mithrilBolt, mithrilGrappleTip) { player, bolt, tip -> + if (getDynLevel(player, Skills.FLETCHING) < 59) { + sendMessage(player, "You need a fletching level of 59 to make this.") + return@onUseWith true + } + queueScript(player, 0) { _ -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + if (removeItemsIfPlayerHasEnough( + player, + Item(mithrilBolt, 1), + tip.asItem() + ) + ) { + addItem(player, mithrilGrapple, 1) + } + + delayClock(player, Clocks.SKILLING, 3) + return@queueScript stopExecuting(player) + } + + + return@onUseWith true + } + + onUseWith(IntType.ITEM, rope, mithrilGrapple) { player, rope, grapple -> + if (getDynLevel(player, Skills.FLETCHING) < 59) { + sendMessage(player, "You need a fletching level of 59 to make this.") + return@onUseWith true + } + queueScript(player, 0) { _ -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + if (removeItemsIfPlayerHasEnough( + player, + rope.asItem(), + grapple.asItem() + ) + ) { + addItem(player, mithrilGrappleWithRope, 1) + } + delayClock(player, Clocks.SKILLING, 3) + return@queueScript stopExecuting(player) + } + return@onUseWith true + } + + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHead.java b/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHead.java deleted file mode 100644 index c7ab5ec7c..000000000 --- a/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHead.java +++ /dev/null @@ -1,123 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.arrow; - -import org.crandor.game.node.item.Item; - -*/ -/** - * Represents the enum storing the arrow head information. - * @author 'Vexia - * @note brutal arrows after quest. - *//* - -public enum ArrowHead { - BRONZE_ARROW(new Item(39), new Item(882), 1, 2.6), - IRON_ARROW(new Item(40), new Item(884), 15, 3.8), - STEEL_ARROW(new Item(41), new Item(886), 30, 6.3), - MITHRIL_ARROW(new Item(42), new Item(888), 45, 8.8), - ADAMANT_ARROW(new Item(43), new Item(890), 60, 10), - RUNE_ARROW(new Item(44), new Item(892), 75, 13.8), - DRAGON_ARROW(new Item(11237), new Item(11212), 90, 16.3), - BROAD_ARROW(new Item(13278), new Item(4160), 52, 10); - - */ -/** - * Constructs a new {@code ArrowHead.java} {@code Object}. - * @param item the item. - * @param product the product. - * @param level the level. - * @param experience the experience. - *//* - - ArrowHead(Item item, Item product, int level, double experience) { - this.item = item; - this.product = product; - this.level = level; - this.experience = experience; - } - - */ -/** - * Represents the arrow tip. - *//* - - private final Item item; - - */ -/** - * Represents the product item. - *//* - - private final Item product; - - */ -/** - * Represents the level required. - *//* - - private final int level; - - */ -/** - * Represents the experience gained. - *//* - - private final double experience; - - */ -/** - * Gets the item. - * @return The item. - *//* - - public Item getTips() { - return item; - } - - */ -/** - * Gets the product. - * @return The product. - *//* - - public Item getProduct() { - return product; - } - - */ -/** - * Gets the level. - * @return The level. - *//* - - public int getLevel() { - return level; - } - - */ -/** - * Gets the experience. - * @return The experience. - *//* - - public double getExperience() { - return experience; - } - - */ -/** - * Gets the arrow head. - * @param item the item. - * @return the arrow head. - *//* - - public static ArrowHead forItem(final Item item) { - for (ArrowHead arrow : ArrowHead.values()) { - if (arrow.getTips().getId() == item.getId()) { - return arrow; - } - } - return null; - } -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHeadPulse.java b/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHeadPulse.java deleted file mode 100644 index 5ea27c2cc..000000000 --- a/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHeadPulse.java +++ /dev/null @@ -1,110 +0,0 @@ -package content.global.skill.fletching.items.arrow; - -import content.global.skill.slayer.SlayerManager; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import content.global.skill.fletching.Fletching; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -import static core.api.ContentAPIKt.*; - -/** - * Represents the arrow head pulse to complete the headless arrow. - * @author 'Vexia - */ -public class ArrowHeadPulse extends SkillPulse { - - /** - * Represents the headless arrow item. - */ - private static final Item HEADLESS_ARROW = new Item(53); - - /** - * Represents the arrow head. - */ - private final Fletching.ArrowHeads arrow; - - /** - * Represents the sets to do. - */ - private int sets; - - /** - * Constructs a new {@code ArrowHeadPulse.java} {@code Object}. - * @param player the player. - * @param node the node. - * @param arrow the arrow. - * @param sets the sets. - */ - public ArrowHeadPulse(final Player player, final Item node, final Fletching.ArrowHeads arrow, final int sets) { - super(player, node); - this.arrow = arrow; - this.sets = sets; - } - - @Override - public boolean checkRequirements() { - if (arrow.unfinished == 4160) { - if (!SlayerManager.getInstance(player).flags.isBroadsUnlocked()) { - player.getDialogueInterpreter().sendDialogue("You need to unlock the ability to create broad arrows."); - return false; - } - } - if (player.getSkills().getLevel(Skills.FLETCHING) < arrow.level) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + arrow.level + " to do this."); - return false; - } - if (!hasSpaceFor(player, arrow.getFinished())) { - sendDialogue(player, "You do not have enough inventory space."); - return false; - } - return true; - } - - @Override - public void animate() { - } - - @Override - public boolean reward() { - if (getDelay() == 1) { - super.setDelay(3); - } - Item tip = arrow.getUnfinished(); - int tipAmount = player.getInventory().getAmount(arrow.unfinished); - int shaftAmount = player.getInventory().getAmount(HEADLESS_ARROW); - if (tipAmount >= 15 && shaftAmount >= 15) { - HEADLESS_ARROW.setAmount(15); - tip.setAmount(15); - player.getPacketDispatch().sendMessage("You attach arrow heads to 15 arrow shafts."); - } else { - int amount = tipAmount > shaftAmount ? shaftAmount : tipAmount; - HEADLESS_ARROW.setAmount(amount); - tip.setAmount(amount); - player.getPacketDispatch().sendMessage(amount == 1 ? "You attach an arrow head to an arrow shaft." : "You attach arrow heads to " + amount + " arrow shafts."); - } - if (player.getInventory().remove(HEADLESS_ARROW, tip)) { - player.getSkills().addExperience(Skills.FLETCHING, arrow.experience * tip.getAmount(), true); - Item product = arrow.getFinished(); - product.setAmount(tip.getAmount()); - player.getInventory().add(product); - } - HEADLESS_ARROW.setAmount(1); - tip.setAmount(1); - if (!player.getInventory().containsItem(HEADLESS_ARROW)) { - return true; - } - if (!player.getInventory().containsItem(tip)) { - return true; - } - sets--; - return sets == 0; - } - - @Override - public void message(int type) { - - } - -} diff --git a/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessArrowPulse.java b/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessArrowPulse.java deleted file mode 100644 index 3125b5669..000000000 --- a/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessArrowPulse.java +++ /dev/null @@ -1,145 +0,0 @@ -package content.global.skill.fletching.items.arrow; - -import org.rs09.consts.Items; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -import static core.api.ContentAPIKt.*; - -/** - * Represents the arrow pulse for creating unfinished arrows. - * @author 'Vexia - */ -public final class HeadlessArrowPulse extends SkillPulse { - - /** - * Represents the headless arrow item. - */ - private final Item HEADLESS_ARROW = new Item(Items.HEADLESS_ARROW_53); - - /** - * Represents the arrow shaft item. - */ - private final Item ARROW_SHAFT = new Item(Items.ARROW_SHAFT_52); - - /** - * Represents the feather items. - */ - private static final Item[] FEATHER = new Item[] { - new Item(Items.FEATHER_314), - new Item(Items.STRIPY_FEATHER_10087), - new Item(Items.RED_FEATHER_10088), - new Item(Items.BLUE_FEATHER_10089), - new Item(Items.YELLOW_FEATHER_10090), - new Item(Items.ORANGE_FEATHER_10091) - }; - - /** - * The feather being used. - */ - private Item feather; - - /** - * Represents the amount to make. - */ - private int sets; - - /** - * Represents if we should use sets, meaning we have 15 & 15 arrow shafts and feathers. - */ - private boolean useSets = false; - - /** - * Constructs a new {@code ArrowPulse.java} {@code Object}. - * @param player the player. - * @param node the node. - */ - public HeadlessArrowPulse(Player player, Item node, Item feather, int sets) { - super(player, node); - this.sets = sets; - this.feather = feather; - } - - @Override - public boolean checkRequirements() { - if (!player.getInventory().containsItem(ARROW_SHAFT)) { - player.getDialogueInterpreter().sendDialogue("You don't have any arrow shafts."); - return false; - } - if (feather == null || !player.getInventory().containsItem(feather)) { - player.getDialogueInterpreter().sendDialogue("You don't have any feathers."); - return false; - } - if (player.getInventory().contains(ARROW_SHAFT.getId(), 15) && player.getInventory().contains(feather.getId(), 15)) { - useSets = true; - } else { - useSets = false; - } - if (!hasSpaceFor(player, HEADLESS_ARROW.asItem())) { - sendDialogue(player, "You do not have enough inventory space."); - return false; - } - return true; - } - - @Override - public void animate() { - } - - @Override - public boolean reward() { - int featherAmount = player.getInventory().getAmount(feather); - int shaftAmount = player.getInventory().getAmount(ARROW_SHAFT); - if (getDelay() == 1) { - super.setDelay(3); - } - if (featherAmount >= 15 && shaftAmount >= 15) { - feather.setAmount(15); - ARROW_SHAFT.setAmount(15); - player.getPacketDispatch().sendMessage("You attach feathers to 15 arrow shafts."); - } else { - int amount = Math.min(featherAmount, shaftAmount); - feather.setAmount(amount); - ARROW_SHAFT.setAmount(amount); - player.getPacketDispatch().sendMessage(amount == 1 - ? "You attach a feathers to a shaft." : "You attach feathers to " + amount + " arrow shafts."); - } - if (player.getInventory().remove(feather, ARROW_SHAFT)) { - HEADLESS_ARROW.setAmount(feather.getAmount()); - player.getSkills().addExperience(Skills.FLETCHING, HEADLESS_ARROW.getAmount(), true); - player.getInventory().add(HEADLESS_ARROW); - } - HEADLESS_ARROW.setAmount(1); - feather.setAmount(1); - ARROW_SHAFT.setAmount(1); - if (!player.getInventory().containsItem(ARROW_SHAFT)) { - return true; - } - if (!player.getInventory().containsItem(feather)) { - return true; - } - sets--; - return sets <= 0; - } - - @Override - public void message(int type) { - } - - /** - * Gets the feather item. - * @return the item. - */ - private Item getFeather() { - int length = FEATHER.length; - for (int i = 0; i < length; i++) { - Item f = FEATHER[i]; - if (player.getInventory().containsItem(f)) { - return f; - } - } - return null; - } -} diff --git a/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessOgreArrowPulse.java b/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessOgreArrowPulse.java deleted file mode 100644 index fd7af6731..000000000 --- a/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessOgreArrowPulse.java +++ /dev/null @@ -1,131 +0,0 @@ -package content.global.skill.fletching.items.arrow; - -import core.game.node.entity.player.Player; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import core.game.node.item.Item; -import org.rs09.consts.Items; - -import static core.api.ContentAPIKt.hasSpaceFor; -import static core.api.ContentAPIKt.sendDialogue; - -/** - * Represents the arrow pulse for creating unfinished ogre arrows. - * @author 'Vexia - */ -public final class HeadlessOgreArrowPulse extends SkillPulse { - - /** - * Represents the headless ogre arrow item. - */ - private final Item HEADLESS_ARROW = new Item(Items.FLIGHTED_OGRE_ARROW_2865); - - /** - * Represents the ogre arrow shaft item. - */ - private final Item ARROW_SHAFT = new Item(Items.OGRE_ARROW_SHAFT_2864); - - /** - * Represents the feather items. - */ - private static final Item[] FEATHER = new Item[] { - new Item(Items.FEATHER_314, 4), - }; - - /** - * The feather being used. - */ - private Item feather; - - /** - * Represents the amount to make. - */ - private int sets; - - /** - * Constructs a new {@code ArrowPulse.java} {@code Object}. - * @param player the player. - * @param node the node. - */ - public HeadlessOgreArrowPulse(Player player, Item node, Item feather, int sets) { - super(player, node); - this.sets = sets; - this.feather = feather; - } - - @Override - public boolean checkRequirements() { - if (!player.getInventory().containsItem(ARROW_SHAFT)) { - player.getDialogueInterpreter().sendDialogue("You don't have any arrow shafts."); - return false; - } - if (feather == null || !player.getInventory().containsItem(feather)) { - player.getDialogueInterpreter().sendDialogue("You don't have any feathers."); - return false; - } - if (!hasSpaceFor(player, HEADLESS_ARROW.asItem())) { - sendDialogue(player, "You do not have enough inventory space."); - return false; - } - return true; - } - - @Override - public void animate() { - } - - @Override - public boolean reward() { - int featherAmount = player.getInventory().getAmount(feather); - int shaftAmount = player.getInventory().getAmount(ARROW_SHAFT); - if (getDelay() == 1) { - super.setDelay(3); - } - if (featherAmount >= 24 && shaftAmount >= 6) { - feather.setAmount(24); - ARROW_SHAFT.setAmount(6); - player.getPacketDispatch().sendMessage("You attach 24 feathers to 6 ogre arrow shafts."); - } else { - int amount = Math.min(featherAmount / 4, shaftAmount); - feather.setAmount(amount*4); - ARROW_SHAFT.setAmount(amount); - player.getPacketDispatch().sendMessage(amount == 1 - ? "You attach a feathers to a shaft." : "You attach " + amount * 4 + " feathers to " + amount + " ogre arrow shafts."); - } - if (player.getInventory().remove(feather, ARROW_SHAFT)) { - HEADLESS_ARROW.setAmount(ARROW_SHAFT.getAmount()); - player.getSkills().addExperience(Skills.FLETCHING, HEADLESS_ARROW.getAmount(), true); - player.getInventory().add(HEADLESS_ARROW); - } - HEADLESS_ARROW.setAmount(1); - feather.setAmount(1); - ARROW_SHAFT.setAmount(1); - if (!player.getInventory().containsItem(ARROW_SHAFT)) { - return true; - } - if (!player.getInventory().containsItem(feather)) { - return true; - } - sets--; - return sets <= 0; - } - - @Override - public void message(int type) { - } - - /** - * Gets the feather item. - * @return the item. - */ - private Item getFeather() { - int length = FEATHER.length; - for (int i = 0; i < length; i++) { - Item f = FEATHER[i]; - if (player.getInventory().containsItem(f)) { - return f; - } - } - return null; - } -} diff --git a/Server/src/main/content/global/skill/fletching/items/bolts/Bolt.java b/Server/src/main/content/global/skill/fletching/items/bolts/Bolt.java deleted file mode 100644 index f877050db..000000000 --- a/Server/src/main/content/global/skill/fletching/items/bolts/Bolt.java +++ /dev/null @@ -1,123 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.bolts; - -import org.crandor.game.node.item.Item; - -*/ -/** - * Represents an enum of bolts. - * @author 'Vexia - *//* - -public enum Bolt { - BRONZE_BOLT(new Item(9375), new Item(877), 9, 0.5), - BLURITE_BOLT(new Item(9376), new Item(9139), 24, 1), - IRON_BOLT(new Item(9377), new Item(9140), 39, 1.5), - SILVER_BOLT(new Item(9382), new Item(9145), 43, 2.5), - STEEL_BOLT(new Item(9378), new Item(9141), 46, 3.5), - MITHRIL_BOLT(new Item(9379), new Item(9142), 54, 5), - ADAMANTITE_BOLT(new Item(9380), new Item(9143), 61, 7), - RUNITE_BOLT(new Item(9381), new Item(9144), 69, 10), - BROAD_BOLT(new Item(13279), new Item(13280), 55, 3); - - */ -/** - * The item required. - *//* - - private final Item item; - - */ -/** - * The product recieved. - *//* - - private final Item product; - - */ -/** - * The level required. - *//* - - private final int level; - - */ -/** - * The experience gained. - *//* - - private final double experience; - - */ -/** - * Constructs a new {@code Bolt} {@code Object}. - * @param item the item. - * @param product the product. - * @param level the level. - * @param experience the experienece. - *//* - - Bolt(Item item, Item product, int level, double experience) { - this.item = item; - this.product = product; - this.level = level; - this.experience = experience; - } - - */ -/** - * Gets the item. - * @return The item. - *//* - - public Item getItem() { - return item; - } - - */ -/** - * Gets the product. - * @return The product. - *//* - - public Item getProduct() { - return product; - } - - */ -/** - * Gets the level. - * @return The level. - *//* - - public int getLevel() { - return level; - } - - */ -/** - * Gets the experience. - * @return The experience. - *//* - - public double getExperience() { - return experience; - } - - */ -/** - * Method used to get the bolt for the item. - * @param item the item. - * @return the bolt. - *//* - - public static Bolt forItem(final Item item) { - for (Bolt bolt : Bolt.values()) { - if (bolt.getItem().getId() == item.getId()) { - return bolt; - } - } - return null; - } -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/items/bolts/BoltPulse.java b/Server/src/main/content/global/skill/fletching/items/bolts/BoltPulse.java deleted file mode 100644 index b345c4276..000000000 --- a/Server/src/main/content/global/skill/fletching/items/bolts/BoltPulse.java +++ /dev/null @@ -1,130 +0,0 @@ -package content.global.skill.fletching.items.bolts; - -import content.global.skill.slayer.SlayerManager; -import org.rs09.consts.Items; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import content.global.skill.fletching.Fletching; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the bolt pulse class to make bolts. - * @author ceik - */ -public final class BoltPulse extends SkillPulse { - - /** - * Represents the feather item. - */ - private Item feather; - - /** - * Represents possible feather Items - */ - private static final Item[] FEATHER = new Item[] { - new Item(Items.FEATHER_314), - new Item(Items.STRIPY_FEATHER_10087), - new Item(Items.RED_FEATHER_10088), - new Item(Items.BLUE_FEATHER_10089), - new Item(Items.YELLOW_FEATHER_10090), - new Item(Items.ORANGE_FEATHER_10091) - }; - - /** - * Represents the bolt. - */ - private final Fletching.Bolts bolt; - - /** - * Represents the sets to do. - */ - private int sets; - - /** - * Represents if we're using sets. - */ - private boolean useSets = false; - - /** - * Constructs a new {@code BoltPulse.java} {@code Object}. - * @param player the player. - * @param node the node. - */ - public BoltPulse(Player player, Item node, final Fletching.Bolts bolt, final Item feather, final int sets) { - super(player, node); - this.bolt = bolt; - this.sets = sets; - this.feather = feather; - } - - @Override - public boolean checkRequirements() { - if (bolt.getUnfinished().getId() == 13279) { - if (!SlayerManager.getInstance(player).flags.isBroadsUnlocked()) { - player.getDialogueInterpreter().sendDialogue("You need to unlock the ability to create broad bolts."); - return false; - } - } - if (player.getSkills().getLevel(Skills.FLETCHING) < bolt.level) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + bolt.level + " in order to do this."); - return false; - } - if (!player.getInventory().containsItem(feather)) { - return false; - } - if (!player.getInventory().containsItem(bolt.getUnfinished())) { - return false; - } - if (!player.getInventory().hasSpaceFor(bolt.getFinished())) { - player.getDialogueInterpreter().sendDialogue("You do not have enough inventory space."); - return false; - } - - return true; - } - - @Override - public void animate() { - } - - @Override - public boolean reward() { - int featherAmount = player.getInventory().getAmount(feather); - int boltAmount = player.getInventory().getAmount(bolt.unfinished); - if (getDelay() == 1) { - super.setDelay(3); - } - final Item unfinished = bolt.getUnfinished(); - if (featherAmount >= 10 && boltAmount >= 10) { - feather.setAmount(10); - unfinished.setAmount(10); - player.getPacketDispatch().sendMessage("You fletch 10 bolts."); - } else { - int amount = featherAmount > boltAmount ? boltAmount : featherAmount; - feather.setAmount(amount); - unfinished.setAmount(amount); - player.getPacketDispatch().sendMessage(amount == 1 ? "You attach a feather to a bolt." : "You fletch " + amount + " bolts"); - } - if (player.getInventory().remove(feather, unfinished)) { - Item product = bolt.getFinished(); - product.setAmount(feather.getAmount()); - player.getSkills().addExperience(Skills.FLETCHING, product.getAmount() * bolt.experience, true); - player.getInventory().add(product); - } - feather.setAmount(1); - if (!player.getInventory().containsItem(feather)) { - return true; - } - if (!player.getInventory().containsItem(bolt.getUnfinished())) { - return true; - } - sets--; - return sets <= 0; - } - - @Override - public void message(int type) { - } - -} diff --git a/Server/src/main/content/global/skill/fletching/items/bow/StringBow.java b/Server/src/main/content/global/skill/fletching/items/bow/StringBow.java deleted file mode 100644 index 0187f17bb..000000000 --- a/Server/src/main/content/global/skill/fletching/items/bow/StringBow.java +++ /dev/null @@ -1,136 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.bow; - -import org.crandor.game.node.item.Item; -import org.crandor.game.world.update.flag.context.Animation; - -*/ -/** - * Represents the enum of stringing bows. - * @author 'Vexia - *//* - -public enum StringBow { - SHORT_BOW(new Item(50), new Item(841), 5, 5, new Animation(6678)), - LONG_BOW(new Item(48), new Item(839), 10, 10, new Animation(6684)), - OAK_SHORTBOW(new Item(54), new Item(843), 20, 16.5, new Animation(6679)), - OAK_LONGBOW(new Item(56), new Item(845), 25, 25, new Animation(6685)), - WILLOW_SHORTBOW(new Item(60), new Item(849), 35, 33.3, new Animation(6680)), - WILLOW_LONGBOW(new Item(58), new Item(847), 40, 41.5, new Animation(6686)), - MAPLE_SHORTBOW(new Item(64), new Item(853), 50, 50, new Animation(6681)), - MAPLE_LONGBOW(new Item(62), new Item(851), 55, 58.3, new Animation(6687)), - YEW_SHORTBOW(new Item(68), new Item(857), 65, 66, new Animation(6682)), - YEW_LONGBOW(new Item(66), new Item(855), 70, 75, new Animation(6688)), - MAGIC_SHORTBOW(new Item(72), new Item(861), 80, 83.3, new Animation(6683)), - MAGIC_LONGBOW(new Item(70), new Item(859), 85, 91.5, new Animation(6689)); - - - StringBow(final Item item, final Item product, final int level, final double experience, final Animation animation) { - this.item = item; - this.product = product; - this.level = level; - this.experience = experience; - this.animation = animation; - } - - */ -/** - * The item required. - *//* - - private final Item item; - - */ -/** - * The item product. - *//* - - private final Item product; - - */ -/** - * The level required. - *//* - - private final int level; - - */ -/** - * The experience required. - *//* - - private final double experience; - - */ -/** - * The animation of stringing. - *//* - - private final Animation animation; - - */ -/** - * Gets the item. - * @return The item. - *//* - - public Item getItem() { - return item; - } - - */ -/** - * Gets the product. - * @return The product. - *//* - - public Item getProduct() { - return product; - } - - */ -/** - * Gets the level. - * @return The level. - *//* - - public int getLevel() { - return level; - } - - */ -/** - * Gets the experience. - * @return The experience. - *//* - - public double getExperience() { - return experience; - } - - */ -/** - * Method used to get the animation. - * @return the animation. - *//* - - public Animation getAnimation() { - return animation; - } - - */ -/** - * Method used to get the string bow for the item. - * @param item the item. - * @return the string bow. - *//* - - public static StringBow forItem(final int id) { - for (StringBow bw : StringBow.values()) { - if (bw.getItem().getId() == id) { - return bw; - } - } - return null; - } -}*/ diff --git a/Server/src/main/content/global/skill/fletching/items/bow/StringPulse.java b/Server/src/main/content/global/skill/fletching/items/bow/StringPulse.java deleted file mode 100644 index 0d8645e44..000000000 --- a/Server/src/main/content/global/skill/fletching/items/bow/StringPulse.java +++ /dev/null @@ -1,103 +0,0 @@ -package content.global.skill.fletching.items.bow; - -import core.game.node.entity.player.info.LogType; -import core.game.node.entity.player.info.PlayerMonitor; -import core.game.node.entity.player.link.diary.DiaryType; -import core.game.world.map.zone.ZoneBorders; -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import content.global.skill.fletching.Fletching; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -import static core.api.ContentAPIKt.amountInInventory; - -/** - * Represents the skill pulse of stringing. - * - * @author Ceikry - */ -public class StringPulse extends SkillPulse { - - /** - * Represents the string bow. - */ - private final Fletching.String bow; - - /** - * The amount. - */ - private int amount; - - private int initialAmount; - private int processedAmount; - - /** - * Constructs a new {@code StringbowPlugin.java} {@code Object}. - * - * @param player the player. - * @param node the node. - */ - public StringPulse(Player player, Item node, final Fletching.String bow, int amount) { - super(player, node); - this.bow = bow; - this.amount = amount; - this.initialAmount = amountInInventory(player, node.getId()); - this.processedAmount = 0; - } - - @Override - public boolean checkRequirements() { - if (getDelay() == 1) { - setDelay(2); - } - if (player.getSkills().getLevel(Skills.FLETCHING) < bow.level) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + bow.level + " to string this bow."); - return false; - } - if (!player.getInventory().containsItem(new Item(bow.unfinished))) { - return false; - } - if (!player.getInventory().containsItem(new Item(bow.string))) { - player.getDialogueInterpreter().sendDialogue("You seem to have run out of bow strings."); - return false; - } - animate(); - return true; - } - - @Override - public void animate() { - player.animate(bow.animation); - } - - @Override - public boolean reward() { - if (player.getInventory().remove(new Item(bow.unfinished), new Item(bow.string))) { - player.getInventory().add(new Item(bow.product)); - player.getSkills().addExperience(Skills.FLETCHING, bow.experience, true); - player.getPacketDispatch().sendMessage("You add a string to the bow."); - processedAmount++; - if (processedAmount > initialAmount) { - PlayerMonitor.log(player, LogType.DUPE_ALERT, "fletched item (" + player.getName() + ", " + bow.unfinished + "): initialAmount " + initialAmount + ", processedAmount " + processedAmount); - } - - if (bow == Fletching.String.MAGIC_SHORTBOW - && (new ZoneBorders(2721, 3489, 2724, 3493, 0).insideBorder(player) - || new ZoneBorders(2727, 3487, 2730, 3490, 0).insideBorder(player)) - && player.getAttribute("diary:seers:fletch-magic-short-bow", false)) { - player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 2); - } - } - if (!player.getInventory().containsItem(new Item(bow.string)) || !player.getInventory().containsItem(new Item(bow.unfinished))) { - return true; - } - amount--; - return amount == 0; - } - - @Override - public void message(int type) { - } - -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/CrossbowPulse.java b/Server/src/main/content/global/skill/fletching/items/crossbow/CrossbowPulse.java deleted file mode 100644 index cfe0cf53b..000000000 --- a/Server/src/main/content/global/skill/fletching/items/crossbow/CrossbowPulse.java +++ /dev/null @@ -1,97 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.crossbow; - -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import org.crandor.game.node.entity.player.Player; -import org.crandor.game.node.item.Item; - -*/ -/** - * Represents the skill pulse of stringing. - * @author 'Vexia - *//* - -public class CrossbowPulse extends SkillPulse { - - */ -/** - * Represents the bow string item. - *//* - - private final Item BOW_STRING = new Item(9438); - - */ -/** - * Represents the string bow. - *//* - - private final StringCross bow; - - */ -/** - * Represents the amount. - *//* - - private int amount; - - */ -/** - * Constructs a new {@code StringcrossbowPlugin.java} {@code Object}. - * @param player the player. - * @param node the node. - *//* - - public CrossbowPulse(Player player, Item node, final StringCross bow, int amount) { - super(player, node); - this.bow = bow; - this.amount = amount; - } - - @Override - public boolean checkRequirements() { - if (player.getSkills().getLevel(Skills.FLETCHING) < bow.getLevel()) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + bow.getLevel() + " to string this crossbow."); - return false; - } - if (!player.getInventory().containsItem(BOW_STRING)) { - player.getDialogueInterpreter().sendDialogue("You seem to have run out of bow strings."); - return false; - } - return true; - } - - @Override - public void animate() { - player.animate(bow.getAnimation()); - } - - @Override - public boolean reward() { - if (getDelay() == 1) { - super.setDelay(5); - return false; - } - if (player.getInventory().remove(bow.getItem(), BOW_STRING)) { - player.getInventory().add(bow.getProduct()); - player.getSkills().addExperience(Skills.FLETCHING, bow.getExperience(), true); - player.getPacketDispatch().sendMessage("You add a string to the crossbow."); - } - if (!player.getInventory().containsItem(BOW_STRING) || !player.getInventory().containsItem(bow.getItem())) { - return true; - } - amount--; - return amount == 0; - } - - @Override - public void message(int type) { - switch (type) { - case 0: - break; - case 1: - break; - } - } - -}*/ diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/Limb.java b/Server/src/main/content/global/skill/fletching/items/crossbow/Limb.java deleted file mode 100644 index 6ffc01413..000000000 --- a/Server/src/main/content/global/skill/fletching/items/crossbow/Limb.java +++ /dev/null @@ -1,128 +0,0 @@ -package content.global.skill.fletching.items.crossbow; - -import core.game.node.item.Item; -import core.game.world.update.flag.context.Animation; - -/** - * Represents the enum for limbs. - * @author 'Vexia - */ -public enum Limb { - WOODEN_STOCK(new Item(9440), new Item(9420), new Item(9454), 9, 12, new Animation(4436)), - OAK_STOCK(new Item(9442), new Item(9422), new Item(9176), 24, 32, new Animation(4437)), - WILLOW_STOCK(new Item(9444), new Item(9423), new Item(9457), 39, 44, new Animation(4438)), - TEAK_STOCK(new Item(9446), new Item(9425), new Item(9459), 46, 54, new Animation(4439)), - MAPLE_STOCK(new Item(9448), new Item(9427), new Item(9461), 54, 64, new Animation(4440)), - MAHOGANY_STOCK(new Item(9450), new Item(9429), new Item(9463), 61, 82, new Animation(4441)), - YEW_STOCK(new Item(9452), new Item(9431), new Item(9465), 69, 100, new Animation(4442)); - - /** - * Constructs a new {@code StringcrosbowPlugin.java} {@code Object}. - * @param stock the stock. - * @param limb the limb. - * @param product the product. - * @param level the level. - * @param experience the experience. - * @param animation the animation. - */ - Limb(Item stock, Item limb, Item product, int level, double experience, Animation animation) { - this.stock = stock; - this.limb = limb; - this.product = product; - this.level = level; - this.experience = experience; - this.animation = animation; - } - - /** - * The stock. - */ - private final Item stock; - - /** - * The limb. - */ - private final Item limb; - - /** - * The product. - */ - private final Item product; - - /** - * The level. - */ - private final int level; - - /** - * The experience. - */ - private final double experience; - - /** - * The animation. - */ - private final Animation animation; - - /** - * Gets the stock. - * @return The stock. - */ - public Item getStock() { - return stock; - } - - /** - * Gets the limb. - * @return The limb. - */ - public Item getLimb() { - return limb; - } - - /** - * Gets the product. - * @return The product. - */ - public Item getProduct() { - return product; - } - - /** - * Gets the level. - * @return The level. - */ - public int getLevel() { - return level; - } - - /** - * Gets the experience. - * @return The experience. - */ - public double getExperience() { - return experience; - } - - /** - * Gets the animation. - * @return The animation. - */ - public Animation getAnimation() { - return animation; - } - - /** - * Method used to get the {@link Limb} for the item. - * @param item the item. - * @return the limb. - */ - public static Limb forItems(final Item item, final Item second) { - for (Limb l : Limb.values()) { - if (l.getLimb().getId() == item.getId() && l.getStock().getId() == second.getId() || l.getLimb().getId() == second.getId() && l.getStock().getId() == item.getId()) { - return l; - } - } - return null; - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/LimbPulse.kt b/Server/src/main/content/global/skill/fletching/items/crossbow/LimbPulse.kt deleted file mode 100644 index 2d6d35562..000000000 --- a/Server/src/main/content/global/skill/fletching/items/crossbow/LimbPulse.kt +++ /dev/null @@ -1,52 +0,0 @@ -package content.global.skill.fletching.items.crossbow - -import core.game.node.entity.player.Player -import core.game.node.entity.skill.SkillPulse -import core.game.node.entity.skill.Skills -import content.global.skill.fletching.Fletching -import core.game.node.item.Item - -/** - * Represents the skill pulse of attaching limbs. - * @author Ceikry - */ -class LimbPulse(player: Player?, node: Item, private val limb: Fletching.Limb, private var amount: Int) : SkillPulse(player, node) { - override fun checkRequirements(): Boolean { - if (player.skills.getLevel(Skills.FLETCHING) < limb.level) { - player.dialogueInterpreter.sendDialogue("You need a fletching level of " + limb.level + " to attach these limbs.") - return false - } - if (!player.inventory.containsItem(Item(limb.limb))) { - player.dialogueInterpreter.sendDialogue("That's not the correct limb to attach.") - return false - } - if(!player.inventory.containsItem(Item(limb.stock))){ - player.dialogueInterpreter.sendDialogue("That's not the correct stock for that limb.") - return false - } - return player.inventory.containsItem(Item(limb.stock)) - } - - override fun animate() { - player.animate(limb.animation) - } - - override fun reward(): Boolean { - if (delay == 1) { - super.setDelay(6) - return false - } - if (player.inventory.remove(Item(limb.stock), Item(limb.limb))) { - player.inventory.add(Item(limb.product)) - player.skills.addExperience(Skills.FLETCHING, limb.experience, true) - player.packetDispatch.sendMessage("You attach the metal limbs to the stock.") - } - if (!player.inventory.containsItem(Item(limb.limb))) { - return true - } - amount-- - return amount == 0 - } - - override fun message(type: Int) {} -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/StringCross.java b/Server/src/main/content/global/skill/fletching/items/crossbow/StringCross.java deleted file mode 100644 index 32671c480..000000000 --- a/Server/src/main/content/global/skill/fletching/items/crossbow/StringCross.java +++ /dev/null @@ -1,139 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.crossbow; - -import org.crandor.game.node.item.Item; -import org.crandor.game.world.update.flag.context.Animation; - -*/ -/** - * Represents the enum of stringing crossbows. - * @author 'Vexia - *//* - -public enum StringCross { - BRONZE_CBOW(new Item(9454), new Item(9174), 9, 6, new Animation(6671)), - BLURITE_CBOW(new Item(9456), new Item(9176), 24, 16, new Animation(6672)), - IRON_CBOW(new Item(9457), new Item(9177), 39, 22, new Animation(6673)), - STEEL_CBOW(new Item(9459), new Item(9179), 46, 27, new Animation(6674)), - MITHIRIL_CBOW(new Item(9461), new Item(9181), 54, 32, new Animation(6675)), - ADAMANT_CBOW(new Item(9463), new Item(9183), 61, 41, new Animation(6676)), - RUNITE_CBOW(new Item(9465), new Item(9185), 69, 50, new Animation(6677)); - */ -/** - * Constructs a new {@code StringcrossbowPlugin.java} {@code Object}. - * @param item the item. - * @param product the product. - * @param level the level. - * @param experience the experience. - *//* - - StringCross(final Item item, final Item product, final int level, final double experience, final Animation animation) { - this.item = item; - this.product = product; - this.level = level; - this.experience = experience; - this.animation = animation; - } - - */ -/** - * The item required. - *//* - - private final Item item; - - */ -/** - * The item product. - *//* - - private final Item product; - - */ -/** - * The level required. - *//* - - private final int level; - - */ -/** - * The experience required. - *//* - - private final double experience; - - */ -/** - * The animation of stringing. - *//* - - private final Animation animation; - - */ -/** - * Gets the item. - * @return The item. - *//* - - public Item getItem() { - return item; - } - - */ -/** - * Gets the product. - * @return The product. - *//* - - public Item getProduct() { - return product; - } - - */ -/** - * Gets the level. - * @return The level. - *//* - - public int getLevel() { - return level; - } - - */ -/** - * Gets the experience. - * @return The experience. - *//* - - public double getExperience() { - return experience; - } - - */ -/** - * Method used to get the animation. - * @return the animation. - *//* - - public Animation getAnimation() { - return animation; - } - - */ -/** - * Method used to get the string bow for the item. - * @param item the item. - * @return the string bow. - *//* - - public static StringCross forItem(final Item item) { - for (StringCross bw : StringCross.values()) { - if (bw.getItem().getId() == item.getId()) { - return bw; - } - } - return null; - } -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/items/darts/Dart.java b/Server/src/main/content/global/skill/fletching/items/darts/Dart.java deleted file mode 100644 index 235849496..000000000 --- a/Server/src/main/content/global/skill/fletching/items/darts/Dart.java +++ /dev/null @@ -1,96 +0,0 @@ -package content.global.skill.fletching.items.darts; - -import core.game.node.item.Item; - -/** - * Represents the enum to hold dart info. - * @author 'Vexia - */ -public enum Dart { - BRONZE_DART(new Item(819), new Item(806), 1, 1.8), - IRON_DART(new Item(820), new Item(807), 22, 3.8), - STEEL_DART(new Item(821), new Item(808), 37, 7.5), - MITHRIL_DART(new Item(822), new Item(809), 52, 11.2), - ADAMANT_DART(new Item(823), new Item(810), 67, 15), - RUNE_DART(new Item(824), new Item(811), 81, 18.8), - DRAGON_DART(new Item(11232), new Item(11230), 95, 25); - /** - * Constructs a new {@code Dart} {@code Object}. - * @param item the item. - * @param product the product. - * @param level the level. - * @param experience the experience. - */ - Dart(final Item item, final Item product, final int level, final double experience) { - this.item = item; - this.product = product; - this.level = level; - this.experience = experience; - } - - /** - * Represents the item required. - */ - private final Item item; - - /** - * Represents the product gained. - */ - private final Item product; - - /** - * Represents the level required. - */ - private final int level; - - /** - * Represents the experience gained. - */ - private final double experience; - - /** - * Gets the item. - * @return The item. - */ - public Item getItem() { - return item; - } - - /** - * Gets the product. - * @return The product. - */ - public Item getProduct() { - return product; - } - - /** - * Gets the level. - * @return The level. - */ - public int getLevel() { - return level; - } - - /** - * Gets the experience. - * @return The experience. - */ - public double getExperience() { - return experience; - } - - /** - * Method used to get the dart for the item. - * @param item the item. - * @return the dart. - */ - public static Dart forItem(final Item item) { - for (Dart dart : Dart.values()) { - if (dart.getItem().getId() == item.getId()) { - return dart; - } - } - return null; - } -} diff --git a/Server/src/main/content/global/skill/fletching/items/darts/DartPulse.java b/Server/src/main/content/global/skill/fletching/items/darts/DartPulse.java deleted file mode 100644 index d65fac185..000000000 --- a/Server/src/main/content/global/skill/fletching/items/darts/DartPulse.java +++ /dev/null @@ -1,105 +0,0 @@ -package content.global.skill.fletching.items.darts; - -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import content.global.skill.fletching.Fletching; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -import static core.api.ContentAPIKt.*; -import content.data.Quests; - -/** - * Represents the dart pulse. - * @author ceikry - */ -public final class DartPulse extends SkillPulse { - - /** - * Represents the feather item. - */ - private static final Item FEATHER = new Item(314); - - /** - * Represents the dart. - */ - private final Fletching.Darts dart; - - /** - * Represents the sets to make. - */ - private int sets; - - /** - * Constructs a new {@code DartPulse.java} {@code Object}. - * @param player the player. - * @param node the node. - */ - public DartPulse(Player player, Item node, Fletching.Darts dart, int sets) { - super(player, node); - this.dart = dart; - this.sets = sets; - } - - @Override - public boolean checkRequirements() { - if (player.getSkills().getLevel(Skills.FLETCHING) < dart.level) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + dart.level + " to do this."); - return false; - } - if (!player.getQuestRepository().isComplete(Quests.THE_TOURIST_TRAP)){ - player.getDialogueInterpreter().sendDialogue("You need to have completed Tourist Trap to fletch darts."); - return false; - } - if (!hasSpaceFor(player, dart.getFinished())) { - sendDialogue(player, "You do not have enough inventory space."); - return false; - } - return true; - } - - @Override - public void animate() { - - } - - @Override - public boolean reward() { - if (getDelay() == 1) { - super.setDelay(3); - } - final Item unfinished = dart.getUnfinished(); - final int dartAmount = player.getInventory().getAmount(unfinished); - final int featherAmount = player.getInventory().getAmount(FEATHER); - if (dartAmount >= 10 && featherAmount >= 10) { - FEATHER.setAmount(10); - unfinished.setAmount(10); - player.getPacketDispatch().sendMessage("You attach feathers to 10 darts."); - } else { - int amount = featherAmount > dartAmount ? dartAmount : featherAmount; - FEATHER.setAmount(amount); - unfinished.setAmount(amount); - player.getPacketDispatch().sendMessage(amount == 1 ? "You attach a feather to a dart." : "You attach feathers to " + amount + " darts."); - } - if (player.getInventory().remove(FEATHER, unfinished)) { - Item product = dart.getFinished(); - product.setAmount(FEATHER.getAmount()); - player.getSkills().addExperience(Skills.FLETCHING, dart.experience * product.getAmount(), true); - player.getInventory().add(product); - } - FEATHER.setAmount(1); - if (!player.getInventory().containsItem(FEATHER)) { - return true; - } - if (!player.getInventory().containsItem(dart.getUnfinished())) { - return true; - } - sets--; - return sets == 0; - } - - @Override - public void message(int type) { - } - -} diff --git a/Server/src/main/content/global/skill/fletching/items/gem/Gem.java b/Server/src/main/content/global/skill/fletching/items/gem/Gem.java deleted file mode 100644 index 6a3377aa4..000000000 --- a/Server/src/main/content/global/skill/fletching/items/gem/Gem.java +++ /dev/null @@ -1,101 +0,0 @@ -package content.global.skill.fletching.items.gem; - -import core.game.node.item.Item; - -/** - * Represents gems to cut into bolt tips. - * @author 'Vexia - * @date 01/12/2013 - */ -public enum Gem { - OPAL(new Item(1609), new Item(45, 12), 11, 1.5), - JADE(new Item(1611), new Item(9187, 12), 26, 2.4), - RED_TOPAZ(new Item(1613), new Item(9188, 12), 48, 3.9), - SAPPHIRE(new Item(1607), new Item(9189, 12), 56, 4), - EMERALD(new Item(1605), new Item(9190, 12), 58, 5.5), - RUBY(new Item(1603), new Item(9191, 12), 63, 6.3), - DIAMOND(new Item(1601), new Item(9192, 12), 65, 7), - DRAGONSTONE(new Item(1615), new Item(9193, 12), 71, 8.2), - ONYX(new Item(6573), new Item(9194, 24), 73, 9.4); - - /** - * Constructs a new {@code Gem.java} {@code Object}. - * @param gem the gem. - * @param bolt the bolt. - * @param level the level. - * @param experience the experience. - */ - Gem(Item gem, Item bolt, int level, double experience) { - this.gem = gem; - this.bolt = bolt; - this.level = level; - this.experience = experience; - } - - /** - * Represents the gem. - */ - private final Item gem; - - /** - * Represents the bolt. - */ - private final Item bolt; - - /** - * Represents the level required. - */ - private final int level; - - /** - * Represents the experience gained. - */ - private final double experience; - - /** - * Gets the gem. - * @return The gem. - */ - public Item getGem() { - return gem; - } - - /** - * Gets the bolt. - * @return The bolt. - */ - public Item getBolt() { - return bolt; - } - - /** - * Gets the level. - * @return The level. - */ - public int getLevel() { - return level; - } - - /** - * Gets the experience. - * @return The experience. - */ - public double getExperience() { - return experience; - } - - /** - * Method used to get a gem for the item. - * @param item the item. - * @return the gem. - */ - public static Gem forItem(final Item item) { - for (Gem gem : values()) { - if (gem.getGem().getId() == item.getId()) { - return gem; - } - } - return null; - } - -} diff --git a/Server/src/main/content/global/skill/fletching/items/gem/GemBolt.java b/Server/src/main/content/global/skill/fletching/items/gem/GemBolt.java deleted file mode 100644 index b21e6a164..000000000 --- a/Server/src/main/content/global/skill/fletching/items/gem/GemBolt.java +++ /dev/null @@ -1,144 +0,0 @@ -/* -package core.game.node.entity.skill.fletching.items.gem; - -import org.crandor.game.node.item.Item; - -*/ -/** - * Represents a gem bolt. - * @author 'Vexia - * @date 01/12/2013 - *//* - -public enum GemBolt { - OPAL(new Item(877, 10), new Item(45, 10), new Item(879, 10), 11, 1.5), - PEARL(new Item(9140, 10), new Item(46, 10), new Item(880, 10), 41, 3.2), - JADE(new Item(9139, 10), new Item(9187, 10), new Item(9335, 10), 26, 2.4), - RED_TOPAZ(new Item(9141, 10), new Item(9188, 10), new Item(9336, 10), 48, 3.9), - SAPPHIRE(new Item(9142, 10), new Item(9189, 10), new Item(9337, 10), 56, 4), - EMERALD(new Item(9142, 10), new Item(9190, 10), new Item(9338, 10), 58, 5.5), - RUBY(new Item(9143, 10), new Item(9191, 10), new Item(9339, 10), 63, 6.3), - DIAMOND(new Item(9143, 10), new Item(9192, 10), new Item(9340, 10), 65, 7), - DRAGONSTONE(new Item(9144, 10), new Item(9193, 10), new Item(9341, 10), 71, 8.2), - ONYX(new Item(9144, 10), new Item(9194, 10), new Item(9342, 10), 73, 9.4); - - */ -/** - * Constructs a new {@code GemBolt} {@code Object}. - * @param base the base. - * @param tip the tip. - * @param level the level. - * @param experience the experience. - *//* - - GemBolt(Item base, Item tip, Item product, int level, double experience) { - this.base = base; - this.tip = tip; - this.product = product; - this.level = level; - this.experience = experience; - } - - */ -/** - * Represents the base item. - *//* - - private final Item base; - - */ -/** - * Represents the tip to attach. - *//* - - private final Item tip; - - */ -/** - * Represents the product. - *//* - - private final Item product; - - */ -/** - * Represents the level. - *//* - - private final int level; - - */ -/** - * Represents the experience. - *//* - - private final double experience; - - */ -/** - * Gets the base. - * @return The base. - *//* - - public Item getBase() { - return base; - } - - */ -/** - * Gets the tip. - * @return The tip. - *//* - - public Item getTip() { - return tip; - } - - */ -/** - * Gets the product. - * @return The product. - *//* - - public Item getProduct() { - return product; - } - - */ -/** - * Gets the level. - * @return The level. - *//* - - public int getLevel() { - return level; - } - - */ -/** - * Gets the experience. - * @return The experience. - *//* - - public double getExperience() { - return experience; - } - - */ -/** - * Method used to get the gem bolt from the id. - * @param boltt the boltt. - * @param tip the tip. - * @return the bolt. - *//* - - public static GemBolt forItems(final Item boltt, final Item tip) { - for (GemBolt bolt : values()) { - if (bolt.getBase().getId() == boltt.getId() && bolt.getTip().getId() == tip.getId() || bolt.getBase().getId() == tip.getId() && bolt.getTip().getId() == boltt.getId()) { - return bolt; - } - } - return null; - } -} -*/ diff --git a/Server/src/main/content/global/skill/fletching/items/gem/GemBoltCutPulse.kt b/Server/src/main/content/global/skill/fletching/items/gem/GemBoltCutPulse.kt deleted file mode 100644 index e03781529..000000000 --- a/Server/src/main/content/global/skill/fletching/items/gem/GemBoltCutPulse.kt +++ /dev/null @@ -1,68 +0,0 @@ -package content.global.skill.fletching.items.gem - -import core.game.node.entity.player.Player -import core.game.node.entity.skill.SkillPulse -import core.game.node.entity.skill.Skills -import content.global.skill.fletching.Fletching.GemBolts -import core.game.node.item.Item -import core.game.world.update.flag.context.Animation -import org.rs09.consts.Items - -/** - * Represents the gem cutting pulse(gem to bolt). - * @author Ceikry - */ -class GemBoltCutPulse -/** - * Constructs a new `GemCutPulse.java` `Object`. - * @param player the player. - * @param node the node. - * @param amount the amount. - */(player: Player?, node: Item?, - /** - * Represents the gem we're cutting. - */ - private val gem: GemBolts, - /** - * Represents the amount to make. - */ - private var amount: Int) : SkillPulse(player, node) { - /** - * Represents the ticks passed. - */ - private var ticks = 0 - - override fun checkRequirements(): Boolean { - if (player.skills.getLevel(Skills.FLETCHING) < gem.level) { - player.dialogueInterpreter.sendDialogue("You need a Fletching level of " + gem.level + " or above to do that.") - return false - } - return player.inventory.containsItem(Item(gem.gem)) - } - - override fun animate() { - if (ticks % 6 == 0) { - player.animate(ANIMATION) - } - } - - override fun reward(): Boolean { - if (++ticks % 5 != 0) { - return false - } - val reward = if (gem.gem == Items.OYSTER_PEARLS_413) Item(gem.tip, 24) else Item(gem.tip, 12) - if (player.inventory.remove(Item(gem.gem))) { - player.inventory.add(reward) - player.skills.addExperience(Skills.FLETCHING, gem.experience, true) - } - amount-- - return amount <= 0 - } - - companion object { - /** - * Represents the cutting animation. - */ - private val ANIMATION = Animation(6702) - } -} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/gem/GemBoltPulse.java b/Server/src/main/content/global/skill/fletching/items/gem/GemBoltPulse.java deleted file mode 100644 index 4cd856e8a..000000000 --- a/Server/src/main/content/global/skill/fletching/items/gem/GemBoltPulse.java +++ /dev/null @@ -1,91 +0,0 @@ -package content.global.skill.fletching.items.gem; - -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import content.global.skill.fletching.Fletching; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the attaching of a gem bolt to a premade bolt. - * @author Ceikry - */ -public final class GemBoltPulse extends SkillPulse { - - /** - * Represents the gem bolt being made. - */ - private Fletching.GemBolts bolt; - - /** - * Represents the sets to make. - */ - private int sets = 0; - - /** - * Represents the ticks passed. - */ - private int ticks; - - /** - * Constructs a new {@code GemBoltPulse} {@code Object}. - * @param player the player. - * @param node the node. - * @param sets the sets. - */ - public GemBoltPulse(Player player, Item node, Fletching.GemBolts bolt, int sets) { - super(player, node); - this.bolt = bolt; - this.sets = sets; - } - - @Override - public boolean checkRequirements() { - if (player.getSkills().getLevel(Skills.FLETCHING) < bolt.level) { - player.getDialogueInterpreter().sendDialogue("You need a Fletching level of " + bolt.level + " or above to do that."); - return false; - } - if (!player.getInventory().containsItem(new Item(bolt.base)) || !player.getInventory().containsItem(new Item(bolt.tip))) { - return false; - } - if (!player.getInventory().hasSpaceFor(new Item(bolt.product))){ - player.getDialogueInterpreter().sendDialogue("You do not have enough inventory space."); - return false; - } - return true; - } - - @Override - public void animate() { - } - - @Override - public boolean reward() { - if (++ticks % 3 != 0) { - return false; - } - int baseAmount = player.getInventory().getAmount(bolt.base); - int tipAmount = player.getInventory().getAmount(bolt.tip); - Item base = new Item(bolt.base); - Item tip = new Item(bolt.tip); - Item product = new Item(bolt.product); - if(baseAmount >= 10 && tipAmount >= 10){ - base.setAmount(10); - tip.setAmount(10); - product.setAmount(10); - } else { - int amount = baseAmount > tipAmount ? tipAmount : baseAmount; - base.setAmount(amount); - tip.setAmount(amount); - product.setAmount(amount); - } - if (player.getInventory().remove(base,tip)) { - player.getInventory().add(product); - player.getSkills().addExperience(Skills.FLETCHING, bolt.experience * product.getAmount(), true); - player.getPacketDispatch().sendMessage(product.getAmount() == 1 ? "You attach the tip to the bolt." : "You fletch " + product.getAmount() + " bolts."); - } - sets--; - return sets <= 0; - } - -} diff --git a/Server/src/main/content/global/skill/fletching/items/grapple/GrapplePulse.java b/Server/src/main/content/global/skill/fletching/items/grapple/GrapplePulse.java deleted file mode 100644 index cbba3820f..000000000 --- a/Server/src/main/content/global/skill/fletching/items/grapple/GrapplePulse.java +++ /dev/null @@ -1,85 +0,0 @@ -package content.global.skill.fletching.items.grapple; - -import core.game.node.entity.skill.SkillPulse; -import core.game.node.entity.skill.Skills; -import core.game.node.entity.player.Player; -import core.game.node.item.Item; - -/** - * Represents the skill pulse used to create a mith grapple. - * @author 'Vexia - * @date 21/12/2013 - */ -public final class GrapplePulse extends SkillPulse { - - /** - * Represents the mith grapple tip. - */ - private static final Item MITH_GRAPPLE = new Item(9418); - - /** - * Represents the mithril grapple tio. - */ - private static final Item GRAPPLE_TIP = new Item(9416); - - /** - * Represents the mithril bolt. - */ - private static final Item MITHRIL_BOLT = new Item(9142); - - /** - * Represents the amount of the grapple to make. - */ - private int amount; - - /** - * Constructs a new {@code GrapplePulse} {@code Object}. - * @param player the player. - * @param node the node. - * @param amount the amount. - */ - public GrapplePulse(Player player, Item node, int amount) { - super(player, node); - this.amount = amount; - } - - @Override - public boolean checkRequirements() { - int inventoryAmount = player.getInventory().getAmount(GRAPPLE_TIP); - if (amount > inventoryAmount) { - amount = inventoryAmount; - } - if (!player.getInventory().containsItem(GRAPPLE_TIP) || !player.getInventory().containsItem(MITHRIL_BOLT)) { - return false; - } - if (player.getSkills().getLevel(Skills.FLETCHING) < 59) { - player.getDialogueInterpreter().sendDialogue("You need a fletching level of at least 59 in order to do this."); - return false; - } - return true; - } - - @Override - public void animate() { - } - - @Override - public boolean reward() { - if (getDelay() == 1) { - setDelay(3); - return false; - } - if (player.getInventory().remove(GRAPPLE_TIP) && player.getInventory().remove(MITHRIL_BOLT)) { - player.getInventory().add(MITH_GRAPPLE); - player.getSkills().addExperience(Skills.FLETCHING, 5, true); - } - amount--; - return amount < 1; - } - - @Override - public void message(int type) { - - } - -} diff --git a/Server/src/main/content/global/skill/fletching/log/CraftItemWithLogScript.kt b/Server/src/main/content/global/skill/fletching/log/CraftItemWithLogScript.kt new file mode 100644 index 000000000..33e6c5524 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/log/CraftItemWithLogScript.kt @@ -0,0 +1,113 @@ +package content.global.skill.fletching.log + +import content.global.skill.fletching.AchievementDiaryAttributeKeys +import content.global.skill.fletching.Zones +import content.global.skill.fletching.log.GrammarHelpers.aOrAn +import content.global.skill.fletching.log.GrammarHelpers.makeFriendlyName +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.Items + +/** + * Represents the queueScript used to craft things by carving a log + * @author ceik + * @param player the player. + * @param logCraftInfo crafting info about what we're making out of the log + * @param amount iterations of craft to run + */ +class CraftItemWithLogScript( + private val player: Player, + private val logCraftInfo: LogCraftInfo, + private val amount: Int +) { + + private val initialDelay = 1 + + // src https://gitlab.com/2009scape/2009scape/-/merge_requests/1960#note_2702231552 + private val subsequentDelay = 3 + + private val carveLogAnimation = Animation(1248) + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < logCraftInfo.level) { + LogCraftableListeners.sendLevelCheckFailDialog(player, logCraftInfo) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + if (removeItem(player, logCraftInfo.logItemId.asItem())) { + player.animate(carveLogAnimation) + + val finishedItemName = makeFriendlyName(Item(logCraftInfo.finishedItemId).name) + + val amountToCraft = when (logCraftInfo) { + LogCraftInfo.OGRE_ARROW_SHAFT -> RandomFunction.random(2, 6) + LogCraftInfo.ARROW_SHAFT -> 15 + else -> 1 + } + + if (logCraftInfo == LogCraftInfo.OGRE_COMP_BOW) { + if (!removeItem(player, Items.WOLF_BONES_2859)) { + return@queueScript stopExecuting(player) + } + } + + sendCraftMessageToPlayer(amountToCraft, finishedItemName) + + addItem(player, logCraftInfo.finishedItemId, amountToCraft) + rewardXP(player, Skills.FLETCHING, logCraftInfo.experience) + + if (logCraftInfo == LogCraftInfo.MAGIC_SHORTBOW) { + handleSeersMagicShortbowAchievement() + } + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= amount - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } + + private fun handleSeersMagicShortbowAchievement() { + if (Zones.inAnyZone(player, Zones.seersMagicShortbowAchievementZones) && + !player.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE, 2, 2) + ) { + setAttribute( + player, + "/save:${AchievementDiaryAttributeKeys.FLETCHED_UNSTRUNG_MAGIC_SHORTBOW}", + true + ) + } + } + + private fun sendCraftMessageToPlayer(amountToCraft: Int, finishedItemName: String) { + when (logCraftInfo) { + LogCraftInfo.ARROW_SHAFT -> sendMessage( + player, + "You carefully cut the wood into $amountToCraft arrow shafts." + ) + + LogCraftInfo.OGRE_ARROW_SHAFT -> sendMessage( + player, + "You carefully cut the wood into $amountToCraft arrow shafts." + ) + + else -> sendMessage( + player, + "You carefully cut the wood into ${aOrAn(finishedItemName)} $finishedItemName." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/log/GrammarHelpers.kt b/Server/src/main/content/global/skill/fletching/log/GrammarHelpers.kt new file mode 100644 index 000000000..5863c51ea --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/log/GrammarHelpers.kt @@ -0,0 +1,20 @@ +package content.global.skill.fletching.log + +import core.tools.StringUtils + +object GrammarHelpers { + fun makeFriendlyName(name: String): String { + return name.replace("(u)", "").trim { it <= ' ' } + } + + /** + * Returns "a" or "an" depending on whether the word begins with a vowel + */ + @Suppress("GrazieInspection") + fun aOrAn(word: String): String { + return when (StringUtils.isPlusN(word)) { + true -> "an" + false -> "a" + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/log/LogCraftInfo.kt b/Server/src/main/content/global/skill/fletching/log/LogCraftInfo.kt new file mode 100644 index 000000000..2111606dc --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/log/LogCraftInfo.kt @@ -0,0 +1,63 @@ +package content.global.skill.fletching.log + +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different items from logs + * @property logItemId the log item id that can be used to craft this item + * @property finishedItemId the resulting finished bolt Item id. + * @property level the level required to craft. + * @property experience the experience gained by crafting. + */ +enum class LogCraftInfo(val logItemId: Int, val finishedItemId: Int, val experience: Double, val level: Int) { + ARROW_SHAFT(Items.LOGS_1511, Items.ARROW_SHAFT_52, 5.0, 1), + SHORT_BOW(Items.LOGS_1511, Items.SHORTBOW_U_50, 5.0, 5), + LONG_BOW(Items.LOGS_1511, Items.LONGBOW_U_48, 10.0, 10), + WOODEN_STOCK(Items.LOGS_1511, Items.WOODEN_STOCK_9440, 6.0, 9), + + OGRE_ARROW_SHAFT(Items.ACHEY_TREE_LOGS_2862, Items.OGRE_ARROW_SHAFT_2864, 6.4, 5), + OGRE_COMP_BOW(Items.ACHEY_TREE_LOGS_2862, Items.UNSTRUNG_COMP_BOW_4825, 45.0, 30), + + OAK_SHORTBOW(Items.OAK_LOGS_1521, Items.OAK_SHORTBOW_U_54, 16.5, 20), + OAK_LONGBOW(Items.OAK_LOGS_1521, Items.OAK_LONGBOW_U_56, 25.0, 25), + OAK_STOCK(Items.OAK_LOGS_1521, Items.OAK_STOCK_9442, 16.0, 24), + + WILLOW_SHORTBOW(Items.WILLOW_LOGS_1519, Items.WILLOW_SHORTBOW_U_60, 33.3, 35), + WILLOW_LONGBOW(Items.WILLOW_LOGS_1519, Items.WILLOW_LONGBOW_U_58, 41.5, 40), + WILLOW_STOCK(Items.WILLOW_LOGS_1519, Items.WILLOW_STOCK_9444, 22.0, 39), + + MAPLE_SHORTBOW(Items.MAPLE_LOGS_1517, Items.MAPLE_SHORTBOW_U_64, 50.0, 50), + MAPLE_LONGBOW(Items.MAPLE_LOGS_1517, Items.MAPLE_LONGBOW_U_62, 58.3, 55), + MAPLE_STOCK(Items.MAPLE_LOGS_1517, Items.MAPLE_STOCK_9448, 32.0, 54), + + YEW_SHORTBOW(Items.YEW_LOGS_1515, Items.YEW_SHORTBOW_U_68, 67.5, 65), + YEW_LONGBOW(Items.YEW_LOGS_1515, Items.YEW_LONGBOW_U_66, 75.0, 70), + YEW_STOCK(Items.YEW_LOGS_1515, Items.YEW_STOCK_9452, 50.0, 69), + + MAGIC_SHORTBOW(Items.MAGIC_LOGS_1513, Items.MAGIC_SHORTBOW_U_72, 83.3, 80), + MAGIC_LONGBOW(Items.MAGIC_LOGS_1513, Items.MAGIC_LONGBOW_U_70, 91.5, 85), + + TEAK_STOCK(Items.TEAK_LOGS_6333, Items.TEAK_STOCK_9446, 27.0, 46), + + MAHOGANY_STOCK(Items.MAHOGANY_LOGS_6332, Items.MAHOGANY_STOCK_9450, 41.0, 61); + + + companion object { + val logIds: IntArray = LogCraftInfo.values().map { logCraftInfo: LogCraftInfo -> logCraftInfo.logItemId }.distinct().toIntArray() + + private val logCraftablesByLogId = associateCraftInfoByLogIds() + private fun associateCraftInfoByLogIds(): Map> { + val map = HashMap>() + + for (logId in logIds) { + map[logId] = LogCraftInfo.values().filter { logCraftInfo: LogCraftInfo -> logCraftInfo.logItemId == logId } + } + + return map + } + + fun forLogId(logId: Int): List? { + return logCraftablesByLogId[logId] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/log/LogCraftableListeners.kt b/Server/src/main/content/global/skill/fletching/log/LogCraftableListeners.kt new file mode 100644 index 000000000..fde0d5ff4 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/log/LogCraftableListeners.kt @@ -0,0 +1,83 @@ +package content.global.skill.fletching.log + +import content.data.Quests +import content.global.skill.fletching.log.GrammarHelpers.aOrAn +import content.global.skill.fletching.log.GrammarHelpers.makeFriendlyName +import core.api.* +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items + +@Suppress("unused") // Reflectively loaded +class LogCraftableListeners : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.KNIFE_946, *LogCraftInfo.logIds) { player, knife, log -> + val applicableCraftInfosForLog = LogCraftInfo.forLogId(log.id) ?: return@onUseWith false + val craftableItems = + applicableCraftInfosForLog.map { logCraftable -> Item(logCraftable.finishedItemId) }.toTypedArray() + + val handler: SkillDialogueHandler = object : SkillDialogueHandler( + player, + SkillDialogue.forLength(applicableCraftInfosForLog.size), + *craftableItems + ) { + override fun create(amount: Int, index: Int) { + if (!playerMeetsInitialRequirements(applicableCraftInfosForLog[index])) return + CraftItemWithLogScript(player, applicableCraftInfosForLog[index], amount).invoke() + } + + private fun playerMeetsInitialRequirements(logCraftInfo: LogCraftInfo): Boolean { + if (getDynLevel(player, Skills.FLETCHING) < logCraftInfo.level) { + sendLevelCheckFailDialog(player, logCraftInfo) + return false + } + if (logCraftInfo == LogCraftInfo.OGRE_ARROW_SHAFT && + !isQuestStarted(player, Quests.BIG_CHOMPY_BIRD_HUNTING) + ) { + sendDialogue(player, "You must have started ${Quests.BIG_CHOMPY_BIRD_HUNTING} to make those.") + return false + } + if (logCraftInfo == LogCraftInfo.OGRE_COMP_BOW) { + if (getQuestStage(player, Quests.ZOGRE_FLESH_EATERS) < 8) { + sendMessage( + player, + "You must have started Zogre Flesh Eaters and asked Grish to string this." + ) + return false + } + if (amountInInventory(player, Items.WOLF_BONES_2859) < 1) { + sendMessage(player, "You need to have Wolf Bones in order to make this.") + return false + } + } + return true + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, log.id) + } + } + handler.open() + return@onUseWith true + } + } + + companion object { + fun sendLevelCheckFailDialog(player: Player, logCraftInfo: LogCraftInfo) { + val finishedItem = Item(logCraftInfo.finishedItemId) + val friendlyCraftedItemName = makeFriendlyName(finishedItem.name) + sendDialogue( + player, + "You need a Fletching skill of ${logCraftInfo.level} or above to make ${ + aOrAn( + friendlyCraftedItemName + ) + } $friendlyCraftedItemName." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/stringing/StringItemScript.kt b/Server/src/main/content/global/skill/fletching/stringing/StringItemScript.kt new file mode 100644 index 000000000..633e29667 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/stringing/StringItemScript.kt @@ -0,0 +1,71 @@ +package content.global.skill.fletching.stringing + +import content.global.skill.fletching.AchievementDiaryAttributeKeys +import content.global.skill.fletching.Zones +import content.global.skill.fletching.stringing.StringableCraftInfo.Companion.applicableStringId +import core.api.* +import core.game.interaction.Clocks +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.node.item.Item + +/** + * Represents queueScript to string a bow/crossbow + * @author Ceikry + * @param player the player. + * @param stringableCraftInfo contains crafting information about what we're stringing + * @param amount the amount of items to string + */ +class StringItemScript( + private val player: Player, + private val stringableCraftInfo: StringableCraftInfo, + private var amount: Int +) { + private val initialDelay = 1 + private val subsequentDelay = 2 + + fun invoke() { + queueScript(player, initialDelay) { stage -> + if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player) + + if (getDynLevel(player, Skills.FLETCHING) < stringableCraftInfo.level) { + StringingListeners.sendLevelCheckFailDialogue(player, stringableCraftInfo.level) + return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...) + } + + if ( + removeItemsIfPlayerHasEnough( + player, + Item(stringableCraftInfo.unstrungItemId), + Item(stringableCraftInfo.applicableStringId) + ) + ) { + player.animate(stringableCraftInfo.animation) + + addItem(player, stringableCraftInfo.strungItemId, 1) + rewardXP(player, Skills.FLETCHING, stringableCraftInfo.experience) + sendMessage(player, "You add a string to the bow.") + if (stringableCraftInfo == StringableCraftInfo.MAGIC_SHORTBOW) { + handleSeersMagicShortbowAchievement() + } + } else { + return@queueScript stopExecuting(player) + } + + if (stage >= amount - 1) { + return@queueScript stopExecuting(player) + } + + return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true) + } + } + + private fun handleSeersMagicShortbowAchievement() { + if (Zones.inAnyZone(player, Zones.seersMagicShortbowAchievementZones) && + getAttribute(player, AchievementDiaryAttributeKeys.FLETCHED_UNSTRUNG_MAGIC_SHORTBOW, false) + ) { + player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 2, 2) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/stringing/StringableCraftInfo.kt b/Server/src/main/content/global/skill/fletching/stringing/StringableCraftInfo.kt new file mode 100644 index 000000000..38c089621 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/stringing/StringableCraftInfo.kt @@ -0,0 +1,66 @@ +package content.global.skill.fletching.stringing + +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items + +/** + * Provides information pertaining to crafting different strung items + * @property isCrossbow is this enum for a crossbow? + * @property unstrungItemId the unstrung item Id + * @property strungItemId the resulting strung item Id + * @property level the level required to string the item + * @property experience experience gained from stringing + * @property animation the stringing animation to play + */ +enum class StringableCraftInfo( + val isCrossbow: Boolean, + val unstrungItemId: Int, + val strungItemId: Int, + val level: Int, + val experience: Double, + val animation: Animation +) { + SHORT_BOW(false, Items.SHORTBOW_U_50, Items.SHORTBOW_841, 5, 5.0, Animation(6678)), + LONG_BOW(false, Items.LONGBOW_U_48, Items.LONGBOW_839, 10, 10.0, Animation(6684)), + OAK_SHORTBOW(false, Items.OAK_SHORTBOW_U_54, Items.OAK_SHORTBOW_843, 20, 16.5, Animation(6679)), + OAK_LONGBOW(false, Items.OAK_LONGBOW_U_56, Items.OAK_LONGBOW_845, 25, 25.0, Animation(6685)), + OGRE_COMP_BOW(false, Items.UNSTRUNG_COMP_BOW_4825, Items.COMP_OGRE_BOW_4827, 30, 45.0, Animation(-1)), + WILLOW_SHORTBOW(false, Items.WILLOW_SHORTBOW_U_60, Items.WILLOW_SHORTBOW_849, 35, 33.3, Animation(6680)), + WILLOW_LONGBOW(false, Items.WILLOW_LONGBOW_U_58, Items.WILLOW_LONGBOW_847, 40, 41.5, Animation(6686)), + MAPLE_SHORTBOW(false, Items.MAPLE_SHORTBOW_U_64, Items.MAPLE_SHORTBOW_853, 50, 50.0, Animation(6681)), + MAPLE_LONGBOW(false, Items.MAPLE_LONGBOW_U_62, Items.MAPLE_LONGBOW_851, 55, 58.3, Animation(6687)), + YEW_SHORTBOW(false, Items.YEW_SHORTBOW_U_68, Items.YEW_SHORTBOW_857, 65, 67.5, Animation(6682)), + YEW_LONGBOW(false, Items.YEW_LONGBOW_U_66, Items.YEW_LONGBOW_855, 70, 75.0, Animation(6688)), + MAGIC_SHORTBOW(false, Items.MAGIC_SHORTBOW_U_72, Items.MAGIC_SHORTBOW_861, 80, 83.3, Animation(6683)), + MAGIC_LONGBOW(false, Items.MAGIC_LONGBOW_U_70, Items.MAGIC_LONGBOW_859, 85, 91.5, Animation(6689)), + + BRONZE_CBOW(true, Items.BRONZE_CBOW_U_9454, Items.BRONZE_CROSSBOW_9174, 9, 6.0, Animation(6671)), + BLURITE_CBOW(true, Items.BLURITE_CBOW_U_9456, Items.BLURITE_CROSSBOW_9176, 24, 16.0, Animation(6672)), + IRON_CBOW(true, Items.IRON_CBOW_U_9457, Items.IRON_CROSSBOW_9177, 39, 22.0, Animation(6673)), + STEEL_CBOW(true, Items.STEEL_CBOW_U_9459, Items.STEEL_CROSSBOW_9179, 46, 27.0, Animation(6674)), + MITHIRIL_CBOW(true, Items.MITHRIL_CBOW_U_9461, Items.MITH_CROSSBOW_9181, 54, 32.0, Animation(6675)), + ADAMANT_CBOW(true, Items.ADAMANT_CBOW_U_9463, Items.ADAMANT_CROSSBOW_9183, 61, 41.0, Animation(6676)), + RUNITE_CBOW(true, Items.RUNITE_CBOW_U_9465, Items.RUNE_CROSSBOW_9185, 69, 50.0, Animation(6677)); + + companion object { + val unstrungBowIds: IntArray = values().map { stringableCraftInfo: StringableCraftInfo -> stringableCraftInfo.unstrungItemId }.toIntArray() + val stringItemIds: IntArray = intArrayOf(Items.BOW_STRING_1777,Items.CROSSBOW_STRING_9438) + + private val stringableCraftInfoByUnstrungItemId = values().associateBy { it.unstrungItemId } + + fun forUnstrungBowItemId(unstrungItemId: Int): StringableCraftInfo? { + return stringableCraftInfoByUnstrungItemId[unstrungItemId] + } + + /** + * Returns the item id that should be used for stringing this enums unstrung bow + */ + val StringableCraftInfo.applicableStringId: Int + get() { + return when { + this.isCrossbow -> Items.CROSSBOW_STRING_9438 + else -> Items.BOW_STRING_1777 + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/stringing/StringingListeners.kt b/Server/src/main/content/global/skill/fletching/stringing/StringingListeners.kt new file mode 100644 index 000000000..051f8102b --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/stringing/StringingListeners.kt @@ -0,0 +1,69 @@ +package content.global.skill.fletching.stringing + +import content.data.Quests +import content.global.skill.fletching.stringing.StringableCraftInfo.Companion.applicableStringId +import core.api.* +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.net.packet.PacketRepository +import core.net.packet.context.ChildPositionContext +import core.net.packet.out.RepositionChild +import org.rs09.consts.Components + +@Suppress("unused") // Reflectively loaded +class StringingListeners : InteractionListener { + override fun defineListeners() { + onUseWith( + IntType.ITEM, + StringableCraftInfo.stringItemIds, + *StringableCraftInfo.unstrungBowIds + ) { player, string, unstrungBow -> + val stringableCraftInfo = StringableCraftInfo.forUnstrungBowItemId(unstrungBow.id) ?: return@onUseWith false + if (string.id != stringableCraftInfo.applicableStringId) { + sendMessage(player, "That's not the right kind of string for this.") + return@onUseWith true + } + if (stringableCraftInfo == StringableCraftInfo.OGRE_COMP_BOW && getQuestStage(player, Quests.ZOGRE_FLESH_EATERS) < 8) { + sendMessage(player, "You must have started Zogre Flesh Eaters and asked Grish to string this.") + return@onUseWith true + } + val handler: SkillDialogueHandler = + object : + SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(stringableCraftInfo.strungItemId)) { + override fun create(amount: Int, index: Int) { + if (getDynLevel(player, Skills.FLETCHING) < stringableCraftInfo.level) { + sendLevelCheckFailDialogue(player, stringableCraftInfo.level) + return + } + StringItemScript(player, stringableCraftInfo, amount).invoke() + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, string.id) + } + } + handler.open() + fixSpacingBetweenTextAndCraftedItemIcon(player) + return@onUseWith true + } + } + + private fun fixSpacingBetweenTextAndCraftedItemIcon(player: Player) { + PacketRepository.send( + RepositionChild::class.java, + ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 215, 10) + ) + } + companion object { + fun sendLevelCheckFailDialogue(player: Player, level: Int) { + sendDialogue( + player, + "You need a fletching level of $level to string this bow." + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/herblore/GrindItemPlugin.kt b/Server/src/main/content/global/skill/herblore/GrindItemPlugin.kt index ec9cd70c4..b87ead3f4 100644 --- a/Server/src/main/content/global/skill/herblore/GrindItemPlugin.kt +++ b/Server/src/main/content/global/skill/herblore/GrindItemPlugin.kt @@ -61,8 +61,7 @@ class GrindItemPlugin : UseWithHandler(233) { override fun reward(): Boolean { if (node.id == Items.FISHING_BAIT_313) { - var quantity = 0 - quantity = if (amountInInventory(player, FISHING_BAIT) >= 10) { + val quantity: Int = if (amountInInventory(player, FISHING_BAIT) >= 10) { 10 } else { amountInInventory(player, FISHING_BAIT) diff --git a/Server/src/main/content/global/skill/magic/SpellListeners.kt b/Server/src/main/content/global/skill/magic/SpellListeners.kt index 95ff686a0..e390516e3 100644 --- a/Server/src/main/content/global/skill/magic/SpellListeners.kt +++ b/Server/src/main/content/global/skill/magic/SpellListeners.kt @@ -1,14 +1,14 @@ package content.global.skill.magic +import core.api.hasLineOfSight +import core.api.log import core.game.event.SpellCastEvent -import core.api.* +import core.game.interaction.MovementPulse import core.game.node.Node import core.game.node.entity.player.Player import core.game.node.entity.player.link.SpellBookManager -import core.tools.Log -import core.tools.SystemLogger -import core.game.interaction.* import core.game.world.map.path.Pathfinder +import core.tools.Log object SpellListeners { val castMap = HashMap Unit>() @@ -44,7 +44,7 @@ object SpellListeners { range = next.first method = next.second ?: return } - + player.scripts.removeWeakScripts() if (type in intArrayOf (SpellListener.NPC, SpellListener.OBJECT, SpellListener.PLAYER, SpellListener.GROUND_ITEM)) { player.pulseManager.run (object : MovementPulse (player, node, Pathfinder.SMART) { override fun pulse() : Boolean { diff --git a/Server/src/main/core/api/ContentAPI.kt b/Server/src/main/core/api/ContentAPI.kt index 813c355dc..8185d5079 100644 --- a/Server/src/main/core/api/ContentAPI.kt +++ b/Server/src/main/core/api/ContentAPI.kt @@ -6,6 +6,7 @@ import content.data.consumables.* import content.data.skill.SkillingTool import content.global.handlers.iface.ge.StockMarket import content.global.skill.slayer.SlayerEquipmentFlags +import content.global.skill.slayer.SlayerFlags import content.global.skill.slayer.SlayerManager import content.global.skill.slayer.Tasks import content.global.skill.summoning.familiar.BurdenBeast @@ -343,6 +344,24 @@ fun removeItem(player: Player, item: T, container: Container = Container.INV } } +/** + * Remove items in a players inventory + * Checks that the player has enough first + * @param player + * @param items the items to remove + */ +fun removeItemsIfPlayerHasEnough(player: Player, vararg items: Item): Boolean { + for (item in items) { + if (amountInInventory(player, item.id) >= 1) continue + return false + } + for (item in items) { + if (removeItem(player, item)) continue + return false + } + return true +} + /** * Add an item to the given player's given container * @param player the player whose container to modify @@ -1948,12 +1967,16 @@ fun setQuestStage(player: Player, quest: Quests, stage: Int) { } /** - * Check if a quest is in progress + * Check if a quests' stage for a given player is (inclusively) between the provided start and end stage */ fun isQuestInProgress(player: Player, quest: Quests, startStage: Int, endStage: Int): Boolean { return player.questRepository.getStage(quest) in startStage..endStage } +fun isQuestStarted(player: Player, quest: Quests): Boolean { + return getQuestStage(player, quest) > 0 +} + /** * Check if a quest is complete */ @@ -2454,7 +2477,11 @@ fun getSlayerTip(player: Player): Array { * @return the task flags as Int. */ fun getSlayerTaskFlags(player: Player): Int { - return SlayerManager.getInstance(player).flags.taskFlags + return getSlayerFlags(player).taskFlags +} + +fun getSlayerFlags(player: Player): SlayerFlags { + return SlayerManager.getInstance(player).flags } /** @@ -2982,10 +3009,14 @@ fun queueScript(entity: Entity, delay: Int = 1, strength: QueueStrength = QueueS * @param entity the entity whose clock we are updating * @param clock the clock we are updating. Please use [core.game.interaction.Clocks] for this argument. * @param ticks the number of ticks to delay by + * @param delayScript whether to delay the script by the number of ticks passed in. * @return always returns false so this can be used as a script return value. **/ -fun delayClock(entity: Entity, clock: Int, ticks: Int) : Boolean { +fun delayClock(entity: Entity, clock: Int, ticks: Int, delayScript: Boolean = false) : Boolean { entity.clocks[clock] = getWorldTicks() + ticks + if (delayScript) { + return delayScript(entity, ticks) + } return false } diff --git a/Server/src/main/core/game/dialogue/SkillDialogueHandler.kt b/Server/src/main/core/game/dialogue/SkillDialogueHandler.kt index 58e692b23..acc07905c 100644 --- a/Server/src/main/core/game/dialogue/SkillDialogueHandler.kt +++ b/Server/src/main/core/game/dialogue/SkillDialogueHandler.kt @@ -19,25 +19,11 @@ open class SkillDialogueHandler( /** * Represents the skill dialogue type. */ - val type: SkillDialogue?, vararg data: Any) { - /** - * Gets the player. - * @return The player. - */ - - /** - * Gets the type. - * @return The type. - */ - - /** - * Gets the passed data. - * @return the data. - */ - /** - * Represents the object data passed through. - */ - val data: Array + val type: SkillDialogue?, + /** + * The items that can be created through this dialog. + */ + vararg val items: Item) { /** * Method used to open a skill dialogue. @@ -70,7 +56,7 @@ open class SkillDialogueHandler( * @return the amount. */ open fun getAll(index: Int): Int { - return player.inventory.getAmount(data[0] as Item) + return player.inventory.getAmount(items[0]) } /** @@ -107,7 +93,7 @@ open class SkillDialogueHandler( private val length: Int) { ONE_OPTION(309, 5, 1) { override fun display(player: Player, handler: SkillDialogueHandler) { - val item = handler.data[0] as Item + val item = handler.items[0] player.packetDispatch.sendString("



" + item.name, 309, 6) player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 309, 2) PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 309, 6, 60, 20)) @@ -125,7 +111,7 @@ open class SkillDialogueHandler( }, MAKE_SET_ONE_OPTION(582, 4, 1) { override fun display(player: Player, handler: SkillDialogueHandler) { - val item = handler.data[0] as Item + val item = handler.items[0] // Send item + item name to interface player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 582, 2) @@ -163,8 +149,8 @@ open class SkillDialogueHandler( override fun display(player: Player, handler: SkillDialogueHandler) { var item: Item player.interfaceManager.openChatbox(306) - for (i in handler.data.indices) { - item = handler.data[i] as Item + for (i in handler.items.indices) { + item = handler.items[i] player.packetDispatch.sendString("



" + handler.getName(item), 303, 7 + i) player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 303, 2 + i) } @@ -190,11 +176,11 @@ open class SkillDialogueHandler( }, THREE_OPTION(304, 8, 3) { override fun display(player: Player, handler: SkillDialogueHandler) { - var item: Item? = null + var item: Item? for (i in 0..2) { - item = handler.data[i] as Item + item = handler.items[i] player.packetDispatch.sendItemZoomOnInterface(item.id, 135, 304, 2 + i) - player.packetDispatch.sendString("



" + item!!.name, 304, 304 - 296 + i * 4) + player.packetDispatch.sendString("



" + item.name, 304, 304 - 296 + i * 4) } } @@ -219,10 +205,10 @@ open class SkillDialogueHandler( }, FOUR_OPTION(305, 9, 4) { override fun display(player: Player, handler: SkillDialogueHandler) { - var item: Item? = null + var item: Item? for (i in 0..3) { - item = handler.data[i] as Item - player.packetDispatch.sendItemZoomOnInterface(item!!.id, 135, 305, 2 + i) + item = handler.items[i] + player.packetDispatch.sendItemZoomOnInterface(item.id, 135, 305, 2 + i) player.packetDispatch.sendString("



" + item.name, 305, 305 - 296 + i * 4) } } @@ -255,8 +241,8 @@ open class SkillDialogueHandler( override fun display(player: Player, handler: SkillDialogueHandler) { var item: Item player.interfaceManager.openChatbox(306) - for (i in handler.data.indices) { - item = handler.data[i] as Item + for (i in handler.items.indices) { + item = handler.items[i] player.packetDispatch.sendString("



" + handler.getName(item), 306, 10 + 4 * i) player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 306, 2 + i) PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 306, 2 + i, positions[i][0], positions[i][1])) @@ -361,14 +347,4 @@ open class SkillDialogueHandler( */ const val SKILL_DIALOGUE = 3 shl 16 } - - /** - * Constructs a new `SkillDialogueHandler` `Object`. - * @param player the player. - * @param type the type. - * @param data the data. - */ - init { - this.data = data as Array - } } \ No newline at end of file diff --git a/Server/src/main/core/game/interaction/InteractionListeners.kt b/Server/src/main/core/game/interaction/InteractionListeners.kt index c28113500..e3cab3e34 100644 --- a/Server/src/main/core/game/interaction/InteractionListeners.kt +++ b/Server/src/main/core/game/interaction/InteractionListeners.kt @@ -164,6 +164,7 @@ object InteractionListeners { @JvmStatic fun run(id: Int, player: Player, node: Node, isEquip: Boolean): Boolean{ + player.scripts.removeWeakScripts() player.dispatch(InteractionEvent(node, if(isEquip) "equip" else "unequip")) if(isEquip){ return equipListeners["equip:$id"]?.invoke(player,node) ?: true @@ -174,6 +175,7 @@ object InteractionListeners { @JvmStatic fun run(used: Node, with: Node, type: IntType, player: Player): Boolean{ + player.scripts.removeWeakScripts() val flag = when(type){ IntType.NPC, IntType.PLAYER -> DestinationFlag.ENTITY IntType.SCENERY -> DestinationFlag.OBJECT @@ -224,6 +226,8 @@ object InteractionListeners { @JvmStatic fun run(id: Int, type: IntType, option: String, player: Player, node: Node): Boolean{ + player.scripts.removeWeakScripts() + val flag = when(type){ IntType.PLAYER -> DestinationFlag.ENTITY IntType.GROUNDITEM -> DestinationFlag.ITEM diff --git a/Server/src/main/core/game/interaction/ScriptProcessor.kt b/Server/src/main/core/game/interaction/ScriptProcessor.kt index 52c86b1e8..2c638f35f 100644 --- a/Server/src/main/core/game/interaction/ScriptProcessor.kt +++ b/Server/src/main/core/game/interaction/ScriptProcessor.kt @@ -1,6 +1,7 @@ package core.game.interaction import core.api.* +import core.game.bots.AIPlayer import core.game.node.Node import core.game.node.entity.Entity import core.game.node.entity.npc.NPC @@ -10,10 +11,10 @@ import core.game.node.scenery.Scenery import core.game.world.GameWorld import core.game.world.map.Location import core.game.world.map.path.Pathfinder -import core.game.bots.AIPlayer import core.tools.Log +import java.io.PrintWriter +import java.io.StringWriter import java.lang.Integer.max -import java.io.* class ScriptProcessor(val entity: Entity) { private var apScript: Script<*>? = null @@ -90,11 +91,8 @@ class ScriptProcessor(val entity: Entity) { } fun processQueue() : Boolean { - var strongInQueue = false - var softInQueue = false var anyExecuted = false - strongInQueue = hasTypeInQueue(QueueStrength.STRONG) - softInQueue = hasTypeInQueue(QueueStrength.SOFT) + val strongInQueue = hasTypeInQueue(QueueStrength.STRONG) if (strongInQueue) { if (entity is Player) { diff --git a/Server/src/main/core/game/node/entity/Entity.java b/Server/src/main/core/game/node/entity/Entity.java index b566cccb0..9699be83d 100644 --- a/Server/src/main/core/game/node/entity/Entity.java +++ b/Server/src/main/core/game/node/entity/Entity.java @@ -78,7 +78,7 @@ public abstract class Entity extends Node { /** * The pulse manager. */ - private final PulseManager pulseManager = new PulseManager(); + private final PulseManager pulseManager = new PulseManager(this); /** * The impact handler. diff --git a/Server/src/main/core/game/node/entity/impl/PulseManager.java b/Server/src/main/core/game/node/entity/impl/PulseManager.java index 74a78e7cc..6f93e1250 100644 --- a/Server/src/main/core/game/node/entity/impl/PulseManager.java +++ b/Server/src/main/core/game/node/entity/impl/PulseManager.java @@ -17,6 +17,12 @@ import java.util.HashMap; */ public final class PulseManager { + private final Entity entity; + + public PulseManager(Entity entity) { + this.entity = entity; + } + /** * The movement pulse. */ @@ -61,6 +67,9 @@ public final class PulseManager { } public void clear() { + entity.scripts.removeWeakScripts(); + entity.scripts.removeNormalScripts(); + currentPulses.forEach((type, pulse) -> { if (type != PulseType.STRONG && pulse != null) pulse.stop(); }); @@ -70,6 +79,9 @@ public final class PulseManager { * Clears the pulses. */ public boolean clear(PulseType pulseType) { + entity.scripts.removeWeakScripts(); + entity.scripts.removeNormalScripts(); + Pulse pulse = currentPulses.get(pulseType); if (pulse != null) { diff --git a/Server/src/main/core/game/system/command/sets/AnimationCommandSet.kt b/Server/src/main/core/game/system/command/sets/AnimationCommandSet.kt index e1de944d1..d06258333 100644 --- a/Server/src/main/core/game/system/command/sets/AnimationCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/AnimationCommandSet.kt @@ -1,5 +1,10 @@ package core.game.system.command.sets +import core.api.animate +import core.api.delayScript +import core.api.queueScript +import core.api.stopExecuting +import core.game.interaction.QueueStrength import core.game.node.entity.npc.NPC import core.game.system.task.Pulse import core.game.world.update.flag.context.Animation @@ -27,23 +32,26 @@ class AnimationCommandSet : CommandSet(Privilege.ADMIN) { player.animate(animation) } - /** - * Force the player to play animation - */ - define("anims", Privilege.ADMIN, "::anim Animation ID", "Plays the animation with the given ID."){ player, args -> + define("anims", Privilege.ADMIN, "::anims <(opt) Duration Per Animation>", "Plays animations from the From ID to the To ID, with a delay of 3 between animations, unless specified otherwise"){ player, args -> + if (args.size < 3) { - reject(player, "Syntax error: ::anim ") + reject(player, "Syntax error: ::anims <(opt) Duration Per Animation>") } - val animation = args[1].toInt() + val animationFrom = args[1].toInt() val animationTo = args[2].toInt() - GameWorld.Pulser.submit(object : Pulse(3, player) { - var someId = animation - override fun pulse(): Boolean { - player.animate(Animation.create(someId)) - someId += 1 - return someId >= animationTo + val animationDelay = (args.getOrNull(3) ?: "3").toInt() + + queueScript(player, 1, QueueStrength.STRONG) { stage: Int -> + val animationId = animationFrom + stage + animate(player, animationId, true) + notify(player, "Playing animation $animationId") + + if (animationId == animationTo) { + return@queueScript stopExecuting(player) } - }) + + return@queueScript delayScript(player, animationDelay) + } } /**