From e958b8d2554ebdcbc7fb960ba54e4c7c7ca2c3a9 Mon Sep 17 00:00:00 2001 From: Ceikry Date: Tue, 12 Apr 2022 08:46:21 +0000 Subject: [PATCH] Completely rewrote the shop system. Shop restocking now works properly, with per-item-in-shop granularity as well. (Thanos tool update released that allows defining this) Shops properly restrict ironmen from buying from player stock/overstocked items Fully functioning individualized player stock support (need to set a server config variable to enable, disabled by default. Specifically, set personalized_shops = true in the world section of the config.) The shop pricing formula now scales up/down with the authentic ratios based on stock quantity. Buying or selling, for example, 1000 of an item, now does the proper calculation for each individual item in the purchase/sale rather than exchanging the full 1000 for the initial price at the time. (For example, in the old shops, feather price at full stock was, say, 6gp. You could buy 1000 feathers at once for 6000gp. Authentically, the pricing for each feather should scale as the stock goes down. Now 1000 feathers at once costs a bit over 7k gp, despite the initial price remaining 6gp.) General store player stock is now shared between all general stores --- .../access/BitregisterAssembler.java | 4 +- .../game/container/impl/BankContainer.java | 8 +- .../content/activity/duel/StakeContainer.java | 2 +- .../activity/partyroom/ChestViewer.java | 10 +- .../tzhaar/TzhaarFightCavesPlugin.java | 3 - .../dialogue/MeleeShopDialoguePlugin.java | 13 +- .../game/content/dialogue/SaniDialogue.java | 4 +- .../content/global/shop/CulinomancerShop.kt | 18 +- .../core/game/content/global/shop/Shop.kt | 865 ------------------ .../game/content/global/shop/ShopViewer.java | 154 ---- .../shootingstar/ScoreboardEntry.java | 10 - .../shootingstar/ScoreboardHandler.java | 31 - .../shootingstar/ScoreboardManager.java | 23 - .../shootingstar/ShootingStarScoreboard.java | 22 - .../merlinscrystal/CandleMakerDialogue.java | 5 +- .../waterfallquest/WaterfallPlugin.java | 1 - .../core/game/content/ttrail/ClueLevel.java | 2 +- .../interaction/inter/EquipmentInterface.java | 8 +- .../interaction/inter/ShoppingPlugin.java | 24 +- .../interaction/item/ExplorersRingPlugin.kt | 2 +- .../game/interaction/npc/GabootyTrade.java | 5 +- .../game/interaction/npc/NPCTradePlugin.kt | 78 -- .../object/BuyCrateOptionPlugin.java | 3 +- .../interaction/object/CulinoChestListener.kt | 2 +- .../object/sorceress/GardenObjectsPlugin.kt | 2 +- .../java/core/game/node/entity/npc/NPC.java | 56 +- .../core/game/node/entity/player/Player.java | 3 + .../entity/player/link/PacketDispatch.java | 6 +- .../entity/player/link/music/MusicPlayer.java | 3 +- .../link/request/trade/TradeModule.java | 8 +- .../construction/npc/StonemasonPlugin.java | 22 +- .../entity/skill/cooking/CookingRewrite.kt | 2 +- .../firemaking/FireMakingOptionPlugin.kt | 2 +- .../skill/summoning/SummoningCreator.java | 2 +- .../net/packet/context/ContainerContext.java | 30 +- .../net/packet/in/RunScriptPacketHandler.java | 7 + .../core/net/packet/out/ContainerPacket.java | 2 +- Server/src/main/kotlin/api/Commands.kt | 49 + Server/src/main/kotlin/api/ContentAPI.kt | 16 + .../src/main/kotlin/api/ContentInterface.kt | 7 + .../main/kotlin/api/IfaceSettingsBuilder.kt | 151 +++ Server/src/main/kotlin/api/LoginListener.kt | 7 +- Server/src/main/kotlin/api/LogoutListener.kt | 7 +- Server/src/main/kotlin/api/MapArea.kt | 18 + Server/src/main/kotlin/api/PersistPlayer.kt | 9 +- Server/src/main/kotlin/api/PersistWorld.kt | 6 - .../src/main/kotlin/api/ShutdownListener.kt | 5 +- Server/src/main/kotlin/api/StartupListener.kt | 5 +- Server/src/main/kotlin/api/TickListener.kt | 5 +- .../scriptrepository/ShootingStarBot.kt | 11 +- .../activity/allfiredup/AFUBeaconHandler.kt | 2 +- .../allfiredup/AFURepairClimbHandler.kt | 2 +- .../BlastFurnaceInterfaceListener.kt | 4 +- .../blastfurnace/BlastFurnaceListeners.kt | 2 +- .../PhunnyGaugeTempInterfaceListener.kt | 4 +- .../FishingTrawlerInteractionHandler.kt | 2 +- .../guild/crafting/CraftingGuildListeners.kt | 2 +- .../game/content/activity/mta/MTAListeners.kt | 2 +- .../pyramidplunder/PharaohSceptre.kt} | 4 +- .../pyramidplunder/PyramidPlunderMinigame.kt | 3 +- .../activity/vinesweeper/Vinesweeper.kt | 748 +++++++-------- .../activity/wguild/WGuildListeners.kt | 2 +- .../ame/events/certer/CerterEventInterface.kt | 4 +- .../events/drilldemon/DrillDemonListeners.kt | 2 +- .../sandwichlady/SandwichLadyInterface.kt | 4 +- .../events/supriseexam/SEPatternInterface.kt | 4 +- .../supriseexam/SupriseExamListeners.kt | 2 +- .../region/taibwowannai/GabootyDialogue.kt | 5 +- .../content/global/action/EquipHandler.kt | 2 +- .../rs09/game/content/global/shops/Shop.kt | 393 ++++++++ .../rs09/game/content/global/shops/Shops.kt | 256 ++++++ .../holiday/christmas/GiftRollPlugin.kt | 2 +- .../holiday/easter/EasterEventListeners.kt | 2 +- .../holiday/halloween/TrickOrTreatHandler.kt | 2 +- .../penguinhns/PenguinSpyingHandler.kt | 2 +- .../worldevents/shootingstar/ShootingStar.kt | 20 +- .../shootingstar/ShootingStarCommands.kt | 40 - .../shootingstar/ShootingStarEvent.kt | 92 -- .../shootingstar/ShootingStarLogin.kt | 29 - .../shootingstar/ShootingStarMiningPulse.kt | 9 +- .../shootingstar/ShootingStarOptionHandler.kt | 39 - .../shootingstar/ShootingStarPlugin.kt | 176 ++++ .../shootingstar/StarSpriteDialogue.kt | 8 +- .../jobs/WorkForInteractionListener.kt | 2 +- .../free/dragonslayer/DSEquipListeners.kt | 2 +- .../JohnathonAntiPoisonInteraction.kt | 2 +- .../familycrest/WitchavenLeverInteraction.kt | 2 +- .../members/monksfriend/BrotherCedricNPC.kt | 2 +- .../members/monksfriend/BrotherOmadNPC.kt | 2 +- .../members/monksfriend/MonasteryMonkNPC.kt | 2 +- .../quest/members/naturespirit/NSListeners.kt | 5 +- .../HunterTalismanListener.kt | 2 +- .../SeerLockInterfaceListener.kt | 4 +- .../thefremenniktrials/SeersHouseListeners.kt | 2 +- .../TFTInteractionListeners.kt | 2 +- .../members/thelostcity/DramenTreeListener.kt | 2 +- .../members/thelosttribe/PickpocketSigmund.kt | 2 +- .../TTDoorCodeInterfaceListener.kt | 4 +- .../tribaltotem/TribalTotemListeners.kt | 2 +- .../members/waterfall/WaterfallListeners.kt | 2 +- .../content/tutorial/TutorialListeners.kt | 2 +- .../game/content/zone/FarmingPatchZone.kt | 90 +- .../content/zone/YanilleAgilityDungeon.kt | 2 +- .../content/zone/keldagrim/OrdanDialogue.kt | 2 +- .../bonegrinder/BoneGrinderListener.kt | 2 +- .../rs09/game/ge/GrandExchangeRecords.kt | 33 +- .../CorporealBeastWarningInterface.kt | 4 +- .../game/interaction/InteractionListener.kt | 28 +- .../game/interaction/InterfaceListener.kt | 10 +- .../kotlin/rs09/game/interaction/Listener.kt | 3 +- .../interaction/inter/CreditShopInterface.kt | 4 +- .../interaction/inter/FairyRingInterface.kt | 4 +- .../interaction/inter/MainGameInterface.kt | 5 +- .../interaction/inter/NPCContactInterface.kt | 4 +- .../game/interaction/inter/RulesAndInfo.kt | 4 +- .../game/interaction/inter/SilverInterface.kt | 6 +- .../interaction/inter/TeleotherInterface.kt | 4 +- .../interaction/inter/ge/ExchangeItemSets.kt | 4 +- .../game/interaction/inter/ge/StockMarket.kt | 8 +- .../interaction/item/BraceletOfClayPlugin.kt | 2 +- .../interaction/item/CadavaPotionListener.kt | 2 +- .../item/DrinkBlamishOilListener.kt | 2 +- .../item/EnchantedJewelleryListener.kt | 2 +- .../game/interaction/item/GodBookListeners.kt | 2 +- .../interaction/item/GrandSeedPodHandler.kt | 2 +- .../interaction/item/ImplingJarListener.kt | 2 +- .../item/ItemQuestRequirementListener.kt | 2 +- .../game/interaction/item/StaffOfTheRaven.kt | 2 +- .../game/interaction/item/StarRingListener.kt | 94 -- .../interaction/item/ToyHorseyListener.kt | 2 +- .../game/interaction/item/ToyListeners.kt | 2 +- .../item/withitem/HaySackOnSpear.kt | 2 +- .../item/withitem/OilFishingRodListener.kt | 2 +- .../item/withitem/PoisonedWeaponListeners.kt | 2 +- .../item/withitem/TOTTHelmOnCape.kt | 2 +- .../item/withitem/WatermelonOnSack.kt | 2 +- .../withnpc/ArchaeologicalExpertListener.kt | 2 +- .../item/withnpc/BonesOnStrayDog.kt | 2 +- .../item/withnpc/CatOnArdougneCivilian.kt | 2 +- .../item/withnpc/CiderOnForester.kt | 2 +- .../interaction/item/withnpc/GCItemOnCat.kt | 2 +- .../interaction/item/withnpc/HatEasterEgg.kt | 2 +- .../item/withnpc/MistagEasterEgg.kt | 2 +- .../item/withnpc/PoisonChaliceOnKingArthur.kt | 2 +- .../item/withnpc/RopeOnLadyKeli.kt | 2 +- .../item/withnpc/ZooknockListener.kt | 2 +- .../item/withobject/AmmoMouldOnFurnace.kt | 2 +- .../interaction/item/withobject/AxeOnTree.kt | 2 +- .../item/withobject/CoalTrucksHandler.kt | 2 +- .../item/withobject/FishEasterEgg.kt | 2 +- .../interaction/item/withobject/HatStand.kt | 2 +- .../interaction/item/withobject/SackOnHay.kt | 2 +- .../item/withobject/WaterSourceListener.kt | 2 +- .../game/interaction/npc/DecantListener.kt | 2 +- .../interaction/npc/NPCDepositListener.kt | 2 +- .../game/interaction/npc/NPCTalkListener.kt | 2 +- .../interaction/object/DemonTauntHandler.kt | 2 +- .../object/EnchantedValleyListeners.kt | 2 +- .../interaction/object/FairyRingPlugin.kt | 2 +- .../interaction/object/GutanothChestPlugin.kt | 2 +- .../interaction/object/JungleBushHandler.kt | 2 +- .../interaction/object/MuddyChestHandler.kt | 2 +- .../interaction/object/TarBarrelListener.kt | 2 +- .../object/VarrockGuardSignpost.kt | 2 +- .../interaction/object/WizardGuildPortals.kt | 2 +- .../canoestation/CanoeInterfaceListeners.kt | 4 +- .../canoestation/CanoeStationListener.kt | 2 +- .../object/objects/CrateHandler.kt | 2 +- .../interaction/region/IsafdarListeners.kt | 2 +- .../interaction/region/MorytaniaListeners.kt | 2 +- .../brimhaven/BrimhavenDungeonListeners.kt | 2 +- .../taverley/TaverleyDungeonListeners.kt | 2 +- .../falador/WineOfZamorakInteraction.kt | 2 +- .../region/lumbridge/ChurchSignListener.kt | 2 +- .../region/lumbridge/CowFieldSignListener.kt | 2 +- .../region/lumbridge/FredChestListener.kt | 2 +- .../lumbridge/GnomeCopterSignListener.kt | 2 +- .../region/rellekka/JatizsoListeners.kt | 2 +- .../region/rellekka/NeitiznotListeners.kt | 2 +- .../region/rellekka/RellekkaListeners.kt | 2 +- .../wilderness/RoguesCastleListeners.kt | 2 +- .../player/diary/seers/SeersCourthouseZone.kt | 31 +- .../player/info/stats/StatsCommandSet.kt | 4 +- .../game/node/entity/skill/AttackListener.kt | 2 +- .../decoration/chapel/BurnerListener.kt | 2 +- .../decoration/questhall/MountedGlory.kt | 2 +- .../decoration/study/TelescopePlugin.kt | 5 +- .../skill/cooking/DoughMakingListener.kt | 2 +- .../skill/farming/FarmerPayOptionHandler.kt | 2 +- .../entity/skill/farming/LeprechaunNoter.kt | 2 +- .../skill/farming/ToolLeprechaunHandler.kt | 3 +- .../skill/farming/ToolLeprechaunInterface.kt | 4 +- .../skill/fletching/FletchingListeners.kt | 2 +- .../gather/GatheringSkillOptionListeners.kt | 2 +- .../BarbFishInteractionListeners.kt | 2 +- .../skill/gather/mining/ProspectListener.kt | 2 +- .../skill/hunter/pitfall/HunterPitfall.kt | 2 +- .../node/entity/skill/magic/SpellTablets.kt | 2 +- .../skill/runecrafting/abyss/AbyssPlugin.kt | 2 +- .../skill/thieving/ThievingListeners.kt | 2 +- .../rs09/game/system/config/ShopParser.kt | 46 +- .../main/kotlin/rs09/plugin/ClassScanner.kt | 88 +- 202 files changed, 1910 insertions(+), 2385 deletions(-) delete mode 100644 Server/src/main/java/core/game/content/global/shop/Shop.kt delete mode 100644 Server/src/main/java/core/game/content/global/shop/ShopViewer.java delete mode 100644 Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardEntry.java delete mode 100644 Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardHandler.java delete mode 100644 Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardManager.java delete mode 100644 Server/src/main/java/core/game/content/global/worldevents/shootingstar/ShootingStarScoreboard.java delete mode 100644 Server/src/main/java/core/game/interaction/npc/NPCTradePlugin.kt create mode 100644 Server/src/main/kotlin/api/Commands.kt create mode 100644 Server/src/main/kotlin/api/ContentInterface.kt create mode 100644 Server/src/main/kotlin/api/IfaceSettingsBuilder.kt create mode 100644 Server/src/main/kotlin/api/MapArea.kt delete mode 100644 Server/src/main/kotlin/api/PersistWorld.kt rename Server/src/main/{java/core/game/interaction/item/PharoahSceptre.kt => kotlin/rs09/game/content/activity/pyramidplunder/PharaohSceptre.kt} (98%) create mode 100644 Server/src/main/kotlin/rs09/game/content/global/shops/Shop.kt create mode 100644 Server/src/main/kotlin/rs09/game/content/global/shops/Shops.kt delete mode 100644 Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarCommands.kt delete mode 100644 Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarEvent.kt delete mode 100644 Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarLogin.kt delete mode 100644 Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarOptionHandler.kt create mode 100644 Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarPlugin.kt delete mode 100644 Server/src/main/kotlin/rs09/game/interaction/item/StarRingListener.kt diff --git a/Server/src/main/java/core/game/container/access/BitregisterAssembler.java b/Server/src/main/java/core/game/container/access/BitregisterAssembler.java index 8410c63f2..a16a79440 100644 --- a/Server/src/main/java/core/game/container/access/BitregisterAssembler.java +++ b/Server/src/main/java/core/game/container/access/BitregisterAssembler.java @@ -8,7 +8,9 @@ import core.game.node.entity.player.Player; * @date 5/02/2013 * @author Stacx * @author Emperor + * @deprecated This is a really bad way of doing what this class needs to do. Please use {@link api.IfaceSettingsBuilder}. */ +@Deprecated() public final class BitregisterAssembler { /** @@ -102,7 +104,7 @@ public final class BitregisterAssembler { if (offset >= length) { throw new RuntimeException("Offset cannot excess length. length = " + length); } - player.getPacketDispatch().sendAccessMask(assembler.calculateRegister(), childIndex, interfaceIndex, offset, length); + player.getPacketDispatch().sendIfaceSettings(assembler.calculateRegister(), childIndex, interfaceIndex, offset, length); } /** diff --git a/Server/src/main/java/core/game/container/impl/BankContainer.java b/Server/src/main/java/core/game/container/impl/BankContainer.java index 98766499b..915aec277 100644 --- a/Server/src/main/java/core/game/container/impl/BankContainer.java +++ b/Server/src/main/java/core/game/container/impl/BankContainer.java @@ -117,11 +117,11 @@ public final class BankContainer extends Container { player.getInventory().getListeners().add(listener); player.getInventory().refresh(); player.varpManager.get(1249).setVarbit(0,lastAmountX).send(player); - player.getPacketDispatch().sendAccessMask(1278, 73, 762, 0, ServerConstants.BANK_SIZE); + player.getPacketDispatch().sendIfaceSettings(1278, 73, 762, 0, ServerConstants.BANK_SIZE); BitregisterAssembler assembly = new BitregisterAssembler(0, 1, 2, 3, 4, 5); assembly.enableExamineOption(); assembly.enableSlotSwitch(); - player.getPacketDispatch().sendAccessMask(assembly.calculateRegister(), 0, 763, 0, 27); + player.getPacketDispatch().sendIfaceSettings(assembly.calculateRegister(), 0, 763, 0, 27); player.getPacketDispatch().sendRunScript(1451, ""); open = true; setTabConfigurations(); @@ -148,11 +148,11 @@ public final class BankContainer extends Container { player.getInventory().getListeners().add(player.getBank().listener); player.getInventory().refresh(); player.varpManager.get(1249).setVarbit(0,lastAmountX).send(player); - player.getPacketDispatch().sendAccessMask(1278, 73, 762, 0, SIZE); + player.getPacketDispatch().sendIfaceSettings(1278, 73, 762, 0, SIZE); BitregisterAssembler assembly = new BitregisterAssembler(0, 1, 2, 3, 4, 5); assembly.enableExamineOption(); assembly.enableSlotSwitch(); - player.getPacketDispatch().sendAccessMask(assembly.calculateRegister(), 0, 763, 0, 27); + player.getPacketDispatch().sendIfaceSettings(assembly.calculateRegister(), 0, 763, 0, 27); player.getPacketDispatch().sendRunScript(1451, ""); open = true; this.player.getBank().setTabConfigurations(player); diff --git a/Server/src/main/java/core/game/content/activity/duel/StakeContainer.java b/Server/src/main/java/core/game/content/activity/duel/StakeContainer.java index 815058ae0..52f204639 100644 --- a/Server/src/main/java/core/game/content/activity/duel/StakeContainer.java +++ b/Server/src/main/java/core/game/content/activity/duel/StakeContainer.java @@ -79,7 +79,7 @@ public class StakeContainer extends Container { public void open() { player.getInterfaceManager().openSingleTab(OVERLAY); player.getPacketDispatch().sendRunScript(150, "IviiiIssssssss", INVY_PARAMS); - player.getPacketDispatch().sendAccessMask(1278, 0, 336, 0, 27); + player.getPacketDispatch().sendIfaceSettings(1278, 0, 336, 0, 27); PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, 2, 93, player.getInventory(), false)); } diff --git a/Server/src/main/java/core/game/content/activity/partyroom/ChestViewer.java b/Server/src/main/java/core/game/content/activity/partyroom/ChestViewer.java index d00ba8dd6..4763e6f23 100644 --- a/Server/src/main/java/core/game/content/activity/partyroom/ChestViewer.java +++ b/Server/src/main/java/core/game/content/activity/partyroom/ChestViewer.java @@ -82,9 +82,9 @@ public final class ChestViewer { */ public void update(int type, ContainerEvent event) { if (event == null) { - player.getPacketDispatch().sendAccessMask(1278, 27, 647, 0, 10); - player.getPacketDispatch().sendAccessMask(1278, 28, 647, 0, 10); - player.getPacketDispatch().sendAccessMask(1278, 29, 647, 0, 10); + player.getPacketDispatch().sendIfaceSettings(1278, 27, 647, 0, 10); + player.getPacketDispatch().sendIfaceSettings(1278, 28, 647, 0, 10); + player.getPacketDispatch().sendIfaceSettings(1278, 29, 647, 0, 10); switch (type) { case 0: player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", BEING_DROPPED); @@ -310,14 +310,14 @@ public final class ChestViewer { player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", INV_OPTIONS); PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 90, c.toArray(), 10, false)); PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 94, player.getInventory(), false)); - player.getPacketDispatch().sendAccessMask(1278, 0, 648, 0, 28); + player.getPacketDispatch().sendIfaceSettings(1278, 0, 648, 0, 28); } } @Override public void refresh(Container c) { if (c instanceof DepositContainer) { - player.getPacketDispatch().sendAccessMask(1278, 0, 648, 0, 28); + player.getPacketDispatch().sendIfaceSettings(1278, 0, 648, 0, 28); player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", ACCEPT); player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", INV_OPTIONS); PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 94, player.getInventory(), false)); diff --git a/Server/src/main/java/core/game/content/activity/tzhaar/TzhaarFightCavesPlugin.java b/Server/src/main/java/core/game/content/activity/tzhaar/TzhaarFightCavesPlugin.java index 7403e5f8f..5bd4894f2 100644 --- a/Server/src/main/java/core/game/content/activity/tzhaar/TzhaarFightCavesPlugin.java +++ b/Server/src/main/java/core/game/content/activity/tzhaar/TzhaarFightCavesPlugin.java @@ -119,9 +119,6 @@ public final class TzhaarFightCavesPlugin extends ActivityPlugin { } }; } else { - if (practice) { - player.setAttribute("fc_wave", 62); - } if (player.getAttribute("fc_wave", 0) == 62) { player.getDialogueInterpreter().sendDialogues(2617, null, "Look out, here comes TzTok-Jad!"); } diff --git a/Server/src/main/java/core/game/content/dialogue/MeleeShopDialoguePlugin.java b/Server/src/main/java/core/game/content/dialogue/MeleeShopDialoguePlugin.java index e69a510fd..c39f94398 100644 --- a/Server/src/main/java/core/game/content/dialogue/MeleeShopDialoguePlugin.java +++ b/Server/src/main/java/core/game/content/dialogue/MeleeShopDialoguePlugin.java @@ -1,16 +1,18 @@ +/* package core.game.content.dialogue; -import core.game.content.global.shop.Shop; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; +*/ /** * Package -> core.game.content.dialogue * Created on -> 9/10/2016 @10:33 PM for 530 * * @author Ethan Kyle Millard - */ + *//* + @Initializable public class MeleeShopDialoguePlugin extends DialoguePlugin { @@ -18,9 +20,11 @@ public class MeleeShopDialoguePlugin extends DialoguePlugin { public MeleeShopDialoguePlugin() { - /** + */ +/** * Empty - */ + *//* + } public MeleeShopDialoguePlugin(Player player) { @@ -61,3 +65,4 @@ public class MeleeShopDialoguePlugin extends DialoguePlugin { return new int[] { 5503 }; } } +*/ diff --git a/Server/src/main/java/core/game/content/dialogue/SaniDialogue.java b/Server/src/main/java/core/game/content/dialogue/SaniDialogue.java index 50b26e74c..b8d69d362 100644 --- a/Server/src/main/java/core/game/content/dialogue/SaniDialogue.java +++ b/Server/src/main/java/core/game/content/dialogue/SaniDialogue.java @@ -4,6 +4,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.skill.Skills; import core.plugin.Initializable; +import rs09.game.content.global.shops.Shops; import rs09.game.system.config.ShopParser; /** @@ -79,7 +80,6 @@ public class SaniDialogue extends DialoguePlugin { break; case 2: end(); - ShopParser.Companion.getSHOPS().get(4905).open(player); break; } break; @@ -136,7 +136,7 @@ public class SaniDialogue extends DialoguePlugin { * @param uid The uid. */ private void openWeaponShop(Player player, int uid) { - ShopParser.Companion.openUid(player, uid); + Shops.openId(player, uid); } @Override diff --git a/Server/src/main/java/core/game/content/global/shop/CulinomancerShop.kt b/Server/src/main/java/core/game/content/global/shop/CulinomancerShop.kt index 05cb109f1..3156b2654 100644 --- a/Server/src/main/java/core/game/content/global/shop/CulinomancerShop.kt +++ b/Server/src/main/java/core/game/content/global/shop/CulinomancerShop.kt @@ -7,6 +7,8 @@ import core.game.node.entity.player.Player import core.game.node.item.Item import core.game.system.task.Pulse import org.rs09.consts.Items +import rs09.game.content.global.shops.Shop +import rs09.game.content.global.shops.ShopItem import rs09.game.world.GameWorld import java.lang.Integer.min import kotlin.collections.HashMap @@ -42,7 +44,7 @@ class CulinomancerShop : LoginListener { //Open methods for the shops - should check player's QP and whether they already have a container generated @JvmStatic fun openShop(player: Player, food: Boolean) { - getShop(player, food).open(player) + getShop(player, food).openFor(player) } //Retrieve a player's shop - should generate the shop if it does not exist. @@ -67,24 +69,24 @@ class CulinomancerShop : LoginListener { } //Generate default food stock based on an amount of total QP. - private fun generateFoodStock(points: Int): Array { - val stock = Array(foodStock.size) { Item(0, 0) } + private fun generateFoodStock(points: Int): Array { + val stock = Array(foodStock.size) { ShopItem(0, 0) } val maxQty = when (val qpTier = (points / 18) - 1) { 0, 1, 2, 3, 4 -> 1 + qpTier else -> qpTier + (qpTier + (qpTier - 5)) //5 = 10, 6 = 13, 7 = 15, etc } for ((index, item) in foodStock.withIndex()) { - stock[index].id = item.id + stock[index].itemId = item.id stock[index].amount = if (item.id == Items.PIZZA_BASE_2283) 1 else maxQty } return stock } //Generate default gear stock based on an amount of total QP. - private fun generateGearStock(points: Int): Array { - val stock = Array(gearStock.size) { Item(0, 0) } + private fun generateGearStock(points: Int): Array { + val stock = Array(gearStock.size) { ShopItem(0, 0) } val qpTier = (points / 18) - for ((index, item) in stock.withIndex()) item.id = gearStock[index] + for ((index, item) in stock.withIndex()) item.itemId = gearStock[index] for (i in 0 until min(qpTier, 10)) { stock[i].amount = 30 @@ -140,4 +142,4 @@ class CulinomancerShop : LoginListener { Item(Items.BUCKET_1925, 1) ) } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/content/global/shop/Shop.kt b/Server/src/main/java/core/game/content/global/shop/Shop.kt deleted file mode 100644 index c83692a89..000000000 --- a/Server/src/main/java/core/game/content/global/shop/Shop.kt +++ /dev/null @@ -1,865 +0,0 @@ -package core.game.content.global.shop - -import api.amountInInventory -import rs09.game.world.GameWorld.ticks -import rs09.game.system.SystemLogger.logInfo -import core.game.node.entity.player.link.diary.DiaryType -import core.cache.def.impl.ItemDefinition -import core.game.container.Container -import core.game.container.ContainerType -import core.game.node.entity.player.Player -import core.game.node.item.Item -import org.rs09.consts.Items.BLACK_CHAINBODY_1107 -import org.rs09.consts.Items.BOWL_1923 -import org.rs09.consts.Items.BUCKET_1925 -import org.rs09.consts.Items.CAKE_TIN_1887 -import org.rs09.consts.Items.CANDLE_36 -import org.rs09.consts.Items.CHAOS_RUNE_562 -import org.rs09.consts.Items.CHISEL_1755 -import org.rs09.consts.Items.DEATH_RUNE_560 -import org.rs09.consts.Items.EMPTY_POT_1931 -import org.rs09.consts.Items.HAMMER_2347 -import org.rs09.consts.Items.JUG_1935 -import org.rs09.consts.Items.NEWCOMER_MAP_550 -import org.rs09.consts.Items.SECURITY_BOOK_9003 -import org.rs09.consts.Items.SHEARS_1735 -import org.rs09.consts.Items.TINDERBOX_590 -import org.rs09.consts.Items.TOKKUL_6529 -import rs09.game.system.config.ItemConfigParser -import java.lang.IndexOutOfBoundsException -import java.util.Arrays -import java.util.ArrayList - -/** - * A class representing a shop. - * - * @author 'Vexia - * @author Jamix77 - */ -open class Shop @JvmOverloads constructor( - /** - * Represents the title of the shop. - */ - val title: String, - /** - * Represents the items in the store. - */ - var items: Array, - /** - * Represents if it's a general store. - */ - val isGeneral: Boolean, - /** - * Represents the currency the shop allows. - */ - val currency: Int = COINS, - /** - * If the shop buys for high alch. - */ - val isHighAlch: Boolean = false -) { - /** - * Gets the containers. - * - * @return The containers. - */ - /** - * Represents the shop containers. - */ - val containers = arrayOf(Container(40, ContainerType.SHOP), Container(40, ContainerType.SHOP)) - /** - * Gets the viewers. - * - * @return The viewers. - */ - /** - * Represents the list of shop viewers. - */ - val viewers: List = ArrayList(20) - /** - * Gets the title. - * - * @return The title. - */ - /** - * Gets the items. - * - * @return The items. - */ - /** - * Gets the general. - * - * @return The general. - */ - /** - * Gets the currency. - * - * @return The currency. - */ - /** - * Gets the bhighAlch. - * - * @return the highAlch - */ - /** - * Gets the SellAllFor value. - * - * @return the sellAllFor - */ - /** - * Sell price for all shop items, if needed. - */ - var sellAllFor = 0 - private set - /** - * Gets the lastRestock. - * - * @return the lastRestock - */ - /** - * Sets the balastRestock. - * - * @param lastRestock the lastRestock to set. - */ - /** - * The last restock. - */ - var lastRestock = 0 - /** - * Check if shop should restock. - * - * @return the restock - */ - /** - * Sets the restock. - * - * @param reStock - */ - /** - * If the shop should restock. - */ - var isRestock = false - /** - * Gets the pointShop. - * - * @return the pointShop - */ - /** - * Sets the pointShop. - * - * @param pointShop the pointShop to set. - */ - /** - * If it's a point shop. - */ - var isPointShop = false - /** - * Gets the npcs. - * - * @return the npcs - */ - /** - * Sets the banpcs. - * - * @param npcs the npcs to set. - */ - /** - * The npcs of the shop. - */ - var npcs: IntArray = intArrayOf() - - /** - * Constructs a new `Shop` `Object`. - * - * @param title the title. - * @param items the items. - * @param general the general. - * @param currency the currency. - * @param highAlch if high alch. - * @param restock if restock. - */ - constructor( - title: String, - items: Array, - general: Boolean, - currency: Int, - highAlch: Boolean, - restock: Boolean, - sellAllFor: Int - ) : this(title, items, general, currency, highAlch) { - this.sellAllFor = sellAllFor - isRestock = restock - } - - /** - * Constructs a new `Shop` `Object` - * - * @param title the shop title - * @param items items the shop can handle - * @param general is this a general store - * @param currency what currency is used - */ - constructor(title: String, items: Array, npcs: IntArray, general: Boolean, currency: Int) : this( - title, - items, - general, - currency, - false - ) { - this.npcs = npcs - } - - /** - * Constructs a new `Shop` `Object`. - * - * @param title the title. - * @param general the general. - */ - constructor(title: String, general: Boolean) : this(title, GENERAL_STORE_ITEMS, general) {} - - /** - * Constructs a new `Shop` `Object`. - * - * @param title the title. - * @param general the general. - * @param highAlch if highAlch. - */ - constructor(title: String, general: Boolean, highAlch: Boolean) : this( - title, - GENERAL_STORE_ITEMS, - general, - COINS, - highAlch - ) { - } - - /** - * Constructs a new `Shop` `Object`. - * - * @param title the title. - * @param general the general. - * @param highAlch if highAlch. - */ - constructor(title: String, general: Boolean, currency: Int, highAlch: Boolean) : this( - title, - GENERAL_STORE_ITEMS, - general, - currency, - highAlch - ) { - } - - /** - * Constructs a new `Shop` `Object`. - * - * @param title the title. - * @param items the items. - * @param npcs the npcs. - * @param general the general. - */ - constructor(title: String, items: Array, npcs: IntArray, general: Boolean) : this( - title, - items, - general, - COINS, - false - ) { - this.npcs = npcs - } - - /** - * Constructs a new `Shop` `Object`. - * - * @param title the title. - * @param npcs the npcs. - * @param general the general. - */ - constructor(title: String, npcs: IntArray, general: Boolean) : this(title, GENERAL_STORE_ITEMS, npcs, general) { - this.npcs = npcs - } - - /** - * Constructs a new `Shop` `Object`. - * - * @param title the title. - * @param npcs the npcs. - * @param general the general. - * @param highAlch if highAlch. - */ - constructor(title: String, npcs: IntArray, general: Boolean, highAlch: Boolean) : this( - title, - GENERAL_STORE_ITEMS, - general, - 995, - highAlch - ) { - this.npcs = npcs - } - - /** - * Method used to open the shop. - * - * @param player the shop. - */ - fun open(player: Player) { - ShopViewer.extend(player, this).open() - - // Browse the Lumbridge General Store - if (title.equals("Lumbridge General Store", ignoreCase = true)) { - player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 0, 18) - } - - // Browse through Oziach's Armour Shop - if (title.equals("Oziach's Armour", ignoreCase = true)) { - player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 1, 20) - } - } - - fun give(player: Player, slot: Int, amount: Int, tabIndex: Int) { - val container = getContainer(tabIndex) - val item = container[slot] ?: return - val add = Item(item.id, amount) - if (add.amount < 1 || !player.inventory.hasSpaceFor(add)) { - player.packetDispatch.sendMessage("You have no inventory space at the moment and cannot get anything.") - return - } - add.amount = getAmount(player, add) - if (add.amount < 1 || !player.inventory.hasSpaceFor(add)) { - player.packetDispatch.sendMessage("You have no inventory space at the moment and cannot get anything.") - return - } - player.inventory.add(add) - update() - } - - /** - * Method used to buy an item from the shop. - * - * @param slot the slot. - * @param amount the amount. - */ - fun buy(player: Player, slot: Int, amount: Int, tabIndex: Int) { - var amount = amount - if (tabIndex == 1 && player.ironmanManager.checkRestriction()) { - return - } - val container = getContainer(tabIndex) - val item = container[slot] ?: return - if (item.amount == 0) { - player.packetDispatch.sendMessage("There is no stock of that item at the moment.") - return - } - if (amount > item.amount && item.amount != -1) { - amount = item.amount - } - val add = Item(item.id, amount) - if (player.inventory.getMaximumAdd(add) < amount) { - add.amount = player.inventory.getMaximumAdd(add) - } - if (add.amount < 1 || !player.inventory.hasSpaceFor(add)) { - player.packetDispatch.sendMessage("You have no inventory space at the moment and cannot buy anything.") - return - } - add.amount = getAmount(player, add) - if (add.amount < 1 || !player.inventory.hasSpaceFor(add)) { - player.packetDispatch.sendMessage("You have no inventory space at the moment and cannot buy anything.") - return - } - val price = add.amount * getBuyPrice(item, player) - val currency = Item(currency, price) - if (!canBuy(player, item, price, currency)) { - return - } - if (handleBuy(player, currency)) { - if (isPointShop) { - decrementPoints(player, price) - } - if (tabIndex == 0) { - if (container.getAmount(item) != -1) container.replace( - Item( - item.id, - container.getAmount(item) - add.amount - ), slot, true - ) - } else { - container.remove(add) - container.shift() - } - - // Achievement Diary Handlers - if (add.id == BLACK_CHAINBODY_1107 && title.equals("Wayne's Chains", ignoreCase = true) && !player.getAttribute("diary:falador:black-chain-bought", false)) { - player.setAttribute("/save:diary:falador:black-chain-bought", true) - } - if (add.id == 12622 && title.equals("Sarah's Farming Shop", ignoreCase = true)) { - player.achievementDiaryManager.finishTask(player, DiaryType.FALADOR, 0, 0) - } - if (add.id == CANDLE_36 && title.equals("Candle Shop", ignoreCase = true)) { - player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 0, 9) - } - if (title.equals("Ranging Guild Ticket Exchange", ignoreCase = true)) { - player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 1, 8) - } - player.inventory.add(add) - update() - } - } - - /** - * Method used to sell an item to the shop. - * - * @param slot the slot. - * @param amount the amount. - */ - fun sell(player: Player, slot: Int, amount: Int, tabIndex: Int) { - var amount = amount - var tabIndex = tabIndex - val item = player.inventory[slot] ?: return - val def = ItemDefinition.forId(item.id) - if (!canSell(player, item, def)) { - return - } - val container = getContainer(item) - if (amount > player.inventory.getAmount(item)) { - amount = player.inventory.getAmount(item) - } - var add = Item(item.id, amount) - if (add.amount > container.getMaximumAdd(add)) { - add.amount = container.getMaximumAdd(add) - } - player.debug("" + add.amount) - if (!container.hasSpaceFor(add) || add.amount < 1) { - player.packetDispatch.sendMessage("The shop has ran out of space.") - return - } - val currency = Item(currency, getSellingValue(add, player)) - if (item.definition.isStackable) { - if (!player.inventory.hasSpaceFor(currency)) { - player.packetDispatch.sendMessage("You don't have enough space for that many " + currency.name.toLowerCase() + ".") - return - } - } - player.debug("Selling item") - if (player.inventory.remove(add, slot, true)) { - if (currency.amount > player.inventory.getMaximumAdd(currency)) { - currency.amount = player.inventory.getMaximumAdd(currency) - } - if (!add.definition.isUnnoted) { - add = Item(add.noteChange, add.amount) - } - if (container.getAmount(add.id) == -1 || container.add(add)) { - if (currency.amount > 0) { - player.debug("Adding coins to inventory") - player.inventory.add(currency) - } - val viewer = player.getExtension(ShopViewer::class.java) - tabIndex = if (container === containers[0]) 0 else 1 - sendStock(player, tabIndex) - if (viewer != null) { - viewer.tabIndex = tabIndex - } - update() - } - } - } - - /** - * Values an item. - * - * @param player the player. - * @param viewer the viewer. - * @param item the item. - * @param sell the sell. - */ - fun value(player: Player, viewer: ShopViewer, item: Item, sell: Boolean) { - if (sell) { - if (isPointShop || item.id == viewer.shop.currency || !item.definition.isTradeable || !viewer.shop.itemAllowed( - item.id - ) - ) { - player.packetDispatch.sendMessage("You can't sell this item.") - return - } - val value = viewer.shop.getSellingValue(Item(item.id, 1), player) - var currency = - if (isPointShop) pointsName else ItemDefinition.forId(viewer.shop.currency).name.toLowerCase() - if (value == 1 && currency[currency.length - 1] == 's') { - currency = currency.substring(0, currency.length - 1) - } - player.packetDispatch.sendMessage(item.name + ": shop will buy for " + value + " " + currency + ".") - } else { - val value = viewer.shop.getBuyPrice(item, player) - var name = - if (isPointShop) pointsName + "s" else ItemDefinition.forId(viewer.shop.currency).name.toLowerCase() - if (value == 1 && name[name.length - 1] == 's') { - name = name.substring(0, name.length - 1) - } - player.packetDispatch.sendMessage("" + item.name + ": currently costs " + value + " " + name + ".") - } - } - - /** - * Method used to send a stock - * - * @param player - * @param tabIndex - */ - fun sendStock(player: Player, tabIndex: Int) { - val main = tabIndex == 0 - player.packetDispatch.sendInterfaceConfig(620, 23, !main) - player.packetDispatch.sendInterfaceConfig(620, 24, main) - player.packetDispatch.sendInterfaceConfig(620, 29, !main) - player.packetDispatch.sendInterfaceConfig(620, 25, main) - player.packetDispatch.sendInterfaceConfig(620, 27, main) - player.packetDispatch.sendInterfaceConfig(620, 26, false) - player.packetDispatch.sendAccessMask(1278, if (main) 23 else 24, 620, 0, 40) - } - - /** - * Method used to update the viewers. - */ - fun update() { - for (viewer in viewers) { - viewer.update() - } - } - - /** - * Method used to restock the shop. - */ - fun restock() { - for (container in containers) { - for (i in container.toArray().indices) { - val main = container === containers[0] - val item = container.toArray()[i] ?: continue - var reduce = !main - if (main) { - if (item.amount < items[i].amount) { - item.amount = item.amount + 1 - } - reduce = item.amount > items[i].amount - } - if (reduce) { - val amount = item.amount - 1 - if (amount < 1 && !main) { - container.remove(item) - } else { - item.amount = amount - } - if (!main) { - container.shift() - } - } - } - } - update() - } - - /** - * Checks if the player can sell an item to the shop. - * - * @param player the player. - * @param item the item. - * @param def the def. - * @return `True` if so. - */ - open fun canSell(player: Player, item: Item, def: ItemDefinition): Boolean { - if (isPointShop || item.definition.hasDestroyAction() || !def.isTradeable || !itemAllowed(item.id)) { - player.packetDispatch.sendMessage("You can't sell this item to this shop.") - return false - } - if (item.id == currency) { - player.packetDispatch.sendMessage("You can't sell " + item.name.toLowerCase() + " to a shop.") - return false - } - return true - } - - /** - * Gets the amount to buy/sell. - * - * @param player the player. - * @param add the added item. - * @return the amount. - */ - fun getAmount(player: Player?, add: Item): Int { - return add.amount - } - - /** - * Checks if the player can buy the item. - * - * @param player the player. - * @param currency the currency. - * @return `True` if so. - */ - fun handleBuy(player: Player, currency: Item?): Boolean { - return isPointShop || player.inventory.remove(currency) - } - - /** - * Checks if the player can buy from the shop. - * - * @param player the player. - * @param item the item. - * @param price the price. - * @param currency the currency. - * @return `True` if they can buy. - */ - fun canBuy(player: Player, item: Item, price: Int, currency: Item): Boolean { - if (!isPointShop && !player.inventory.containsItem(currency)) { - player.packetDispatch.sendMessage( - "You don't have enough " + ItemDefinition.forId(currency.id).name.toLowerCase() + "." - ) - return false - } - if (isPointShop && getPoints(player) < price) { - player.sendMessage("You don't have enough " + pointsName + "s.") - return false - } - return true - } - - /** - * Gets the points. - * - * @param player the player. - * @return the points. - */ - fun getPoints(player: Player?): Int { - return 0 - } - - /** - * Decrements the points. - * - * @param player the player. - * @param decrement the decrementation. - */ - fun decrementPoints(player: Player?, decrement: Int) {} - - /** - * Gets the points name. - * - * @return the name. - */ - val pointsName: String - get() = "" - - /** - * Gets the value gained for selling this item to a certain shop. - * - * @param item The item to sell. - * @param player the player. - * @return The value. - */ - fun getSellingValue(item: Item, player: Player): Int { - var item = item - if (!item.definition.isUnnoted) { - player.setAttribute("shop:originalId", item.id) - item = Item(item.noteChange, item.amount) - } - var amount = getContainer(1).getAmount(item) - if (amount < 1) { - amount = getContainer(0).getAmount(item) - } - return getSellingValue(player, amount, item) - } - - /** - * Gets the selling value formula based. - * - * @param amount the amount. - * @param item the item. - * @return the selling value. - */ - private fun getSellingValue(player: Player, amount: Int, item: Item): Int { - val id = player.getAttribute("shop:originalId", item.id) - if (item.amount > amountInInventory(player, id)) { - item.amount = amountInInventory(player, id) - player.removeAttribute("shop:originalId") - } - val diff = if (item.definition.isStackable) 0.005 else 0.05 - var maxMod = 1.0 - amount * diff - if (maxMod < 0.25) { - maxMod = 0.25 - } - var minMod = maxMod - (item.amount - 1) * diff - if (minMod < 0.25) { - minMod = 0.25 - } - val mod = (maxMod + minMod) / 2 - logInfo("" + item.definition.getAlchemyValue(isHighAlch) + " " + mod + " " + item.amount) - val baseValue = item.definition.getAlchemyValue(isHighAlch) - var value = (baseValue * mod * item.amount).toInt() - if (currency == TOKKUL_6529 && item.id == CHAOS_RUNE_562) value = 13 * item.amount - if (currency == TOKKUL_6529 && item.id == DEATH_RUNE_560) value = 27 * item.amount - if (item.id == 12183) { - value = 25 * item.amount - } - return value - } - - /** - * Gets the buying price. - * - * @param item the item. - * @return the price. - */ - open fun getBuyPrice(item: Item, player: Player): Int { - var item = item - item = Item(item.id, 1) - var price = item.definition.value - val sellVal = getSellingValue(item, player) - if (price < sellVal) { - price = getSellingValue(player, 0, item) + sellVal - (sellVal - item.definition.maxValue) - } - if (price < 0) { - price = 1 - } - if (currency == TOKKUL) { - val tokkul = item.definition.getConfiguration("tokkul_price", -1) - if (tokkul > 0) { - price = tokkul - } - if (player.achievementDiaryManager.karamjaGlove != -1) { - price = kotlin.math.floor(price * 0.87).toInt() - } - } - if (currency == ARCHERY_TICKET) { - val tickets = item.definition.getConfiguration(ItemConfigParser.ARCHERY_TICKET_PRICE, -1) - if (tickets > 0) { - price = tickets - } - } - return if (sellAllFor > 0) sellAllFor else price - } - - /** - * Checks if the item is allowed to be sold to the shop. - * - * @param itemId the item id. - * @return `True` if so. - */ - fun itemAllowed(itemId: Int): Boolean { - if (isGeneral) { - return true - } - var noteId = ItemDefinition.forId(itemId).noteId - if (!ItemDefinition.forId(itemId).isUnnoted) { - noteId = ItemDefinition.forId(noteId).noteId - } - for (id in items) { - if (itemId == id.id || noteId > -1 && noteId == ItemDefinition.forId(id.id).noteId) { - return true - } - } - return false - } - - /** - * Gets the container the item should go to. - * - * @param item the item. - * @return the container. - */ - fun getContainer(item: Item): Container { - val itemId = item.id - var noteId = ItemDefinition.forId(itemId).noteId - if (!ItemDefinition.forId(itemId).isUnnoted) { - noteId = ItemDefinition.forId(noteId).noteId - } - for (i in items) { - if (i.id == item.id || noteId > -1 && noteId == ItemDefinition.forId(i.id).noteId) { - return getContainer(0) - } - } - return getContainer(1) - } - - /** - * Creates a copy of this shop. - * - * @return the shop. - */ - fun copy(): Shop { - return Shop(title, items, isGeneral, currency, isHighAlch) - } - - /** - * Gets the container on the slot. - * - * @param tabIndex the tab index. - * @return the container. - */ - fun getContainer(tabIndex: Int): Container { - if (tabIndex > containers.size) { - throw IndexOutOfBoundsException("Error! Shop tab index out of bounds.") - } - return containers[tabIndex] - } - - override fun toString(): String { - return "Shop [containers=" + Arrays.toString(containers) + ", viewers=" + viewers + ", title=" + title + ", items=" + Arrays.toString( - items - ) + ", general=" + isGeneral + ", currency=" + currency + ", highAlch=" + isHighAlch + "]" - } - - fun setItems(items: ArrayList) { - this.items = items.toTypedArray() - } - - companion object { - /** - * Represents the general store items. - */ - val GENERAL_STORE_ITEMS = arrayOf( - Item(EMPTY_POT_1931, 5), - Item(JUG_1935, 5), - Item(SHEARS_1735, 2), - Item(BUCKET_1925, 3), - Item(BOWL_1923, 2), - Item(CAKE_TIN_1887, 2), - Item(TINDERBOX_590, 2), - Item(CHISEL_1755, 2), - Item(HAMMER_2347, 5), - Item(NEWCOMER_MAP_550, 5), - Item(SECURITY_BOOK_9003, 5) - ) - - /** - * Represents the coins item. - */ - private const val COINS = 995 - - /** - * Represents the tokkul item id. - */ - private const val TOKKUL = 6529 - - /** - * Represents the archery ticket item id - */ - private const val ARCHERY_TICKET = 1464 - } - /** - * Constructs a new `Shop` `Object`. - * - * @param title the title. - * @param items the items. - * @param isGeneral the general. - * @param currency the currency. - * @param isHighAlch if high alch. - */ - /** - * Constructs a new `Shop` `Object`. - * - * @param title the title. - * @param items the items. - * @param general the general. - */ - init { - this.getContainer(0).add(*items) - isRestock = true - lastRestock = ticks + 100 - } -} \ No newline at end of file diff --git a/Server/src/main/java/core/game/content/global/shop/ShopViewer.java b/Server/src/main/java/core/game/content/global/shop/ShopViewer.java deleted file mode 100644 index c910aa992..000000000 --- a/Server/src/main/java/core/game/content/global/shop/ShopViewer.java +++ /dev/null @@ -1,154 +0,0 @@ -package core.game.content.global.shop; - -import core.game.component.CloseEvent; -import core.game.component.Component; -import core.game.node.entity.player.Player; -import core.net.packet.PacketRepository; -import core.net.packet.context.ContainerContext; -import core.net.packet.out.ContainerPacket; - -/** - * Represents the viewing of a shop. - * @author 'Vexia - */ -public final class ShopViewer { - - /** - * Represents the main component. - */ - private static final Component COMPONENT = new Component(620).setCloseEvent(new ShopCloseEvent()); - - /** - * Represents the single tab component. - */ - private static final Component SINGLE_TAB = new Component(621); - - /** - * Represents the player. - */ - private final Player player; - - /** - * Represents the shop being viewed. - */ - private Shop shop; - - /** - * Represents the tab index. - */ - private int tabIndex; - - /** - * Constructs a new {@code ShopViewer} {@code Object}. - * @param player the player. - * @param shop the shop. - */ - public ShopViewer(Player player, Shop shop) { - this.player = player; - this.shop = shop; - } - - /** - * Extends a shop a shop viewer to the player instance. - * @param player the player. - * @param shop the shop. - * @return the viewer. - */ - public static ShopViewer extend(final Player player, Shop shop) { - ShopViewer viewer = player.getExtension(ShopViewer.class); - if (viewer != null) { - return viewer; - } - player.addExtension(ShopViewer.class, (viewer = new ShopViewer(player, shop))); - return viewer; - } - - /** - * Method used to open the shop visual. - */ - public void open() { - update(); - shop.getViewers().add(this); - player.getInterfaceManager().open(COMPONENT); - player.getInterfaceManager().openSingleTab(SINGLE_TAB); - shop.sendStock(player, tabIndex); - player.getPacketDispatch().sendRunScript(25, "vg", 868, 92); - player.getPacketDispatch().sendAccessMask(1278, 0, 621, 0, 28); - player.getPacketDispatch().sendString(shop.getTitle(), 620, 22); - player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", "", "", "", "", "Buy X", "Buy 10", "Buy 5", "Buy 1", "Value", -1, 0, 4, 10, 92, 620 << 16 | 23); - player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", "", "", "", "", "Buy X", "Buy 10", "Buy 5", "Buy 1", "Value", -1, 0, 4, 10, 31, (620 << 16) | 24); - player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", "", "", "", "", "Sell X", "Sell 10", "Sell 5", "Sell 1", "Value", -1, 0, 7, 4, 93, 621 << 16); - } - - /** - * Method used to update the contents on the component. - */ - public void update() { - PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 93, player.getInventory().toArray(), 28, false)); - PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 92, shop.getContainer(0).toArray(), shop.getContainer(0).itemCount(), false)); - PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, 64271, 31, shop.getContainer(1).toArray(), shop.getContainer(1).itemCount(), false)); - } - - /** - * Method used to show a stock. - */ - public void showStock(int tabIndex) { - this.tabIndex = tabIndex; - shop.sendStock(player, tabIndex); - update(); - } - - /** - * Sets the tabIndex. - * @param tabIndex The tabIndex to set. - */ - public void setTabIndex(int tabIndex) { - this.tabIndex = tabIndex; - } - - /** - * Gets the player. - * @return The player. - */ - public Player getPlayer() { - return player; - } - - /** - * Gets the shop. - * @return The shop. - */ - public Shop getShop() { - return shop; - } - - /** - * Gets the tabIndex. - * @return The tabIndex. - */ - public int getTabIndex() { - return tabIndex; - } - - /** - * Represents the close event when a shop is closed. - * @author 'Vexia - */ - public static final class ShopCloseEvent implements CloseEvent { - - @Override - public boolean close(Player player, Component c) { - final ShopViewer viewer = player.getExtension(ShopViewer.class); - if (viewer == null) { - return true; - } - player.removeExtension(ShopViewer.class); - viewer.getShop().getViewers().remove(viewer); - player.getInterfaceManager().closeSingleTab(); - player.removeAttribute("spawning_items"); - return true; - } - - } - -} diff --git a/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardEntry.java b/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardEntry.java deleted file mode 100644 index 0996dd66a..000000000 --- a/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardEntry.java +++ /dev/null @@ -1,10 +0,0 @@ -package core.game.content.global.worldevents.shootingstar; - -public class ScoreboardEntry{ - public String playerName; - public int time; - public ScoreboardEntry(String player, int time){ - this.playerName = player; - this.time = time; - } -} diff --git a/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardHandler.java b/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardHandler.java deleted file mode 100644 index d2c011b97..000000000 --- a/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -package core.game.content.global.worldevents.shootingstar; - -import core.cache.def.impl.SceneryDefinition; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import rs09.game.world.GameWorld; -import core.plugin.Plugin; - -public class ScoreboardHandler extends OptionHandler { - int index = 0; - int ifaceid = ShootingStarScoreboard.iface.getId(); - @Override - public boolean handle(Player player, Node node, String option) { - ScoreboardManager.getEntries().forEach(e -> { - player.getPacketDispatch().sendString("" + Math.floor(((GameWorld.getTicks() - e.time) / 0.6) / 60) + " minutes ago",ifaceid,index + 6); - player.getPacketDispatch().sendString(e.playerName,ifaceid,index + 11); - index++; - }); - index = 0; - player.getInterfaceManager().open(ShootingStarScoreboard.iface); - return true; - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(38669).getHandlers().put("option:read",this); - - return this; - } -} diff --git a/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardManager.java b/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardManager.java deleted file mode 100644 index 86d8f7099..000000000 --- a/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ScoreboardManager.java +++ /dev/null @@ -1,23 +0,0 @@ -package core.game.content.global.worldevents.shootingstar; - -import core.game.node.entity.player.Player; -import rs09.game.system.SystemLogger; -import rs09.game.world.GameWorld; - -import java.util.ArrayList; -import java.util.List; - -public class ScoreboardManager { - public static List entries = new ArrayList<>(20); - - public static void submit(Player player){ - if(entries.size() == 5){ - entries.remove(0); - } - entries.add(new ScoreboardEntry(player.getUsername(), GameWorld.getTicks())); - } - - public static List getEntries(){ - return entries; - } -} diff --git a/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ShootingStarScoreboard.java b/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ShootingStarScoreboard.java deleted file mode 100644 index 654151ffb..000000000 --- a/Server/src/main/java/core/game/content/global/worldevents/shootingstar/ShootingStarScoreboard.java +++ /dev/null @@ -1,22 +0,0 @@ -package core.game.content.global.worldevents.shootingstar; - -import core.game.component.Component; -import core.game.component.ComponentDefinition; -import core.game.component.ComponentPlugin; -import core.game.node.entity.player.Player; -import core.plugin.Plugin; - -public class ShootingStarScoreboard extends ComponentPlugin { - public static Component iface = new Component(787); - - @Override - public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { - return true; - } - - @Override - public Plugin newInstance(Object arg) throws Throwable { - ComponentDefinition.put(iface.getId(),this); - return null; - } -} diff --git a/Server/src/main/java/core/game/content/quest/members/merlinscrystal/CandleMakerDialogue.java b/Server/src/main/java/core/game/content/quest/members/merlinscrystal/CandleMakerDialogue.java index 6585260c1..70092c9f4 100644 --- a/Server/src/main/java/core/game/content/quest/members/merlinscrystal/CandleMakerDialogue.java +++ b/Server/src/main/java/core/game/content/quest/members/merlinscrystal/CandleMakerDialogue.java @@ -9,6 +9,7 @@ import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; import core.game.node.item.Item; import core.plugin.Plugin; +import rs09.game.content.global.shops.Shops; import rs09.game.system.config.ShopParser; import rs09.plugin.ClassScanner; @@ -58,7 +59,7 @@ public final class CandleMakerDialogue extends DialoguePlugin { NPC npc = node.asNpc(); Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); if (quest.getStage(player) > 60) { - ShopParser.Companion.openUid(player, 198); + Shops.openId(player, 198); } else { npc.openShop(player); } @@ -175,7 +176,7 @@ public final class CandleMakerDialogue extends DialoguePlugin { case 30: end(); if (quest.getStage(player) > 60) { - ShopParser.Companion.openUid(player, 198); + Shops.openId(player, 198); } else { npc.openShop(player); } diff --git a/Server/src/main/java/core/game/content/quest/members/waterfallquest/WaterfallPlugin.java b/Server/src/main/java/core/game/content/quest/members/waterfallquest/WaterfallPlugin.java index 5adb516a2..4818bcb45 100644 --- a/Server/src/main/java/core/game/content/quest/members/waterfallquest/WaterfallPlugin.java +++ b/Server/src/main/java/core/game/content/quest/members/waterfallquest/WaterfallPlugin.java @@ -289,7 +289,6 @@ public final class WaterfallPlugin extends OptionHandler { public boolean pulse() { player.getPacketDispatch().sendMessage("You are washed downstream but feel lucky to be alive."); player.teleport(new Location(2527, 3413)); - player.logoutListeners.remove("waterfall"); return true; } }); diff --git a/Server/src/main/java/core/game/content/ttrail/ClueLevel.java b/Server/src/main/java/core/game/content/ttrail/ClueLevel.java index 05d21c73b..54d03960f 100644 --- a/Server/src/main/java/core/game/content/ttrail/ClueLevel.java +++ b/Server/src/main/java/core/game/content/ttrail/ClueLevel.java @@ -524,7 +524,7 @@ public enum ClueLevel { value += item.getValue(); } player.sendMessage("Your clue is worth approximately " + NumberFormat.getInstance().format(value) + " coins!"); - player.getPacketDispatch().sendAccessMask(1278, 4, 364, 0, 6); + player.getPacketDispatch().sendIfaceSettings(1278, 4, 364, 0, 6); InterfaceContainer.generateItems(player, rewards.toArray(new Item[] {}), new String[] { "" }, 364, 4, 3, 3); return; } diff --git a/Server/src/main/java/core/game/interaction/inter/EquipmentInterface.java b/Server/src/main/java/core/game/interaction/inter/EquipmentInterface.java index 282bf3320..bf2541046 100644 --- a/Server/src/main/java/core/game/interaction/inter/EquipmentInterface.java +++ b/Server/src/main/java/core/game/interaction/inter/EquipmentInterface.java @@ -113,8 +113,8 @@ public final class EquipmentInterface extends ComponentPlugin { boolean skulled = p.getSkullManager().isSkulled(); boolean usingProtect = p.getPrayer().get(PrayerType.PROTECT_ITEMS); p.getInterfaceManager().openComponent(102); - p.getPacketDispatch().sendAccessMask(211, 0, 2, 6684690, 4); - p.getPacketDispatch().sendAccessMask(212, 0, 2, 6684693, 42); + p.getPacketDispatch().sendIfaceSettings(211, 0, 2, 6684690, 4); + p.getPacketDispatch().sendIfaceSettings(212, 0, 2, 6684693, 42); Container[] itemArray = DeathTask.getContainers(p); Container kept = itemArray[0]; int state = 0; // 1=familiar carrying items @@ -166,11 +166,11 @@ public final class EquipmentInterface extends ComponentPlugin { BitregisterAssembler assembly = new BitregisterAssembler(new String[] { "Equip" }); assembly.enableExamineOption(); assembly.enableSlotSwitch(); - p.getPacketDispatch().sendAccessMask(assembly.calculateRegister(), 0, 670, 0, 27); + p.getPacketDispatch().sendIfaceSettings(assembly.calculateRegister(), 0, 670, 0, 27); p.getInventory().getListeners().add(listener); p.getInventory().refresh(); ItemDefinition.statsUpdate(p); - p.getPacketDispatch().sendAccessMask(1278, 14, 667, 0, 13); + p.getPacketDispatch().sendIfaceSettings(1278, 14, 667, 0, 13); break; } } diff --git a/Server/src/main/java/core/game/interaction/inter/ShoppingPlugin.java b/Server/src/main/java/core/game/interaction/inter/ShoppingPlugin.java index 56c2c0c6b..64787fc23 100644 --- a/Server/src/main/java/core/game/interaction/inter/ShoppingPlugin.java +++ b/Server/src/main/java/core/game/interaction/inter/ShoppingPlugin.java @@ -1,3 +1,4 @@ +/* package core.game.interaction.inter; import static api.ContentAPIKt.*; @@ -15,11 +16,13 @@ import core.plugin.Plugin; import kotlin.Unit; import kotlin.jvm.functions.Function1; +*/ /** * Represents the plugin used to handle the shopping interface. * @author 'Vexia * @version 1.0 - */ + *//* + @Initializable public final class ShoppingPlugin extends ComponentPlugin { @@ -97,13 +100,15 @@ public final class ShoppingPlugin extends ComponentPlugin { return true; } - /** + */ +/** * Method used to value an item. * @param player the player. * @param viewer the viewer. * @param item the item. * @param sell the sell. - */ + *//* + private void value(final Player player, final ShopViewer viewer, final Item item, final boolean sell) { if (item == null) { return; @@ -111,11 +116,13 @@ public final class ShoppingPlugin extends ComponentPlugin { viewer.getShop().value(player, viewer, item, sell); } - /** + */ +/** * Gets the run script for selling an item. * @return the script. * @param slot the slot. - */ + *//* + private Function1 getRunScript(final ShopViewer viewer, final int slot, final int componentId) { return (value) -> { switch (componentId){ @@ -130,12 +137,15 @@ public final class ShoppingPlugin extends ComponentPlugin { }; } - /** + */ +/** * Gets the amount by the opcode. * @param opcode the opcode. * @return the amount. - */ + *//* + private int getAmount(int opcode) { return opcode == 196 ? 1 : opcode == 124 ? 5 : opcode == 199 ? 10 : -1; } } +*/ diff --git a/Server/src/main/java/core/game/interaction/item/ExplorersRingPlugin.kt b/Server/src/main/java/core/game/interaction/item/ExplorersRingPlugin.kt index 87b49d3eb..5b0c3cdd7 100644 --- a/Server/src/main/java/core/game/interaction/item/ExplorersRingPlugin.kt +++ b/Server/src/main/java/core/game/interaction/item/ExplorersRingPlugin.kt @@ -26,7 +26,7 @@ import rs09.game.interaction.InteractionListener * * @author Vexia */ -class ExplorersRingPlugin : InteractionListener() { +class ExplorersRingPlugin : InteractionListener { val RINGS = intArrayOf(Items.EXPLORERS_RING_1_13560, Items.EXPLORERS_RING_2_13561, Items.EXPLORERS_RING_3_13562) val CABBAGE_PORT = Location.create(3051, 3291, 0) diff --git a/Server/src/main/java/core/game/interaction/npc/GabootyTrade.java b/Server/src/main/java/core/game/interaction/npc/GabootyTrade.java index 08d5dc4ae..ecb525db8 100644 --- a/Server/src/main/java/core/game/interaction/npc/GabootyTrade.java +++ b/Server/src/main/java/core/game/interaction/npc/GabootyTrade.java @@ -7,6 +7,7 @@ import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.plugin.Plugin; +import rs09.game.content.global.shops.Shops; import rs09.game.system.config.ShopParser; /** @@ -39,11 +40,11 @@ public final class GabootyTrade extends OptionHandler { return true; case "trade-co-op": - ShopParser.Companion.openUid(player, 226); + Shops.openId(player, 226); return true; case "trade-drinks": - ShopParser.Companion.openUid(player, 227); + Shops.openId(player, 227); return true; } break; diff --git a/Server/src/main/java/core/game/interaction/npc/NPCTradePlugin.kt b/Server/src/main/java/core/game/interaction/npc/NPCTradePlugin.kt deleted file mode 100644 index 72928510e..000000000 --- a/Server/src/main/java/core/game/interaction/npc/NPCTradePlugin.kt +++ /dev/null @@ -1,78 +0,0 @@ -package core.game.interaction.npc - -import api.* -import core.cache.def.impl.NPCDefinition -import core.game.component.Component -import core.game.content.dialogue.FacialExpression -import core.plugin.Initializable -import core.game.interaction.OptionHandler -import core.game.node.Node -import core.game.node.entity.npc.NPC -import core.game.node.entity.player.Player -import core.plugin.Plugin -import core.game.node.entity.skill.crafting.TanningProduct -import org.rs09.consts.NPCs -import rs09.game.interaction.InteractionListener -import rs09.tools.END_DIALOGUE - -/** - * Represents the plugin used for an npc with the trade option. - * @author Ceikry - * @version 1.0 - */ -class NPCTradePlugin : InteractionListener() { - override fun defineListeners() { - on(NPC, "trade", "shop"){player, node -> - val npc = node as NPC - if (npc.id == 2824) { - TanningProduct.open(player, 2824) - return@on true - } - if (npc.id == 7601) { - openInterface(player, 732) - return@on true - } - return@on npc.openShop(player) - } - - on(NPCs.SIEGFRIED_ERKLE_933, NPC, "trade"){player, node -> - val points = getQP(player) - if(points < 40){ - sendNPCDialogue(player, NPCs.SIEGFRIED_ERKLE_933, "I'm sorry, adventurer, but you need 40 quest points to buy from me.") - return@on true - } - node.asNpc().openShop(player) - return@on true - } - - on(NPCs.FUR_TRADER_1316, NPC,"trade") { player, node -> - if (!isQuestComplete(player, "Fremennik Trials")) { - sendNPCDialogue(player, NPCs.FUR_TRADER_1316, "I don't sell to outerlanders.", FacialExpression.ANNOYED).also { END_DIALOGUE } - } else { - END_DIALOGUE.also { node.asNpc().openShop(player) } - } - return@on true - } - - on(NPCs.FISH_MONGER_1315, NPC,"trade") { player, node -> - if (!isQuestComplete(player, "Fremennik Trials")) { - sendNPCDialogue(player, NPCs.FISH_MONGER_1315, "I don't sell to outerlanders.", FacialExpression.ANNOYED).also { END_DIALOGUE } - } else { - END_DIALOGUE.also { node.asNpc().openShop(player) } - } - return@on true - } - } - - override fun defineDestinationOverrides() { - setDest(NPC,"trade","shop"){_,node -> - val npc = node as NPC - if (npc.getAttribute("facing_booth", false)) { - val offsetX = npc.direction.stepX shl 1 - val offsetY = npc.direction.stepY shl 1 - return@setDest npc.location.transform(offsetX, offsetY, 0) - } - return@setDest node.location - } - } -} \ No newline at end of file diff --git a/Server/src/main/java/core/game/interaction/object/BuyCrateOptionPlugin.java b/Server/src/main/java/core/game/interaction/object/BuyCrateOptionPlugin.java index b5535e752..5ff264f16 100644 --- a/Server/src/main/java/core/game/interaction/object/BuyCrateOptionPlugin.java +++ b/Server/src/main/java/core/game/interaction/object/BuyCrateOptionPlugin.java @@ -6,6 +6,7 @@ import core.game.node.Node; import core.game.node.entity.player.Player; import core.plugin.Initializable; import core.plugin.Plugin; +import rs09.game.content.global.shops.Shops; import rs09.game.system.config.ShopParser; /** @@ -18,7 +19,7 @@ public final class BuyCrateOptionPlugin extends OptionHandler { @Override public boolean handle(Player player, Node node, String option) { - ShopParser.Companion.openUid(player, 93); + Shops.openId(player, 93); return true; } diff --git a/Server/src/main/java/core/game/interaction/object/CulinoChestListener.kt b/Server/src/main/java/core/game/interaction/object/CulinoChestListener.kt index 9c47b357a..ec0fecb32 100644 --- a/Server/src/main/java/core/game/interaction/object/CulinoChestListener.kt +++ b/Server/src/main/java/core/game/interaction/object/CulinoChestListener.kt @@ -18,7 +18,7 @@ import rs09.game.interaction.InteractionListener * Handles the culino chest options. * @author Ceikry */ -class CulinoChestListener : InteractionListener() { +class CulinoChestListener : InteractionListener { val CULINO_CHEST = Scenery.CHEST_12309 override fun defineListeners() { diff --git a/Server/src/main/java/core/game/interaction/object/sorceress/GardenObjectsPlugin.kt b/Server/src/main/java/core/game/interaction/object/sorceress/GardenObjectsPlugin.kt index aa900ce26..e69566e99 100644 --- a/Server/src/main/java/core/game/interaction/object/sorceress/GardenObjectsPlugin.kt +++ b/Server/src/main/java/core/game/interaction/object/sorceress/GardenObjectsPlugin.kt @@ -26,7 +26,7 @@ import rs09.game.world.GameWorld import rs09.plugin.ClassScanner -class GardenObjectsPlugin : InteractionListener() { +class GardenObjectsPlugin : InteractionListener { val SQIRK_TREES = intArrayOf(21767, 21768, 21769, 21766) val FOUNTAIN = 21764 diff --git a/Server/src/main/java/core/game/node/entity/npc/NPC.java b/Server/src/main/java/core/game/node/entity/npc/NPC.java index a7368a983..80ba045bc 100644 --- a/Server/src/main/java/core/game/node/entity/npc/NPC.java +++ b/Server/src/main/java/core/game/node/entity/npc/NPC.java @@ -3,7 +3,6 @@ package core.game.node.entity.npc; import api.events.NPCKillEvent; import core.cache.def.impl.NPCDefinition; import core.game.content.dialogue.DialoguePlugin; -import core.game.content.global.shop.Shop; import core.game.interaction.Interaction; import core.game.interaction.MovementPulse; import core.game.node.entity.Entity; @@ -33,6 +32,7 @@ import core.game.world.update.flag.npc.NPCForceChat; import core.game.world.update.flag.npc.NPCSwitchId; import core.tools.RandomFunction; import rs09.game.content.global.GlobalKillCounter; +import rs09.game.content.global.shops.Shops; import rs09.game.content.jobs.JobManager; import rs09.game.node.entity.combat.CombatSwingHandler; import rs09.game.system.config.NPCConfigParser; @@ -140,11 +140,6 @@ public class NPC extends Entity { * If the npc can never walk. */ private boolean neverWalks; - - /** - * The shop of this npc. - */ - private Shop shop; /** * The force talk string. @@ -234,18 +229,6 @@ public class NPC extends Entity { npc.size = size; } } - if (definition.hasAction("trade")) { - shop = ShopParser.Companion.getSHOPS().get(getId()); - if (shop != null) { - shop = shop.copy(); - } - } - if (definition.hasAction("sew")) { - shop = ShopParser.Companion.getSHOPS().get(getId()); - if (shop != null) { - shop = shop.copy(); - } - } } @Override @@ -321,23 +304,14 @@ public class NPC extends Entity { * @return {@code True} if so. */ public boolean openShop(Player player) { - shop = null; - if(shop != null){ - player.debug("testing new shop for: " + name); - } - if (shop == null) { - shop = ShopParser.Companion.getSHOPS().get(getId()); - if (shop == null) { - return false; - } - } if (getName().contains("assistant")) { NPC n = RegionManager.getNpc(this, getId() - 1); if (n != null) { return n.openShop(player); } } - shop.open(player); + + Shops.getShopsByNpc().get(id).openFor(player); //Fix for issue #11 for shops keeping dialogue open. DialoguePlugin dialogue = player.getDialogueInterpreter().getDialogue(); @@ -470,14 +444,6 @@ public class NPC extends Entity { } } } - if (shop != null) { - if (shop.getLastRestock() < GameWorld.getTicks()) { - if (shop.isRestock()) { - shop.restock(); - shop.setLastRestock(GameWorld.getTicks() + 100); - } - } - } if (forceTalk != null && getAttribute("lastForceTalk", 0) < GameWorld.getTicks()) { sendChat(forceTalk); setAttribute("lastForceTalk", GameWorld.getTicks() + RandomFunction.random(15, 30)); @@ -942,22 +908,6 @@ public class NPC extends Entity { return this; } - /** - * Gets the shop. - * @return the shop - */ - public Shop getShop() { - return shop; - } - - /** - * Sets the bashop. - * @param shop the shop to set. - */ - public void setShop(Shop shop) { - this.shop = shop; - } - /** * Gets the slayerExperience. * @return The slayerExperience. diff --git a/Server/src/main/java/core/game/node/entity/player/Player.java b/Server/src/main/java/core/game/node/entity/player/Player.java index b1eb8aead..60f7aefe5 100644 --- a/Server/src/main/java/core/game/node/entity/player/Player.java +++ b/Server/src/main/java/core/game/node/entity/player/Player.java @@ -20,6 +20,7 @@ import core.game.node.entity.player.info.RenderInfo; import core.game.node.entity.player.info.Rights; import core.game.node.entity.player.info.UIDInfo; import core.game.node.entity.player.info.login.LoginConfiguration; +import core.game.node.entity.player.info.login.PlayerParser; import core.game.node.entity.player.link.*; import core.game.node.entity.player.link.appearance.Appearance; import core.game.node.entity.player.link.audio.AudioManager; @@ -63,12 +64,14 @@ import core.tools.RandomFunction; import core.tools.StringUtils; import kotlin.Unit; import kotlin.jvm.functions.Function1; +import org.json.simple.JSONObject; import org.rs09.consts.Items; import rs09.GlobalStats; import rs09.ServerConstants; import rs09.game.VarpManager; import rs09.game.node.entity.combat.CombatSwingHandler; import rs09.game.node.entity.combat.equipment.EquipmentDegrader; +import rs09.game.node.entity.player.info.login.PlayerSaveParser; import rs09.game.node.entity.player.info.login.PlayerSaver; import rs09.game.node.entity.skill.runecrafting.PouchManager; import rs09.game.node.entity.state.newsys.State; diff --git a/Server/src/main/java/core/game/node/entity/player/link/PacketDispatch.java b/Server/src/main/java/core/game/node/entity/player/link/PacketDispatch.java index b36a385bd..08bdf7217 100644 --- a/Server/src/main/java/core/game/node/entity/player/link/PacketDispatch.java +++ b/Server/src/main/java/core/game/node/entity/player/link/PacketDispatch.java @@ -97,14 +97,14 @@ public final class PacketDispatch { /** * Send a access mask. - * @param id The access mask id. + * @param settingsHash The access mask settingsHash. * @param childId The access mask child id. * @param interfaceId The access mask interface Id. * @param offset The access mask off set. * @param length The access mask length. */ - public void sendAccessMask(int id, int childId, int interfaceId, int offset, int length) { - PacketRepository.send(AccessMask.class, new AccessMaskContext(player, id, childId, interfaceId, offset, length)); + public void sendIfaceSettings(int settingsHash, int childId, int interfaceId, int offset, int length) { + PacketRepository.send(AccessMask.class, new AccessMaskContext(player, settingsHash, childId, interfaceId, offset, length)); } /** diff --git a/Server/src/main/java/core/game/node/entity/player/link/music/MusicPlayer.java b/Server/src/main/java/core/game/node/entity/player/link/music/MusicPlayer.java index 68e73a28f..a1839bcb8 100644 --- a/Server/src/main/java/core/game/node/entity/player/link/music/MusicPlayer.java +++ b/Server/src/main/java/core/game/node/entity/player/link/music/MusicPlayer.java @@ -10,7 +10,6 @@ import core.net.packet.context.StringContext; import core.net.packet.out.MusicPacket; import core.net.packet.out.StringPacket; -import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import java.util.Random; @@ -80,7 +79,7 @@ public final class MusicPlayer { for (int i = 0; i < CONFIG_IDS.length; i++) { value |= 2 << i; } - player.getPacketDispatch().sendAccessMask(value, 1, 187, 0, CONFIG_IDS.length * 64); + player.getPacketDispatch().sendIfaceSettings(value, 1, 187, 0, CONFIG_IDS.length * 64); if (!unlocked.containsKey(TUTORIAL_MUSIC)) { unlock(TUTORIAL_MUSIC, false); } diff --git a/Server/src/main/java/core/game/node/entity/player/link/request/trade/TradeModule.java b/Server/src/main/java/core/game/node/entity/player/link/request/trade/TradeModule.java index f55e121e6..741047d3f 100644 --- a/Server/src/main/java/core/game/node/entity/player/link/request/trade/TradeModule.java +++ b/Server/src/main/java/core/game/node/entity/player/link/request/trade/TradeModule.java @@ -272,10 +272,10 @@ public final class TradeModule implements RequestModule { player.getInterfaceManager().open(MAIN_INTERFACE); player.getInterfaceManager().openSingleTab(OVERLAY_INTERFACE); player.getInventory().refresh(); - player.getPacketDispatch().sendAccessMask(1278, 30, 335, 0, 27); - player.getPacketDispatch().sendAccessMask(1026, 32, 335, 0, 27); - player.getPacketDispatch().sendAccessMask(1278, 0, 336, 0, 27); - player.getPacketDispatch().sendAccessMask(2360446, 0, 335, 0, 27); + player.getPacketDispatch().sendIfaceSettings(1278, 30, 335, 0, 27); + player.getPacketDispatch().sendIfaceSettings(1026, 32, 335, 0, 27); + player.getPacketDispatch().sendIfaceSettings(1278, 0, 336, 0, 27); + player.getPacketDispatch().sendIfaceSettings(2360446, 0, 335, 0, 27); player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", INVENTORY_PARAMS); player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", TRADE_PARAMS); player.getPacketDispatch().sendRunScript(695, "IviiiIsssssssss", PARTENER_PARAMS); diff --git a/Server/src/main/java/core/game/node/entity/skill/construction/npc/StonemasonPlugin.java b/Server/src/main/java/core/game/node/entity/skill/construction/npc/StonemasonPlugin.java index 9b306ad71..ff62cbf67 100644 --- a/Server/src/main/java/core/game/node/entity/skill/construction/npc/StonemasonPlugin.java +++ b/Server/src/main/java/core/game/node/entity/skill/construction/npc/StonemasonPlugin.java @@ -2,7 +2,6 @@ package core.game.node.entity.skill.construction.npc; import core.cache.def.impl.ItemDefinition; import core.cache.def.impl.NPCDefinition; -import core.game.content.global.shop.Shop; import core.game.interaction.OptionHandler; import core.game.node.Node; import core.game.node.entity.player.Player; @@ -16,11 +15,11 @@ import core.plugin.Plugin; */ @Initializable public class StonemasonPlugin extends OptionHandler { - - /** +/* + *//** * The store that sells supplies. - */ - private static final SupplyStore STORE = new SupplyStore(); + *//* + private static final SupplyStore STORE = new SupplyStore();*/ @Override public Plugin newInstance(Object arg) throws Throwable { @@ -34,21 +33,20 @@ public class StonemasonPlugin extends OptionHandler { switch (option) { case "trade": case "talk-to": - STORE.open(player); break; } return true; } - - /** +/* + *//** * Stonemason's store. * @author Splinter - */ + *//* public static class SupplyStore extends Shop { - /** + *//** * Constructs a new {@Code SupplyStore} {@Code Object} - */ + *//* public SupplyStore() { super("Keldagrim Stonemason", new Item[] { new Item(3420, 1000), new Item(8786, 20), new Item(8784, 20), new Item(8788, 10) }, false); } @@ -73,6 +71,6 @@ public class StonemasonPlugin extends OptionHandler { } return -1; } - } + }*/ } \ No newline at end of file diff --git a/Server/src/main/java/core/game/node/entity/skill/cooking/CookingRewrite.kt b/Server/src/main/java/core/game/node/entity/skill/cooking/CookingRewrite.kt index 94c1413e4..fc6415333 100644 --- a/Server/src/main/java/core/game/node/entity/skill/cooking/CookingRewrite.kt +++ b/Server/src/main/java/core/game/node/entity/skill/cooking/CookingRewrite.kt @@ -17,7 +17,7 @@ import rs09.game.node.entity.skill.cooking.CookingDialogue * @author Ceikry * @author bushtail - added bear meat for sinew making */ -class CookingRewrite : InteractionListener() { +class CookingRewrite : InteractionListener { val RAW_FOODS: IntArray diff --git a/Server/src/main/java/core/game/node/entity/skill/firemaking/FireMakingOptionPlugin.kt b/Server/src/main/java/core/game/node/entity/skill/firemaking/FireMakingOptionPlugin.kt index 35e27354f..e54e9d16c 100644 --- a/Server/src/main/java/core/game/node/entity/skill/firemaking/FireMakingOptionPlugin.kt +++ b/Server/src/main/java/core/game/node/entity/skill/firemaking/FireMakingOptionPlugin.kt @@ -3,7 +3,7 @@ package core.game.node.entity.skill.firemaking import org.rs09.consts.Items import rs09.game.interaction.InteractionListener -class FiremakingListener : InteractionListener() +class FiremakingListener : InteractionListener { val logs = intArrayOf(1511, 1521, 1513, 1515, 1517, 1519, 1521, 2862, 3438, 3440, 3442, 3444, 3446, 3448, 6211, 6213, 6332, 6333, 7404, 7405, 7406, 8934, 9067, 10328, 10329, 10808, 10810, 10812, 11035, 12581, 12583, 3125) diff --git a/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningCreator.java b/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningCreator.java index effcd02ca..1adb6a8c9 100644 --- a/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningCreator.java +++ b/Server/src/main/java/core/game/node/entity/skill/summoning/SummoningCreator.java @@ -60,7 +60,7 @@ public final class SummoningCreator { public static final void configure(final Player player, final boolean pouch) { player.getInterfaceManager().open(pouch ? SUMMONING_COMPONENT : SCROLL_COMPONENT); player.getPacketDispatch().sendRunScript(pouch ? 757 : 765, pouch ? "Iiissssss" : "Iiisssss", pouch ? POUCH_PARAMS : SCROLL_PARAMS); - player.getPacketDispatch().sendAccessMask(pouch ? 190 : 126, 15, pouch ? 669 : 673, 0, 78); + player.getPacketDispatch().sendIfaceSettings(pouch ? 190 : 126, 15, pouch ? 669 : 673, 0, 78); } /** diff --git a/Server/src/main/java/core/net/packet/context/ContainerContext.java b/Server/src/main/java/core/net/packet/context/ContainerContext.java index 0a8d2de95..7b4a3ea9c 100644 --- a/Server/src/main/java/core/net/packet/context/ContainerContext.java +++ b/Server/src/main/java/core/net/packet/context/ContainerContext.java @@ -29,7 +29,7 @@ public final class ContainerContext implements Context { /** * The container type. */ - private final int type; + private final int containerId; /** * The items. @@ -73,12 +73,12 @@ public final class ContainerContext implements Context { * @param player The player. * @param interfaceId The interface id. * @param childId The child id. - * @param type The container type. + * @param containerId The container type. * @param container The container. * @param split If the container should be split. */ - public ContainerContext(Player player, int interfaceId, int childId, int type, Container container, boolean split) { - this(player, interfaceId, childId, type, container.toArray(), container.toArray().length, split); + public ContainerContext(Player player, int interfaceId, int childId, int containerId, Container container, boolean split) { + this(player, interfaceId, childId, containerId, container.toArray(), container.toArray().length, split); } /** @@ -86,12 +86,12 @@ public final class ContainerContext implements Context { * @param player The player. * @param interfaceId The interface id. * @param childId The child id. - * @param type The container type. + * @param containerId The container type. * @param items The items. * @param split If the container should be split. */ - public ContainerContext(Player player, int interfaceId, int childId, int type, Item[] items, boolean split) { - this(player, interfaceId, childId, type, items, items.length, split); + public ContainerContext(Player player, int interfaceId, int childId, int containerId, Item[] items, boolean split) { + this(player, interfaceId, childId, containerId, items, items.length, split); } /** @@ -99,16 +99,16 @@ public final class ContainerContext implements Context { * @param player The player. * @param interfaceId The interface id. * @param childId The child id. - * @param type The container type. + * @param containerId The container containerId. * @param items The items. * @param length The length. * @param split If the container should be split. */ - public ContainerContext(Player player, int interfaceId, int childId, int type, Item[] items, int length, boolean split) { + public ContainerContext(Player player, int interfaceId, int childId, int containerId, Item[] items, int length, boolean split) { this.player = player; this.interfaceId = interfaceId; this.childId = childId; - this.type = type; + this.containerId = containerId; this.items = items; this.length = length; this.split = split; @@ -120,16 +120,16 @@ public final class ContainerContext implements Context { * @param player The player. * @param interfaceId The interface id. * @param childId The child id. - * @param type The container type. + * @param containerId The container containerId. * @param items The items. * @param split If the container should be split. * @param slots The slots to update. */ - public ContainerContext(Player player, int interfaceId, int childId, int type, Item[] items, boolean split, int... slots) { + public ContainerContext(Player player, int interfaceId, int childId, int containerId, Item[] items, boolean split, int... slots) { this.player = player; this.interfaceId = interfaceId; this.childId = childId; - this.type = type; + this.containerId = containerId; this.items = items; this.length = items.length; this.split = split; @@ -153,8 +153,8 @@ public final class ContainerContext implements Context { * Gets the type. * @return The type. */ - public int getType() { - return type; + public int getContainerId() { + return containerId; } /** diff --git a/Server/src/main/java/core/net/packet/in/RunScriptPacketHandler.java b/Server/src/main/java/core/net/packet/in/RunScriptPacketHandler.java index 515c2af4e..307029346 100644 --- a/Server/src/main/java/core/net/packet/in/RunScriptPacketHandler.java +++ b/Server/src/main/java/core/net/packet/in/RunScriptPacketHandler.java @@ -30,6 +30,13 @@ public class RunScriptPacketHandler implements IncomingPacket { } else { value = buffer.getInt(); } + if(value instanceof Integer) + { + if((int) value <= 0){ + player.removeAttribute("runscript"); + return; + } + } try { script.invoke(value); } catch (NumberFormatException nfe){ diff --git a/Server/src/main/java/core/net/packet/out/ContainerPacket.java b/Server/src/main/java/core/net/packet/out/ContainerPacket.java index be4dcd001..9e3b8eda8 100644 --- a/Server/src/main/java/core/net/packet/out/ContainerPacket.java +++ b/Server/src/main/java/core/net/packet/out/ContainerPacket.java @@ -24,7 +24,7 @@ public final class ContainerPacket implements OutgoingPacket { buffer = new IoBuffer(slotBased ? 22 : 105, PacketHeader.SHORT); buffer.putShort(context.getInterfaceId()); buffer.putShort(context.getChildId()); - buffer.putShort(context.getType()); + buffer.putShort(context.getContainerId()); if (slotBased) { for (int slot : context.getSlots()) { buffer.putSmart(slot); diff --git a/Server/src/main/kotlin/api/Commands.kt b/Server/src/main/kotlin/api/Commands.kt new file mode 100644 index 000000000..406350e26 --- /dev/null +++ b/Server/src/main/kotlin/api/Commands.kt @@ -0,0 +1,49 @@ +package api + +import core.game.node.entity.player.Player +import rs09.game.system.command.Command +import rs09.game.system.command.CommandMapping +import rs09.game.system.command.Privilege +import rs09.tools.stringtools.colorize + +/** + * An interface for writing content that allows the class to define commands. + * + * Includes methods [reject] and [notify] for notifying the player of a command rejection or some output text respectively. + * + * Includes the method [define] to define individual commands + * + * Commands should ideally be defined in the required [defineCommands] method. + */ +interface Commands : ContentInterface { + /** + * Glorified player.sendMessage with red text coloring. Please use this + * rather than just player.sendMessage for anything that involves informing the player + * of proper usage or invalid syntax. Throws an IllegalStateException and ends command execution immediately. + */ + fun reject(player: Player, vararg message: String){ + for(msg in message) { + player.sendMessage(colorize("-->%R$msg")) + } + throw IllegalStateException() + } + + /** + * Glorified player.sendMessage with black text coloring and an arrow. Use this when you need to + * notify/inform a player of some information from within the command without ending execution. + */ + fun notify(player: Player, message: String){ + player.sendMessage(colorize("-->$message")) + } + + /** + * Used to define commands. define("name",(optional) privilege override){ handle } + * @param name the name of the command. Example: ::example would be just "example" + * @param privilege the rights level needed to execute the command. Options are [Privilege.STANDARD], [Privilege.MODERATOR], [Privilege.ADMIN]. Defaults to [Privilege.STANDARD] + */ + fun define(name: String, privilege: Privilege = Privilege.STANDARD, handle: (Player, Array) -> Unit){ + CommandMapping.register(Command(name, privilege, handle)) + } + + fun defineCommands() +} \ No newline at end of file diff --git a/Server/src/main/kotlin/api/ContentAPI.kt b/Server/src/main/kotlin/api/ContentAPI.kt index fbb2d9e66..7de033bd6 100644 --- a/Server/src/main/kotlin/api/ContentAPI.kt +++ b/Server/src/main/kotlin/api/ContentAPI.kt @@ -1,6 +1,7 @@ package api import Cutscene +import com.moandjiezana.toml.Toml import core.cache.def.impl.ItemDefinition import core.cache.def.impl.SceneryDefinition import core.game.component.Component @@ -45,6 +46,7 @@ import rs09.game.content.global.GlobalKillCounter import rs09.game.interaction.InteractionListeners import rs09.game.system.SystemLogger import rs09.game.system.config.ItemConfigParser +import rs09.game.system.config.ServerConfigParser import rs09.game.world.GameWorld import rs09.game.world.GameWorld.Pulser import rs09.game.world.repository.Repository @@ -714,6 +716,15 @@ fun findLocalNPCs(entity: Entity, ids: IntArray, distance: Int): List{ return RegionManager.getLocalNpcs(entity, distance).filter { it.id in ids }.toList() } +/** + * @param regionId the ID of the region + * @return a [ZoneBorders] encapsulating the entire region indicated by the provided regionId + */ +fun getRegionBorders(regionId: Int) : ZoneBorders +{ + return ZoneBorders.forRegion(regionId) +} + /** * Gets the value of an attribute key from the Entity's attributes store * @param entity the entity to get the attribute from @@ -1447,4 +1458,9 @@ fun Player.getCutscene(): Cutscene? { fun Player.getCutsceneStage(): Int { return getAttribute(this, Cutscene.ATTRIBUTE_CUTSCENE_STAGE, 0) +} + +fun getServerConfig() : Toml +{ + return ServerConfigParser.tomlData ?: Toml() } \ No newline at end of file diff --git a/Server/src/main/kotlin/api/ContentInterface.kt b/Server/src/main/kotlin/api/ContentInterface.kt new file mode 100644 index 000000000..c8bdc0ca9 --- /dev/null +++ b/Server/src/main/kotlin/api/ContentInterface.kt @@ -0,0 +1,7 @@ +package api + +interface ContentInterface { + /** + * A dummy/shell interface that allows us to more easily load content via class scanning + */ +} \ No newline at end of file diff --git a/Server/src/main/kotlin/api/IfaceSettingsBuilder.kt b/Server/src/main/kotlin/api/IfaceSettingsBuilder.kt new file mode 100644 index 000000000..ff2084f55 --- /dev/null +++ b/Server/src/main/kotlin/api/IfaceSettingsBuilder.kt @@ -0,0 +1,151 @@ +package api + +/** + * Used to generate interface settings hashes. + * Deprecates [core.game.container.access.BitregisterAssembler] + * @author Ceikry + */ +class IfaceSettingsBuilder { + /** + * Contains the value which should be sent in access mask packet. + */ + private var value = 0 + + /** + * Sets right click option settings. If specified option is not allowed, it + * might not appear in the context menu, and if it does, it will throw an error when clicked. + * @param optionId The option index. + */ + fun enableOption(optionId: Int): IfaceSettingsBuilder { + require(!(optionId < 0 || optionId > 9)) { "Option index must be 0-9." } + value = value or (0x1 shl optionId + 1) + return this + } + + fun enableOptions(vararg ids: Int): IfaceSettingsBuilder { + for (i in ids.indices) { + enableOption(ids[i]) + } + return this + } + + fun enableOptions(ids: IntRange): IfaceSettingsBuilder { + for (i in ids.start..ids.endInclusive) { + enableOption(i) + } + return this + } + + fun enableAllOptions(): IfaceSettingsBuilder { + for (i in 0..9) { + enableOption(i) + } + return this + } + + fun enableOptions(vararg options: String?): IfaceSettingsBuilder { + for (i in options.indices) { + enableOption(i) + } + return this + } + + /** + * Sets use on option settings. If nothing is allowed then 'use' option will + * not appear in right click menu. + */ + fun setUseOnSettings( + groundItems: Boolean, + npcs: Boolean, + objects: Boolean, + otherPlayer: Boolean, + selfPlayer: Boolean, + component: Boolean + ): IfaceSettingsBuilder { + var useFlag = 0 + if (groundItems) { + useFlag = useFlag or 0x1 + } + if (npcs) { + useFlag = useFlag or 0x2 + } + if (objects) { + useFlag = useFlag or 0x4 + } + if (otherPlayer) { + useFlag = useFlag or 0x8 + } + if (selfPlayer) { + useFlag = useFlag or 0x10 + } + if (component) { + useFlag = useFlag or 0x20 + } + value = value or (useFlag shl 11) + return this + } + + /** + * Sets interface events depth. For example, we have inventory interface + * which is opened on gameframe interface (548) If depth is 1, then the + * clicks in inventory will also invoke click event handler scripts on + * gameframe interface. Setting depth to 2 also allows dragged items to + * leave the bounds of their container, useful for things such as bank tabs. + * @param depth The depth value. + */ + fun setInterfaceEventsDepth(depth: Int): IfaceSettingsBuilder { + require(!(depth < 0 || depth > 7)) { "depth must be 0-7." } + value = value and (0x7 shl 18).inv() + value = value or (depth shl 18) + return this + } + + /** + * Allows items in this interface container to be switched around + * @return this builder + */ + fun enableSlotSwitch(): IfaceSettingsBuilder { + value = value or (1 shl 21) + return this + } + + /** + * Allows items in this interface container to have a "Use" option + * @return this builder + */ + fun enableUseOption(): IfaceSettingsBuilder { + value = value or (1 shl 17) + return this + } + + fun enableExamine(): IfaceSettingsBuilder { + value = value or (1 shl 9) + return this + } + + /** + * Allows this component to have items used on it + * @return this builder + */ + fun enableUseOnSelf(): IfaceSettingsBuilder { + value = value or (1 shl 22) + return this + } + + /** + * Allows this component to switch item slots with a slot that contains a null (empty slot) + * @return this builder + */ + fun enableNullSlotSwitch(): IfaceSettingsBuilder { + value = value or (1 shl 23) + return this + } + + /** + * Gets the current value. + * @return The value. + */ + fun build(): Int { + return value + } +} \ No newline at end of file diff --git a/Server/src/main/kotlin/api/LoginListener.kt b/Server/src/main/kotlin/api/LoginListener.kt index 96a900d18..f967353be 100644 --- a/Server/src/main/kotlin/api/LoginListener.kt +++ b/Server/src/main/kotlin/api/LoginListener.kt @@ -2,7 +2,12 @@ package api import core.game.node.entity.player.Player -interface LoginListener { +/** + * An interface for writing content that allows the class to execute some code when a player logs in. + * + * Login listeners are called *before* [PersistPlayer] data is parsed. + */ +interface LoginListener : ContentInterface { /** * NOTE: This should NOT reference any non-static class-local variables. * If you need to access a player's specific instance, use an attribute. diff --git a/Server/src/main/kotlin/api/LogoutListener.kt b/Server/src/main/kotlin/api/LogoutListener.kt index 443d4c5e6..8b7456511 100644 --- a/Server/src/main/kotlin/api/LogoutListener.kt +++ b/Server/src/main/kotlin/api/LogoutListener.kt @@ -2,7 +2,12 @@ package api import core.game.node.entity.player.Player -interface LogoutListener { +/** + * An interface for writing content that allows code to be executed by the class when a player logs out. + * + * Logout listeners are called *before* [PersistPlayer] data is saved. + */ +interface LogoutListener : ContentInterface { /** * NOTE: This should NOT reference any non-static class-local variables. * If you need to access a player's specific instance, use an attribute. diff --git a/Server/src/main/kotlin/api/MapArea.kt b/Server/src/main/kotlin/api/MapArea.kt new file mode 100644 index 000000000..1888c1fc1 --- /dev/null +++ b/Server/src/main/kotlin/api/MapArea.kt @@ -0,0 +1,18 @@ +package api + +import core.game.node.entity.Entity +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction + +/** + * Interface that allows a class to define a map area. + * Optionally-overridable methods include [getRestrictions], [areaEnter], [areaLeave] and [entityStep] + */ +interface MapArea { + fun defineAreaBorders() : Array + fun getRestrictions() : Array {return arrayOf()} + fun areaEnter(entity: Entity) {} + fun areaLeave(entity: Entity, logout: Boolean) {} + fun entityStep(entity: Entity, location: Location, lastLocation: Location) {} +} \ No newline at end of file diff --git a/Server/src/main/kotlin/api/PersistPlayer.kt b/Server/src/main/kotlin/api/PersistPlayer.kt index d09416706..dc9588416 100644 --- a/Server/src/main/kotlin/api/PersistPlayer.kt +++ b/Server/src/main/kotlin/api/PersistPlayer.kt @@ -3,7 +3,14 @@ package api import core.game.node.entity.player.Player import org.json.simple.JSONObject -interface PersistPlayer { +/** + * An interface for writing content that allows data to be saved and loaded from player saves. + * + * Parsing is called *after* any [LoginListener] is executed. + * + * Saving is called *after* any [LogoutListener] is executed. + */ +interface PersistPlayer : ContentInterface { /** * NOTE: This should NOT reference nonstatic class-local variables. * You need to fetch a player's specific instance of the data and save from that. diff --git a/Server/src/main/kotlin/api/PersistWorld.kt b/Server/src/main/kotlin/api/PersistWorld.kt deleted file mode 100644 index cb499402a..000000000 --- a/Server/src/main/kotlin/api/PersistWorld.kt +++ /dev/null @@ -1,6 +0,0 @@ -package api - -interface PersistWorld { - fun saveWorld() - fun parseWorld() -} \ No newline at end of file diff --git a/Server/src/main/kotlin/api/ShutdownListener.kt b/Server/src/main/kotlin/api/ShutdownListener.kt index cc97a06fa..cbabc2c23 100644 --- a/Server/src/main/kotlin/api/ShutdownListener.kt +++ b/Server/src/main/kotlin/api/ShutdownListener.kt @@ -2,7 +2,10 @@ package api import rs09.game.system.SystemLogger -interface ShutdownListener { +/** + * An interface for writing content that allows the class to execute code as the server is shutting down + */ +interface ShutdownListener : ContentInterface { /** * NOTE: This should NOT reference nonstatic class-local variables. */ diff --git a/Server/src/main/kotlin/api/StartupListener.kt b/Server/src/main/kotlin/api/StartupListener.kt index 2240a8895..4f2fe9f9f 100644 --- a/Server/src/main/kotlin/api/StartupListener.kt +++ b/Server/src/main/kotlin/api/StartupListener.kt @@ -2,7 +2,10 @@ package api import rs09.game.system.SystemLogger -interface StartupListener { +/** + * An interface for writing content that allows the class to execute code when the server is started. + */ +interface StartupListener : ContentInterface { /** * NOTE: This should NOT reference nonstatic class-local variables. */ diff --git a/Server/src/main/kotlin/api/TickListener.kt b/Server/src/main/kotlin/api/TickListener.kt index c0d9cf4b1..debf63b37 100644 --- a/Server/src/main/kotlin/api/TickListener.kt +++ b/Server/src/main/kotlin/api/TickListener.kt @@ -1,6 +1,9 @@ package api -interface TickListener { +/** + * An interface for writing content that allows the class to be updated each tick. + */ +interface TickListener : ContentInterface { /** * NOTE: This should NOT reference nonstatic class-local variables. * TickListeners are generally for NON-player, WORLD tick events. diff --git a/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/ShootingStarBot.kt b/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/ShootingStarBot.kt index cd02989d7..187006e01 100644 --- a/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/ShootingStarBot.kt +++ b/Server/src/main/kotlin/rs09/game/ai/general/scriptrepository/ShootingStarBot.kt @@ -6,17 +6,14 @@ import core.game.world.map.Location import core.tools.RandomFunction import org.rs09.consts.Items import rs09.game.ai.general.GeneralBotCreator -import rs09.game.ai.general.ScriptAPI -import rs09.game.content.global.worldevents.WorldEvents -import rs09.game.content.global.worldevents.shootingstar.ShootingStarEvent -import rs09.game.interaction.InteractionListener.Companion.SCENERY +import rs09.game.content.global.worldevents.shootingstar.ShootingStarPlugin +import rs09.game.interaction.InteractionListener import rs09.game.interaction.InteractionListeners -import kotlin.concurrent.timer class ShootingStarBot : Script() { private var state = State.FULL_IDLE private var timerCountdown = 0 - val star = (WorldEvents.get("shooting-stars") as? ShootingStarEvent)!!.star + val star = ShootingStarPlugin.getStar() override fun tick() { bot.fullRestore() @@ -36,7 +33,7 @@ class ShootingStarBot : Script() { } State.MINING -> { - InteractionListeners.run(star.starObject.id, SCENERY, "mine", bot, star.starObject) + InteractionListeners.run(star.starObject.id, InteractionListener.SCENERY, "mine", bot, star.starObject) } State.TELEPORT_BACK -> { diff --git a/Server/src/main/kotlin/rs09/game/content/activity/allfiredup/AFUBeaconHandler.kt b/Server/src/main/kotlin/rs09/game/content/activity/allfiredup/AFUBeaconHandler.kt index 4f9b76d29..c682c6008 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/allfiredup/AFUBeaconHandler.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/allfiredup/AFUBeaconHandler.kt @@ -19,7 +19,7 @@ private val LIGHT_ANIM = Animation(7307) * Handles interactions for beacons * @author Ceikry */ -class AFUBeaconListeners : InteractionListener(){ +class AFUBeaconListeners : InteractionListener{ override fun defineListeners() { on(SCENERY,"add-logs","light"){ player, node -> diff --git a/Server/src/main/kotlin/rs09/game/content/activity/allfiredup/AFURepairClimbHandler.kt b/Server/src/main/kotlin/rs09/game/content/activity/allfiredup/AFURepairClimbHandler.kt index 5e288dbef..b0a5c8710 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/allfiredup/AFURepairClimbHandler.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/allfiredup/AFURepairClimbHandler.kt @@ -16,7 +16,7 @@ import java.util.* * Handles repairing and climbing of the 3 beacon shortcuts needed to access them * @author Ceikry */ -class AFURepairClimbHandler : InteractionListener() { +class AFURepairClimbHandler : InteractionListener { val repairIDs = intArrayOf(38480,38470,38494) val climbIDs = intArrayOf(38469,38471,38486,38481,38469) diff --git a/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/BlastFurnaceInterfaceListener.kt b/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/BlastFurnaceInterfaceListener.kt index 8d716a34e..7a059ac32 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/BlastFurnaceInterfaceListener.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/BlastFurnaceInterfaceListener.kt @@ -11,9 +11,9 @@ import rs09.game.interaction.InterfaceListener * @author definitely phil who didn't get help from ceikry at all haha :) * @version 69.0 */ -class BlastFurnaceInterfaceListener : InterfaceListener() { +class BlastFurnaceInterfaceListener : InterfaceListener { - override fun defineListeners() { + override fun defineInterfaceListeners() { on(Components.BLAST_FURNACE_BAR_STOCK_28){ player, _, _, buttonID, _, _ -> val bar = BFBars.forId(buttonID) ?: return@on false diff --git a/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/BlastFurnaceListeners.kt b/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/BlastFurnaceListeners.kt index 870fa7e33..7d63e9bb7 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/BlastFurnaceListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/BlastFurnaceListeners.kt @@ -18,7 +18,7 @@ import rs09.game.node.entity.npc.other.BlastFurnaceOre * That lives in OrdanDialogue.kt * @author phil lips*/ -class BlastFurnaceListeners : InteractionListener() { +class BlastFurnaceListeners : InteractionListener { val disLoc = getScenery(1941, 4963, 0) val brokenPotPipe = 9117 diff --git a/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/PhunnyGaugeTempInterfaceListener.kt b/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/PhunnyGaugeTempInterfaceListener.kt index 620e28b72..e2d36a9a9 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/PhunnyGaugeTempInterfaceListener.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/blastfurnace/PhunnyGaugeTempInterfaceListener.kt @@ -7,9 +7,9 @@ import rs09.game.interaction.InterfaceListener * Only updates the gauge if people are actually looking at it * @author phil lips*/ -class PhunnyGaugeTempInterfaceListener : InterfaceListener(){ +class PhunnyGaugeTempInterfaceListener : InterfaceListener { - override fun defineListeners() { + override fun defineInterfaceListeners() { onOpen(30) {player, component -> BlastFurnace.gaugeViewList.add(player) return@onOpen true diff --git a/Server/src/main/kotlin/rs09/game/content/activity/fishingtrawler/FishingTrawlerInteractionHandler.kt b/Server/src/main/kotlin/rs09/game/content/activity/fishingtrawler/FishingTrawlerInteractionHandler.kt index bd28bd28b..a5ed02643 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/fishingtrawler/FishingTrawlerInteractionHandler.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/fishingtrawler/FishingTrawlerInteractionHandler.kt @@ -22,7 +22,7 @@ import kotlin.math.ceil * Option handler for fishing trawler * @author Ceikry */ -class FishingTrawlerInteractionHandler : InteractionListener() { +class FishingTrawlerInteractionHandler : InteractionListener { val ENTRANCE_PLANK = 2178 val EXIT_PLANK = 2179 val HOLE = 2167 diff --git a/Server/src/main/kotlin/rs09/game/content/activity/guild/crafting/CraftingGuildListeners.kt b/Server/src/main/kotlin/rs09/game/content/activity/guild/crafting/CraftingGuildListeners.kt index bae2d4250..a14364811 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/guild/crafting/CraftingGuildListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/guild/crafting/CraftingGuildListeners.kt @@ -13,7 +13,7 @@ import rs09.game.interaction.InteractionListener * @author bushtail */ -class CraftingGuildListeners : InteractionListener() { +class CraftingGuildListeners : InteractionListener { private val GUILD_DOOR = Scenery.GUILD_DOOR_2647 private val APRON = Items.BROWN_APRON_1757 private val CAPE = Items.CRAFTING_CAPE_9780 diff --git a/Server/src/main/kotlin/rs09/game/content/activity/mta/MTAListeners.kt b/Server/src/main/kotlin/rs09/game/content/activity/mta/MTAListeners.kt index 54c9b13b2..e478e6f2b 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/mta/MTAListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/mta/MTAListeners.kt @@ -11,7 +11,7 @@ import rs09.game.interaction.InteractionListener import rs09.game.node.entity.skill.magic.SpellListener import rs09.game.node.entity.skill.magic.spellconsts.Modern -class MTAListeners : InteractionListener() { +class MTAListeners : InteractionListener { override fun defineListeners() { on(NPCs.MAZE_GUARDIAN_3102,NPC,"talk-to"){player,node -> player.dialogueInterpreter.open(node.id, node) diff --git a/Server/src/main/java/core/game/interaction/item/PharoahSceptre.kt b/Server/src/main/kotlin/rs09/game/content/activity/pyramidplunder/PharaohSceptre.kt similarity index 98% rename from Server/src/main/java/core/game/interaction/item/PharoahSceptre.kt rename to Server/src/main/kotlin/rs09/game/content/activity/pyramidplunder/PharaohSceptre.kt index eb341201e..6746d2cd8 100644 --- a/Server/src/main/java/core/game/interaction/item/PharoahSceptre.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/pyramidplunder/PharaohSceptre.kt @@ -1,4 +1,4 @@ -package core.game.interaction.item +package rs09.game.content.activity.pyramidplunder import api.EquipmentSlot import api.openDialogue @@ -21,7 +21,7 @@ import rs09.tools.END_DIALOGUE * Adds functionality to the pharoah's scepter * @author ceik */ -class PharoahSceptre : InteractionListener() { +class PharaohSceptre : InteractionListener { override fun defineListeners() { val SCEPTRES = intArrayOf(Items.PHARAOHS_SCEPTRE_9044, Items.PHARAOHS_SCEPTRE_9046, Items.PHARAOHS_SCEPTRE_9048, Items.PHARAOHS_SCEPTRE_9050) diff --git a/Server/src/main/kotlin/rs09/game/content/activity/pyramidplunder/PyramidPlunderMinigame.kt b/Server/src/main/kotlin/rs09/game/content/activity/pyramidplunder/PyramidPlunderMinigame.kt index 703a3794a..d958e3274 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/pyramidplunder/PyramidPlunderMinigame.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/pyramidplunder/PyramidPlunderMinigame.kt @@ -17,11 +17,12 @@ import org.rs09.consts.Scenery import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InteractionListener + /** * The "controller" class for pyramid plunder. Handles per-tick updates, logout hooks, and defines interaction listeners for the minigame. * @author Ceikry */ -class PyramidPlunderMinigame : InteractionListener(), TickListener, LogoutListener { +class PyramidPlunderMinigame : InteractionListener, TickListener, LogoutListener { override fun tick() { val playersToExpel = PlunderUtils.decrementTimeRemaining() playersToExpel.forEach {player -> PlunderUtils.expel(player, false) } diff --git a/Server/src/main/kotlin/rs09/game/content/activity/vinesweeper/Vinesweeper.kt b/Server/src/main/kotlin/rs09/game/content/activity/vinesweeper/Vinesweeper.kt index e9cf73158..7db2ed02c 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/vinesweeper/Vinesweeper.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/vinesweeper/Vinesweeper.kt @@ -1,3 +1,17 @@ +package rs09.game.content.activity.vinesweeper + +import BlinkinDialogue +import WinkinDialogue +import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.DEAD_PLANT_OBJ +import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.FARMERS +import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.FARMER_CLEAR_RADIUS +import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.HOLES +import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.NUMBERS +import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.RABBIT +import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.SEED_LOCS +import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.populateSeeds +import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.scheduleNPCs +import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.sendUpdatedPoints import api.* import core.game.component.Component import core.game.node.entity.Entity @@ -13,164 +27,52 @@ import core.game.node.scenery.SceneryBuilder import core.game.system.task.Pulse import core.game.world.map.Location import core.game.world.map.RegionManager -import core.game.world.map.zone.MapZone import core.game.world.map.zone.ZoneBorders -import core.game.world.map.zone.ZoneBuilder import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; import core.plugin.Initializable import core.tools.RandomFunction +import org.rs09.consts.Components import org.rs09.consts.Items -import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InteractionListener import rs09.game.interaction.InterfaceListener import rs09.game.world.GameWorld; -val AVACH_NIMPORTO_LOC = Location.create(1637, 4709) -val PORTAL = 29534 -val SIGNS = intArrayOf(29461, 29462, 29463, 29464) -val HOLES = intArrayOf(29476, 29477, 29478) -val NUMBERS = intArrayOf(29447, 29448, 29449, 29450, 29451, 29452, 29453, 29454, 29455) -val DEAD_PLANT_OBJ = 29456 -val FLAG_OBJ = 29457 +class Vinesweeper : InteractionListener, InterfaceListener, MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(getRegionBorders(6473)) + } -val TUTORIAL = 685 - -val INSTRUCTION_SIGNS = hashMapOf( - 29463 to 684, - 29464 to 687, - 29462 to 688, - 29461 to 690 - ) - -val RABBIT = 7125 -val FARMERS = intArrayOf(7128, 7129, 7130) -val FARMER_BLINKIN = 7131 -val MRS_WINKIN = 7132 - -val MAX_SEEDS = 300 -val FARMER_CLEAR_RADIUS = 3 -val VINESWEEPER_BORDERS = ZoneBorders(1600,4672,1663,4735) - -fun sendUpdatedPoints(player: Player) { - val points = player.getAttribute("vinesweeper:points", 0); - player.varpManager.get(1195).setVarbit(6, points).send(player) -} - -data class SeedDestination(val player: Player, val loc: Location, val alive: Boolean) { - override fun equals(other: Any?): Boolean { - if(other is SeedDestination) { - return loc.equals(other.loc) - } else { - return false + override fun areaEnter(entity: Entity) { + if(entity is Player) + { + openOverlay(entity, Components.RABBIT_OVERLAY_689) + sendUpdatedPoints(entity) } } -} -var SEED_LOCS: HashSet = HashSet() -fun isSeed(loc: Location): Boolean { - val scenery = getScenery(loc) - return scenery != null && SEED_LOCS.contains(scenery.location) -} - -fun populateSeeds() { - while(SEED_LOCS.size < MAX_SEEDS) { - val loc = VINESWEEPER_BORDERS.getRandomLoc() - val scenery = getScenery(loc) - if(scenery != null && HOLES.contains(scenery.id)) { - SEED_LOCS.add(loc) - } - } -} - -fun isHole(loc: Location): Boolean { - val scenery = getScenery(loc) - return scenery != null && HOLES.contains(scenery.id) -} - -fun scheduleNPCs(player: Player, loc: Location, alive: Boolean, rabbit: Boolean) { - val dest = SeedDestination(player, loc, alive) - val ids = if(rabbit) { intArrayOf(RABBIT, *FARMERS) } else { FARMERS } - for(npc in findLocalNPCs(player, ids, 30)) { - if(npc is VinesweeperNPC) { - npc.seedDestinations.add(dest) - npc.resetWalk() - } - } -} - -object VinesweeperTeleport { - @JvmStatic - fun teleport(npc: NPC, player: Player) { - npc.animate(Animation(437)) - npc.faceTemporary(player, 1) - npc.graphics(Graphics(108)) - player.lock() - player.audioManager.send(125) - Projectile.create(npc, player, 109).send() - npc.sendChat("Avach nimporto!") - GameWorld.Pulser.submit(object : Pulse(1) { - var counter = 0 - override fun pulse(): Boolean { - when (counter++) { - 2 -> { - player.savedData.globalData.essenceTeleporter = npc.id - player.setAttribute("/save:vinesweeper:return-tele:x", npc.location.x) - player.setAttribute("/save:vinesweeper:return-tele:y", npc.location.y) - player.properties.teleportLocation = AVACH_NIMPORTO_LOC - } - 3 -> { - player.graphics(Graphics(110)) - player.unlock() - return true - } + override fun areaLeave(entity: Entity, logout: Boolean) { + if(entity is Player) { + entity.interfaceManager.closeOverlay() + if(!logout) { + entity.sendMessage("Winkin's Farm thanks you for your visit.") + entity.sendMessage("Leftover ogleroots and flags have been returned to the establishment.") + entity.sendMessage("You have been reimbursed at a rate of 10gp per ogleroot and the flags have been collected.") + val flags = entity.inventory.getAmount(Item(Items.FLAG_12625)) + if(flags > 0) { + entity.setAttribute("/save:vinesweeper:stored-flags", flags) + entity.inventory.remove(Item(Items.FLAG_12625, flags)) } - return false - } - }) - } -} - -class VinesweeperListener : InteractionListener() { - fun dig(player: Player, loc: Location) { - if(isSeed(loc)) { - val oldPoints = player.getAttribute("vinesweeper:points", 0) - player.setAttribute("/save:vinesweeper:points", Math.max(oldPoints-10, 0)) - sendUpdatedPoints(player) - player.sendMessage("Oh dear! It looks like you dug up a potato seed by mistake."); - scheduleNPCs(player, loc, false, false) - val scenery = getScenery(loc) - if(scenery != null) { - SceneryBuilder.replace(scenery, scenery.transform(DEAD_PLANT_OBJ)) - } - } else { - player.incrementAttribute("/save:vinesweeper:points", 1) - sendUpdatedPoints(player) - var count = 0 - for(dx in -1..1) { - for(dy in -1..1) { - if(isSeed(loc.transform(dx, dy, 0))) { - count += 1 - } - } - } - val scenery = getScenery(loc) - if(scenery != null) { - SceneryBuilder.replace(scenery, scenery.transform(NUMBERS[count])) - } - if(count == 0) { - for(dx in -1..1) { - for(dy in -1..1) { - val newLoc = loc.transform(dx, dy, 0) - if(isHole(newLoc)) - dig(player, newLoc) - } + val roots = entity.inventory.getAmount(Item(Items.OGLEROOT_12624)) + if(roots > 0) { + entity.inventory.remove(Item(Items.OGLEROOT_12624, roots)) + entity.inventory.add(Item(Items.COINS_995, roots * 10)) } } } } + override fun defineListeners() { - ZoneBuilder.configure(VinesweeperZone()) populateSeeds() on(PORTAL, SCENERY, "enter") { player, _ -> val x = player.getAttribute("vinesweeper:return-tele:x", 3052) @@ -227,7 +129,7 @@ class VinesweeperListener : InteractionListener() { return@on true } on(MRS_WINKIN, NPC, "talk-to") { player, npc -> - openDialogue(player, WinkinDialogue(), npc) + openDialogue(player, WinkinDialogue(), npc) return@on true } on(MRS_WINKIN, NPC, "trade") { player, _ -> @@ -264,7 +166,7 @@ class VinesweeperListener : InteractionListener() { } on(FARMER_BLINKIN, NPC, "talk-to") { player, npc -> //player.interfaceManager.open(Component(TUTORIAL)) - openDialogue(player, BlinkinDialogue(), npc) + openDialogue(player, BlinkinDialogue(), npc) return@on true } on(FARMER_BLINKIN, NPC, "buy-flags") { player, npc -> @@ -280,240 +182,8 @@ class VinesweeperListener : InteractionListener() { return@on true } } -} -@Initializable -class VinesweeperNPC : AbstractNPC { - fun compareDistance(a: SeedDestination, b: SeedDestination): Int { - val da = a.loc.getDistance(location).toInt() - val db = b.loc.getDistance(location).toInt() - return db - da - } - var seedDestinations: ArrayList = ArrayList(); - constructor() : super(RABBIT, null, true) {} - private constructor(id: Int, location: Location) : super(id, location) {} - override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { - return VinesweeperNPC(id, location) - } - - init { - walkRadius = 22 - } - - override fun getIds(): IntArray { - return intArrayOf(RABBIT, *FARMERS) - } - - override fun handleTickActions() { - val dest = seedDestinations.find { sd -> sd.loc == location } - if(dest != null) { - for(npc in RegionManager.getRegionPlane(location).npcs) { - if(npc is VinesweeperNPC) { - npc.seedDestinations.remove(dest) - npc.resetWalk() - } - } - val scenery = getScenery(dest.loc) - if(scenery != null) { - if(id == RABBIT) { - val replacement = if(SEED_LOCS.contains(dest.loc)) { DEAD_PLANT_OBJ } else { HOLES[0] } - SceneryBuilder.replace(scenery, scenery.transform(replacement)) - scheduleNPCs(dest.player, dest.loc, false, false) - } else { - if(dest.alive) { - handleFarmerFlag(scenery, dest) - } else { - sendChat("Hmm. Looks like there's a plant here.") - lock(3) - GameWorld.Pulser.submit(object : Pulse(3) { - override fun pulse(): Boolean { - sendChat("Gracious me! This one's dead") - SceneryBuilder.replace(scenery, scenery.transform(HOLES[0])) - farmerClear(dest) - return true - } - }) - } - } - } - seedDestinations.remove(dest) - } - super.handleTickActions() - } - - override fun getMovementDestination(): Location? { - if(seedDestinations.size > 0) { - seedDestinations.sortBy { a -> a.loc.getDistance(location).toInt() } - return seedDestinations.first().loc - } else { - return super.getMovementDestination() - } - } - - fun handleFarmerFlag(scenery: Scenery, dest: SeedDestination) { - sendChat("Ah, another flag to clear. Let's see what's there.") - lock(3) - animate(Animation(451)) - if(SEED_LOCS.contains(dest.loc)) { - val npc = this - GameWorld.Pulser.submit(object : Pulse(3) { - override fun pulse(): Boolean { - sendChat("Ah! A seed. Points for everyone near me!") - val level = dest.player.skills.getStaticLevel(Skills.FARMING) - val points = RandomFunction.random(level, 4 * level) - dest.player.incrementAttribute("/save:vinesweeper:points", points) - dest.player.inventory.add(Item(Items.FLAG_12625, 1)) - sendUpdatedPoints(dest.player) - for(neighbor in RegionManager.getLocalPlayers(npc)) { - if(neighbor != dest.player) { - neighbor.incrementAttribute("/save:vinesweeper:points", points / 2) - sendUpdatedPoints(neighbor) - } - } - SceneryBuilder.replace(scenery, scenery.transform(HOLES[0])) - farmerClear(dest) - return true - } - }) - } else { - SceneryBuilder.replace(scenery, scenery.transform(HOLES[0])) - var i = 0 - val lines = arrayOf("Hmm, no seeds planted here, I'm afraid.", "I'll have to keep this 'ere flag. Sorry.") - GameWorld.Pulser.submit(object : Pulse(3) { - override fun pulse(): Boolean { - sendChat(lines[i++]) - return i >= lines.size - } - }) - } - } - fun farmerClear(dest: SeedDestination) { - for(dx in -FARMER_CLEAR_RADIUS..FARMER_CLEAR_RADIUS) { - for(dy in -FARMER_CLEAR_RADIUS..FARMER_CLEAR_RADIUS) { - val toClear = getScenery(dest.loc.transform(dx, dy, 0)) - if(toClear != null && intArrayOf(DEAD_PLANT_OBJ, *NUMBERS).contains(toClear.id)) { - SceneryBuilder.replace(toClear, toClear.transform(HOLES[0])) - } - } - } - SEED_LOCS.remove(dest.loc) - populateSeeds() - } -} - -class VinesweeperZone : MapZone("Vinesweeper", true) { - override fun enter(e: Entity): Boolean { - if(e is Player) { - e.interfaceManager.openOverlay(Component(689)) - sendUpdatedPoints(e) - } - - return super.enter(e) - } - - override fun leave(e: Entity, logout: Boolean): Boolean { - if(e is Player) { - e.interfaceManager.closeOverlay() - if(!logout) { - e.sendMessage("Winkin's Farm thanks you for your visit.") - e.sendMessage("Leftover ogleroots and flags have been returned to the establishment.") - e.sendMessage("You have been reimbursed at a rate of 10gp per ogleroot and the flags have been collected.") - val flags = e.inventory.getAmount(Item(Items.FLAG_12625)) - if(flags > 0) { - e.setAttribute("/save:vinesweeper:stored-flags", flags) - e.inventory.remove(Item(Items.FLAG_12625, flags)) - } - val roots = e.inventory.getAmount(Item(Items.OGLEROOT_12624)) - if(roots > 0) { - e.inventory.remove(Item(Items.OGLEROOT_12624, roots)) - e.inventory.add(Item(Items.COINS_995, roots * 10)) - } - } - } - - return super.leave(e, logout) - } - - override fun configure() { - super.registerRegion(6473) - } -} - -class VinesweeperRewards : InterfaceListener() { - val IFACE = 686 - val TRADE_FOR_XP_BUTTON = 53 - val XP_CONFIRM = 72 - val XP_DENY = 73 - - enum class Opcode(val value: Int) { - VALUE(155), - BUY1(196), - BUY5(124), - BUY10(199), - BUYX(234), - } - - data class Reward(val itemID: Int, val points: Int) {} - - val REWARDS = hashMapOf( - 18 to Reward(Items.TOMATO_SEED_5322, 10), - 19 to Reward(Items.SWEETCORN_SEED_5320, 150), - 20 to Reward(Items.STRAWBERRY_SEED_5323, 165), - 21 to Reward(Items.WATERMELON_SEED_5321, 680), - 22 to Reward(Items.GUAM_SEED_5291, 10), - 23 to Reward(Items.MARRENTILL_SEED_5292, 10), - 24 to Reward(Items.RANARR_SEED_5295, 4000), - 25 to Reward(Items.KWUARM_SEED_5299, 1000), - 26 to Reward(Items.TARROMIN_SEED_5293, 10), - 27 to Reward(Items.NASTURTIUM_SEED_5098, 10), - - 28 to Reward(Items.WOAD_SEED_5099, 30), - 29 to Reward(Items.LIMPWURT_SEED_5100, 70), - 30 to Reward(Items.ASGARNIAN_SEED_5308, 5), - 31 to Reward(Items.KRANDORIAN_SEED_5310, 20), - 32 to Reward(Items.REDBERRY_SEED_5101, 5), - 33 to Reward(Items.CADAVABERRY_SEED_5102, 5), - 34 to Reward(Items.DWELLBERRY_SEED_5103, 5), - 35 to Reward(Items.JANGERBERRY_SEED_5104, 10), - 36 to Reward(Items.WHITEBERRY_SEED_5105, 25), - - 37 to Reward(Items.POISON_IVY_SEED_5106, 30), - 38 to Reward(Items.ACORN_5312, 100), - 39 to Reward(Items.WILLOW_SEED_5313, 1800), - 40 to Reward(Items.MAPLE_SEED_5314, 12000), - 41 to Reward(Items.PINEAPPLE_SEED_5287, 10000), - 42 to Reward(Items.YEW_SEED_5315, 29000), - 43 to Reward(Items.PALM_TREE_SEED_5289, 35000), - 44 to Reward(Items.SPIRIT_SEED_5317, 55000), - 45 to Reward(Items.COMPOST_POTION4_6470, 5000), - 46 to Reward(Items.FLAG_12625, 50), - ) - - fun buy(player: Player, buttonID: Int, amount: Int) { - val reward = REWARDS[buttonID] ?: return - val cost = amount * reward.points - val points = player.getAttribute("vinesweeper:points", 0) - if(cost in 1 until points) { - val item = Item(reward.itemID, amount) - if(!player.inventory.add(item)) { - GroundItemManager.create(item, player) - } - player.incrementAttribute("/save:vinesweeper:points", -cost) - sendUpdatedPoints(player) - } else { - // TODO (crash): authenticity - player.sendMessage("You don't have enough points for that.") - } - } - - override fun defineListeners() { - onOpen(IFACE) { _, _ -> - /*for((buttonID, reward) in REWARDS) { - sendItemOnInterface(player, IFACE, buttonID, reward.itemID, 5) - }*/ - //player.packetDispatch.sendRunScript(2003, "") - return@onOpen true - } + override fun defineInterfaceListeners() { on(IFACE) { player, _, opcode, buttonID, _, _ -> when(opcode) { Opcode.VALUE.value -> { @@ -566,6 +236,338 @@ class VinesweeperRewards : InterfaceListener() { return@on true } } + + data class SeedDestination(val player: Player, val loc: Location, val alive: Boolean) { + override fun equals(other: Any?): Boolean { + return if(other is SeedDestination) { + loc == other.loc + } else { + false + } + } + + override fun hashCode(): Int { + return loc.hashCode() + } + } + + companion object + { + val AVACH_NIMPORTO_LOC = Location.create(1637, 4709) + val PORTAL = 29534 + val SIGNS = intArrayOf(29461, 29462, 29463, 29464) + val HOLES = intArrayOf(29476, 29477, 29478) + val NUMBERS = intArrayOf(29447, 29448, 29449, 29450, 29451, 29452, 29453, 29454, 29455) + val DEAD_PLANT_OBJ = 29456 + val FLAG_OBJ = 29457 + + val IFACE = 686 + val TRADE_FOR_XP_BUTTON = 53 + val XP_CONFIRM = 72 + val XP_DENY = 73 + + enum class Opcode(val value: Int) { + VALUE(155), + BUY1(196), + BUY5(124), + BUY10(199), + BUYX(234), + } + + data class Reward(val itemID: Int, val points: Int) {} + + val REWARDS = hashMapOf( + 18 to Reward(Items.TOMATO_SEED_5322, 10), + 19 to Reward(Items.SWEETCORN_SEED_5320, 150), + 20 to Reward(Items.STRAWBERRY_SEED_5323, 165), + 21 to Reward(Items.WATERMELON_SEED_5321, 680), + 22 to Reward(Items.GUAM_SEED_5291, 10), + 23 to Reward(Items.MARRENTILL_SEED_5292, 10), + 24 to Reward(Items.RANARR_SEED_5295, 4000), + 25 to Reward(Items.KWUARM_SEED_5299, 1000), + 26 to Reward(Items.TARROMIN_SEED_5293, 10), + 27 to Reward(Items.NASTURTIUM_SEED_5098, 10), + + 28 to Reward(Items.WOAD_SEED_5099, 30), + 29 to Reward(Items.LIMPWURT_SEED_5100, 70), + 30 to Reward(Items.ASGARNIAN_SEED_5308, 5), + 31 to Reward(Items.KRANDORIAN_SEED_5310, 20), + 32 to Reward(Items.REDBERRY_SEED_5101, 5), + 33 to Reward(Items.CADAVABERRY_SEED_5102, 5), + 34 to Reward(Items.DWELLBERRY_SEED_5103, 5), + 35 to Reward(Items.JANGERBERRY_SEED_5104, 10), + 36 to Reward(Items.WHITEBERRY_SEED_5105, 25), + + 37 to Reward(Items.POISON_IVY_SEED_5106, 30), + 38 to Reward(Items.ACORN_5312, 100), + 39 to Reward(Items.WILLOW_SEED_5313, 1800), + 40 to Reward(Items.MAPLE_SEED_5314, 12000), + 41 to Reward(Items.PINEAPPLE_SEED_5287, 10000), + 42 to Reward(Items.YEW_SEED_5315, 29000), + 43 to Reward(Items.PALM_TREE_SEED_5289, 35000), + 44 to Reward(Items.SPIRIT_SEED_5317, 55000), + 45 to Reward(Items.COMPOST_POTION4_6470, 5000), + 46 to Reward(Items.FLAG_12625, 50), + ) + + fun buy(player: Player, buttonID: Int, amount: Int) { + val reward = REWARDS[buttonID] ?: return + val cost = amount * reward.points + val points = player.getAttribute("vinesweeper:points", 0) + if(cost in 1 until points) { + val item = Item(reward.itemID, amount) + if(!player.inventory.add(item)) { + GroundItemManager.create(item, player) + } + player.incrementAttribute("/save:vinesweeper:points", -cost) + sendUpdatedPoints(player) + } else { + // TODO (crash): authenticity + player.sendMessage("You don't have enough points for that.") + } + } + + + val TUTORIAL = 685 + + val INSTRUCTION_SIGNS = hashMapOf( + 29463 to 684, + 29464 to 687, + 29462 to 688, + 29461 to 690 + ) + + val RABBIT = 7125 + val FARMERS = intArrayOf(7128, 7129, 7130) + val FARMER_BLINKIN = 7131 + val MRS_WINKIN = 7132 + + val MAX_SEEDS = 300 + val FARMER_CLEAR_RADIUS = 3 + val VINESWEEPER_BORDERS = ZoneBorders(1600,4672,1663,4735) + + fun sendUpdatedPoints(player: Player) { + val points = player.getAttribute("vinesweeper:points", 0); + player.varpManager.get(1195).setVarbit(6, points).send(player) + } + + var SEED_LOCS: HashSet = HashSet() + + fun isSeed(loc: Location): Boolean { + val scenery = getScenery(loc) + return scenery != null && SEED_LOCS.contains(scenery.location) + } + + fun populateSeeds() { + while(SEED_LOCS.size < MAX_SEEDS) { + val loc = VINESWEEPER_BORDERS.getRandomLoc() + val scenery = getScenery(loc) + if(scenery != null && HOLES.contains(scenery.id)) { + SEED_LOCS.add(loc) + } + } + } + + fun dig(player: Player, loc: Location) { + if(isSeed(loc)) { + val oldPoints = player.getAttribute("vinesweeper:points", 0) + player.setAttribute("/save:vinesweeper:points", Math.max(oldPoints-10, 0)) + sendUpdatedPoints(player) + player.sendMessage("Oh dear! It looks like you dug up a potato seed by mistake."); + scheduleNPCs(player, loc, false, false) + val scenery = getScenery(loc) + if(scenery != null) { + SceneryBuilder.replace(scenery, scenery.transform(DEAD_PLANT_OBJ)) + } + } else { + player.incrementAttribute("/save:vinesweeper:points", 1) + sendUpdatedPoints(player) + var count = 0 + for(dx in -1..1) { + for(dy in -1..1) { + if(isSeed(loc.transform(dx, dy, 0))) { + count += 1 + } + } + } + val scenery = getScenery(loc) + if(scenery != null) { + SceneryBuilder.replace(scenery, scenery.transform(NUMBERS[count])) + } + if(count == 0) { + for(dx in -1..1) { + for(dy in -1..1) { + val newLoc = loc.transform(dx, dy, 0) + if(isHole(newLoc)) + dig(player, newLoc) + } + } + } + } + } + + fun isHole(loc: Location): Boolean { + val scenery = getScenery(loc) + return scenery != null && HOLES.contains(scenery.id) + } + + fun scheduleNPCs(player: Player, loc: Location, alive: Boolean, rabbit: Boolean) { + val dest = SeedDestination(player, loc, alive) + val ids = if(rabbit) { intArrayOf(RABBIT, *FARMERS) } else { FARMERS } + for(npc in findLocalNPCs(player, ids, 30)) { + if(npc is VinesweeperNPC) { + npc.seedDestinations.add(dest) + npc.resetWalk() + } + } + } + + object VinesweeperTeleport { + @JvmStatic + fun teleport(npc: NPC, player: Player) { + npc.animate(Animation(437)) + npc.faceTemporary(player, 1) + npc.graphics(Graphics(108)) + player.lock() + player.audioManager.send(125) + Projectile.create(npc, player, 109).send() + npc.sendChat("Avach nimporto!") + GameWorld.Pulser.submit(object : Pulse(1) { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 2 -> { + player.savedData.globalData.essenceTeleporter = npc.id + player.setAttribute("/save:vinesweeper:return-tele:x", npc.location.x) + player.setAttribute("/save:vinesweeper:return-tele:y", npc.location.y) + player.properties.teleportLocation = AVACH_NIMPORTO_LOC + } + 3 -> { + player.graphics(Graphics(110)) + player.unlock() + return true + } + } + return false + } + }) + } + } + } +} + +@Initializable +class VinesweeperNPC : AbstractNPC { + var seedDestinations: ArrayList = ArrayList(); + constructor() : super(RABBIT, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return VinesweeperNPC(id, location) + } + + init { + walkRadius = 22 + } + + override fun getIds(): IntArray { + return intArrayOf(RABBIT, *FARMERS) + } + + override fun handleTickActions() { + val dest = seedDestinations.find { sd -> sd.loc == location } + if(dest != null) { + for(npc in RegionManager.getRegionPlane(location).npcs) { + if(npc is VinesweeperNPC) { + npc.seedDestinations.remove(dest) + npc.resetWalk() + } + } + val scenery = getScenery(dest.loc) + if(scenery != null) { + if(id == RABBIT) { + val replacement = if(SEED_LOCS.contains(dest.loc)) { DEAD_PLANT_OBJ } else { HOLES[0] } + SceneryBuilder.replace(scenery, scenery.transform(replacement)) + scheduleNPCs(dest.player, dest.loc, alive = false, rabbit = false) + } else { + if(dest.alive) { + handleFarmerFlag(scenery, dest) + } else { + sendChat("Hmm. Looks like there's a plant here.") + lock(3) + GameWorld.Pulser.submit(object : Pulse(3) { + override fun pulse(): Boolean { + sendChat("Gracious me! This one's dead") + SceneryBuilder.replace(scenery, scenery.transform(HOLES[0])) + farmerClear(dest) + return true + } + }) + } + } + } + seedDestinations.remove(dest) + } + super.handleTickActions() + } + + override fun getMovementDestination(): Location? { + if(seedDestinations.size > 0) { + seedDestinations.sortBy { a -> a.loc.getDistance(location).toInt() } + return seedDestinations.first().loc + } else { + return super.getMovementDestination() + } + } + + fun handleFarmerFlag(scenery: Scenery, dest: Vinesweeper.SeedDestination) { + sendChat("Ah, another flag to clear. Let's see what's there.") + lock(3) + animate(Animation(451)) + if(SEED_LOCS.contains(dest.loc)) { + val npc = this + GameWorld.Pulser.submit(object : Pulse(3) { + override fun pulse(): Boolean { + sendChat("Ah! A seed. Points for everyone near me!") + val level = dest.player.skills.getStaticLevel(Skills.FARMING) + val points = RandomFunction.random(level, 4 * level) + dest.player.incrementAttribute("/save:vinesweeper:points", points) + dest.player.inventory.add(Item(Items.FLAG_12625, 1)) + sendUpdatedPoints(dest.player) + for(neighbor in RegionManager.getLocalPlayers(npc)) { + if(neighbor != dest.player) { + neighbor.incrementAttribute("/save:vinesweeper:points", points / 2) + sendUpdatedPoints(neighbor) + } + } + SceneryBuilder.replace(scenery, scenery.transform(HOLES[0])) + farmerClear(dest) + return true + } + }) + } else { + SceneryBuilder.replace(scenery, scenery.transform(HOLES[0])) + var i = 0 + val lines = arrayOf("Hmm, no seeds planted here, I'm afraid.", "I'll have to keep this 'ere flag. Sorry.") + GameWorld.Pulser.submit(object : Pulse(3) { + override fun pulse(): Boolean { + sendChat(lines[i++]) + return i >= lines.size + } + }) + } + } + fun farmerClear(dest: Vinesweeper.SeedDestination) { + for(dx in -FARMER_CLEAR_RADIUS..FARMER_CLEAR_RADIUS) { + for(dy in -FARMER_CLEAR_RADIUS..FARMER_CLEAR_RADIUS) { + val toClear = getScenery(dest.loc.transform(dx, dy, 0)) + if(toClear != null && intArrayOf(DEAD_PLANT_OBJ, *NUMBERS).contains(toClear.id)) { + SceneryBuilder.replace(toClear, toClear.transform(HOLES[0])) + } + } + } + SEED_LOCS.remove(dest.loc) + populateSeeds() + } } diff --git a/Server/src/main/kotlin/rs09/game/content/activity/wguild/WGuildListeners.kt b/Server/src/main/kotlin/rs09/game/content/activity/wguild/WGuildListeners.kt index d9ad4623e..5ea454ad8 100644 --- a/Server/src/main/kotlin/rs09/game/content/activity/wguild/WGuildListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/activity/wguild/WGuildListeners.kt @@ -7,7 +7,7 @@ import core.game.node.item.Item import org.rs09.consts.Items import rs09.game.interaction.InteractionListener -class WGuildListeners : InteractionListener() { +class WGuildListeners : InteractionListener { override fun defineListeners() { onEquip(Items.DEFENSIVE_SHIELD_8856){player, node -> if (node is Item) { diff --git a/Server/src/main/kotlin/rs09/game/content/ame/events/certer/CerterEventInterface.kt b/Server/src/main/kotlin/rs09/game/content/ame/events/certer/CerterEventInterface.kt index 10d5725b4..9cfcef0ad 100644 --- a/Server/src/main/kotlin/rs09/game/content/ame/events/certer/CerterEventInterface.kt +++ b/Server/src/main/kotlin/rs09/game/content/ame/events/certer/CerterEventInterface.kt @@ -6,7 +6,7 @@ import org.rs09.consts.Items import rs09.game.content.ame.RandomEventManager import rs09.game.interaction.InterfaceListener -class CerterEventInterface : InterfaceListener() { +class CerterEventInterface : InterfaceListener { val CERTER_INTERFACE = 184 val OPTION_A_CHILD = 1 val OPTION_B_CHILD = 2 @@ -31,7 +31,7 @@ class CerterEventInterface : InterfaceListener() { Items.NULL_6198 to "A necklace." ) val falseOptions = arrayOf("An axe.", "An arrow.", "A pair of boots.", "A pair of gloves.", "A staff.", "A bow.", "A feather.", "The disenfrachaised youth of 1940's Columbia.") - override fun defineListeners() { + override fun defineInterfaceListeners() { on(CERTER_INTERFACE) { player, _, _, buttonID, _, _ -> val answer = buttonID - 7 val correctAnswer = player.getAttribute("certer:correctIndex", 0) diff --git a/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/DrillDemonListeners.kt b/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/DrillDemonListeners.kt index e73300052..2a9b8b16a 100644 --- a/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/DrillDemonListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/ame/events/drilldemon/DrillDemonListeners.kt @@ -5,7 +5,7 @@ import core.game.system.task.Pulse import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener -class DrillDemonListeners : InteractionListener() { +class DrillDemonListeners : InteractionListener { val MATS = intArrayOf(10076,10077,10078,10079) override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/content/ame/events/sandwichlady/SandwichLadyInterface.kt b/Server/src/main/kotlin/rs09/game/content/ame/events/sandwichlady/SandwichLadyInterface.kt index 0abce4b1c..a28bb31fe 100644 --- a/Server/src/main/kotlin/rs09/game/content/ame/events/sandwichlady/SandwichLadyInterface.kt +++ b/Server/src/main/kotlin/rs09/game/content/ame/events/sandwichlady/SandwichLadyInterface.kt @@ -5,7 +5,7 @@ import org.rs09.consts.Items import rs09.game.content.ame.RandomEventManager import rs09.game.interaction.InterfaceListener -class SandwichLadyInterface : InterfaceListener(){ +class SandwichLadyInterface : InterfaceListener{ val SANDWICH_INTERFACE = 297 val baguette = Items.BAGUETTE_6961 @@ -16,7 +16,7 @@ class SandwichLadyInterface : InterfaceListener(){ val kebab = Items.KEBAB_1971 val chocobar = Items.CHOCOLATE_BAR_1973 - override fun defineListeners() { + override fun defineInterfaceListeners() { on(SANDWICH_INTERFACE){player, _, _, buttonID, _, _ -> val item = when(buttonID) { diff --git a/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SEPatternInterface.kt b/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SEPatternInterface.kt index 73ac97c4d..3175b9e1b 100644 --- a/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SEPatternInterface.kt +++ b/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SEPatternInterface.kt @@ -5,11 +5,11 @@ import org.rs09.consts.Components import org.rs09.consts.NPCs import rs09.game.interaction.InterfaceListener -class SEPatternInterface : InterfaceListener() { +class SEPatternInterface : InterfaceListener { val COMPONENT = Components.PATTERN_NEXT_103 - override fun defineListeners() { + override fun defineInterfaceListeners() { on(COMPONENT){player, component, opcode, buttonID, slot, itemID -> val index = buttonID - 10 diff --git a/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SupriseExamListeners.kt b/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SupriseExamListeners.kt index 8d8b241ef..f921b780d 100644 --- a/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SupriseExamListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/ame/events/supriseexam/SupriseExamListeners.kt @@ -9,7 +9,7 @@ import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener import rs09.game.interaction.inter.ExperienceInterface -class SupriseExamListeners : InteractionListener() { +class SupriseExamListeners : InteractionListener { val MORDAUT = NPCs.MR_MORDAUT_6117 val BOOK_OF_KNOWLEDGE = Items.BOOK_OF_KNOWLEDGE_11640 override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/content/dialogue/region/taibwowannai/GabootyDialogue.kt b/Server/src/main/kotlin/rs09/game/content/dialogue/region/taibwowannai/GabootyDialogue.kt index b2fe51f80..373c165c9 100644 --- a/Server/src/main/kotlin/rs09/game/content/dialogue/region/taibwowannai/GabootyDialogue.kt +++ b/Server/src/main/kotlin/rs09/game/content/dialogue/region/taibwowannai/GabootyDialogue.kt @@ -5,6 +5,7 @@ import core.game.content.dialogue.FacialExpression import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.plugin.Initializable +import rs09.game.content.global.shops.Shops import rs09.game.system.config.ShopParser /** @@ -116,8 +117,8 @@ class GabootyDialogue(player: Player? = null) : DialoguePlugin(player){ "you know, a little more of this, a little less of that, it all", "adds up and makes for an interesting tipple!").also { stage = 23 } - 90 -> end().also { ShopParser.Companion.openUid(player,226) } - 91 -> end().also { ShopParser.Companion.openUid(player,227) } + 90 -> end().also { Shops.openId(player,226) } + 91 -> end().also { Shops.openId(player,227) } 99 -> end() } diff --git a/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt b/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt index ac25bf1bd..947fe7459 100644 --- a/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt +++ b/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt @@ -20,7 +20,7 @@ import rs09.game.system.config.ItemConfigParser * @author Ceikry * @author Woah */ -class EquipHandler : InteractionListener() { +class EquipHandler : InteractionListener { override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/content/global/shops/Shop.kt b/Server/src/main/kotlin/rs09/game/content/global/shops/Shop.kt new file mode 100644 index 000000000..8556aa9ff --- /dev/null +++ b/Server/src/main/kotlin/rs09/game/content/global/shops/Shop.kt @@ -0,0 +1,393 @@ +package rs09.game.content.global.shops + +import api.* +import core.game.component.Component +import core.game.container.Container +import core.game.container.ContainerEvent +import core.game.container.ContainerListener +import core.game.container.ContainerType +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.net.packet.PacketRepository +import core.net.packet.context.ContainerContext +import core.net.packet.out.ContainerPacket +import org.rs09.consts.Components +import org.rs09.consts.Items +import rs09.ServerConstants +import rs09.game.content.global.shops.Shops.Companion.logShop +import rs09.game.system.SystemLogger +import rs09.game.world.GameWorld +import java.lang.Integer.max +import java.lang.Integer.min +import kotlin.math.ceil + +data class ShopItem(var itemId: Int, var amount: Int, val restockRate: Int = 100) + +class ShopListener(val player: Player) : ContainerListener +{ + var enabled = false + override fun update(c: Container?, event: ContainerEvent?) { + PacketRepository.send(ContainerPacket::class.java, ContainerContext(player, -1, -1, 92, event!!.items, false, *event.slots)) + } + + override fun refresh(c: Container?) { + PacketRepository.send(ContainerPacket::class.java, ContainerContext(player, -1, -1, 92, c!!.toArray(), c.capacity(), false)) + } +} + +class Shop(val title: String, val stock: Array, val general: Boolean = false, val currency: Int = Items.COINS_995, val highAlch: Boolean = false) +{ + val stockInstances = HashMap() + val playerStock = if (general) generalPlayerStock else Container(40, ContainerType.SHOP) + private val needsUpdate = HashMap() + private val restockRates = HashMap() + + init { + if(!getServerConfig().getBoolean(Shops.personalizedShops, false)) + stockInstances[ServerConstants.SERVER_NAME.hashCode()] = generateStockContainer() + } + + fun openFor(player: Player) + { + val cont = getContainer(player) + setInterfaceText(player, title, 620, 22) + setAttribute(player, "shop", this) + setAttribute(player, "shop-cont", cont) + openInterface(player, Components.SHOP_TEMPLATE_620) + player.interfaceManager.openSingleTab(Component(Components.SHOP_TEMPLATE_SIDE_621)) + showTab(player, true) + logShop("Opening shop [Title: $title, Player: ${player.username}]") + } + + fun showTab(player: Player, main: Boolean) + { + val cont = if (main) getAttribute(player, "shop-cont", null) ?: return else playerStock + + if(!main) + { + cont.listeners.remove(listenerInstances[player.username.hashCode()]) + playerStock.listeners.add(listenerInstances[player.username.hashCode()]) + } + else + { + playerStock.listeners.remove(listenerInstances[player.username.hashCode()]) + cont.listeners.add(listenerInstances[player.username.hashCode()]) + } + + val settings = IfaceSettingsBuilder() + .enableOptions(0..9) + .build() + + player.packetDispatch.sendIfaceSettings(settings, if (main) 23 else 24, Components.SHOP_TEMPLATE_620, 0, cont.capacity()) + player.packetDispatch.sendRunScript(150, "IviiiIsssssssss", "", "", "", "", "Buy X", "Buy 10", "Buy 5", "Buy 1", "Value", -1, 0, 4, 10, 92, (620 shl 16) or if (main) 23 else 24) + player.packetDispatch.sendInterfaceConfig(620, 23, !main) + player.packetDispatch.sendInterfaceConfig(620, 24, main) + player.packetDispatch.sendInterfaceConfig(620, 29, !main) + player.packetDispatch.sendInterfaceConfig(620, 25, main) + player.packetDispatch.sendInterfaceConfig(620, 27, main) + player.packetDispatch.sendInterfaceConfig(620, 26, false) + + if (!main) playerStock.refresh() + else cont.refresh() + + setAttribute(player, "shop-main", main) + } + + private fun getContainer(player: Player) : Container + { + val container = if(getServerConfig().getBoolean(Shops.personalizedShops, false)) + stockInstances[player.username.hashCode()] ?: generateStockContainer().also { stockInstances[player.username.hashCode()] = it } + else + stockInstances[ServerConstants.SERVER_NAME.hashCode()]!! + + val listener = listenerInstances[player.username.hashCode()] + + if(listener != null && listener.player != player) + { + container.listeners.remove(listener) + } + + if(listener == null || listener.player != player) + { + listenerInstances[player.username.hashCode()] = ShopListener(player) + } + + return container + } + + private fun generateStockContainer(): Container + { + val container = Container(40, ContainerType.SHOP) + for(item in stock) { + container.add(Item(item.itemId,item.amount)) + restockRates[item.itemId] = item.restockRate + } + + return container + } + + fun restock() + { + stockInstances.filter { needsUpdate[it.key] == true }.forEach{ (player,cont) -> + for(i in 0 until cont.capacity()) + { + if(stock.size < i + 1) break + if(GameWorld.ticks % stock[i].restockRate != 0) continue + + if(cont[i].amount < stock[i].amount){ + cont[i].amount++ + cont.event.flag(i, cont[i]) + } + else if(cont[i].amount > stock[i].amount){ + cont[i].amount-- + cont.event.flag(i, cont[i]) + } + if(cont[i].amount != stock[i].amount) needsUpdate[player] = true + } + cont.update() + } + } + + fun getBuyPrice(player: Player, slot: Int): Item + { + val isMainStock = getAttribute(player, "shop-main", true) + val cont = if (isMainStock) getAttribute(player, "shop-cont", null) ?: return Item(-1,-1) else playerStock + val item = cont[slot] + val price = when(currency) + { + Items.TOKKUL_6529 -> item.definition.getConfiguration("tokkul_price", 1) + Items.ARCHERY_TICKET_1464 -> item.definition.getConfiguration("archery_ticket_price", 1) + else -> getGPCost(Item(item.id, 1), if (isMainStock) stock[item.slot].amount else playerStock[slot].amount, if (isMainStock) item.amount else playerStock[slot].amount) + } + + return Item(currency, price) + } + + fun getSellPrice(player: Player, slot: Int): Pair + { + val shopCont = getAttribute(player, "shop-cont", null) ?: return Pair(null, Item(-1,-1)) + val item = player.inventory[slot] + var (isPlayerStock, shopSlot) = getStockSlot(item.id) + + val stockAmt = + if(isPlayerStock) + 0 + else{ + if(shopSlot != -1) stock[shopSlot].amount + else 0 + } + val currentAmt = + if(isPlayerStock) playerStock.getAmount(item.id) + else { + if(shopSlot != -1) shopCont[shopSlot].amount + else { + isPlayerStock = true + 0 + } + } + + val price = when(currency) + { + Items.TOKKUL_6529 -> item.definition.getConfiguration("tokkul_price", 1) + Items.ARCHERY_TICKET_1464 -> item.definition.getConfiguration("archery_ticket_price", 1) + else -> getGPSell(Item(item.id, 1), stockAmt, currentAmt) + } + + if(!general && stockAmt == 0 && shopSlot == -1) + { + return Pair(null, Item(-1,-1)) + } + + return Pair(if (isPlayerStock) playerStock else shopCont, Item(currency, price)) + } + + private fun getGPCost(item: Item, stockAmount: Int, currentAmt: Int): Int{ + var mod: Int + mod = if(stockAmount == 0) 100 + else if(currentAmt == 0) 130 + else if(currentAmt >= stockAmount) 100 + else 130 - (130 - 100) * currentAmt / stockAmount + if(mod < 1) mod = 1 + mod = max(100, min(130, mod)) + + + val price: Int = ceil(item.definition.value * mod.toDouble() / 100.0).toInt() +/* if(player.getVarp(532) == 6529){ + price = 3 * price / 2 + }*/ + return max(price, 1) + } + + private fun getGPSell(item: Item, stockAmount: Int, currentAmt: Int): Int{ + if(!item.definition.isUnnoted) + item.id = item.noteChange + var mod: Int + mod = if(stockAmount == 0) 70 + else if(currentAmt == 0) 100 + else if(currentAmt >= stockAmount) 70 + else 100 - (100 - 70) * currentAmt / stockAmount + if(mod < 1) mod = 1 + mod = max(70, min(100, mod)) + + var base = if (highAlch) item.definition.getAlchemyValue(true) else item.definition.value + base = max(base, item.definition.value) + + val price: Int = ceil(base * mod.toDouble() / 100.0).toInt() + return max(price, 1) + } + + fun buy(player: Player, slot: Int, amount: Int) + { + if(amount !in 1..Integer.MAX_VALUE) return + val isMainStock = getAttribute(player, "shop-main", false) + if(!isMainStock && player.ironmanManager.isIronman) + { + sendDialogue(player, "As an ironman, you cannot buy from player stock in shops.") + return + } + val cont = if (isMainStock) getAttribute(player, "shop-cont", null) ?: return else playerStock + val inStock = cont[slot] + val item = Item(inStock.id, amount) + if(inStock.amount < amount) + item.amount = inStock.amount + + if(inStock.amount > stock[slot].amount && !getServerConfig().getBoolean(Shops.personalizedShops, false)) + { + sendDialogue(player, "As an ironman, you cannot buy overstocked items from shops.") + return + } + + val cost = getBuyPrice(player, slot) + if(cost.id == -1) sendMessage(player, "This shop cannot sell that item.").also { return } + + if(currency == Items.COINS_995){ + var amt = item.amount + var inStockAmt = inStock.amount + while(amt-- > 1) + cost.amount += getGPCost(Item(item.id, 1), if (isMainStock) stock[slot].amount else playerStock[slot].amount, --inStockAmt) + } else { + cost.amount = cost.amount * item.amount + } + + if(inInventory(player, cost.id, cost.amount)) + { + if(removeItem(player, cost)) + { + if(!hasSpaceFor(player, item)) { + addItem(player, cost.id, cost.amount) + sendMessage(player, "You don't have enough inventory space to buy that many.") + return + } + + if(!isMainStock && cont[slot].amount - item.amount == 0) + { + cont.remove(cont[slot], false) + cont.refresh() + } + else { + cont[slot].amount -= item.amount + cont.event.flag(slot, cont[slot]) + cont.update() + } + + addItem(player, item.id, item.amount) + + if(getServerConfig().getBoolean(Shops.personalizedShops, false)){ + needsUpdate[player.username.hashCode()] = true + } else { + needsUpdate[ServerConstants.SERVER_NAME.hashCode()] = true + } + } + } + else + { + sendMessage(player, "You don't have enough ${cost.name.toLowerCase()} to buy that many.") + } + } + + fun sell(player: Player, slot: Int, amount: Int) + { + if(amount !in 1..Integer.MAX_VALUE) return + val playerInventory = player.inventory[slot] + if(playerInventory.id in intArrayOf(Items.COINS_995, Items.TOKKUL_6529, Items.ARCHERY_TICKET_1464)) + { + sendMessage(player, "You can't sell currency to a shop.") + return + } + val item = Item(playerInventory.id, amount) + val (container,profit) = getSellPrice(player, slot) + if(profit.amount == -1) sendMessage(player, "This item can't be sold to this shop.").also { return } + if(amount > player.inventory.getAmount(item.id)) + item.amount = player.inventory.getAmount(item.id) + + if(currency == Items.COINS_995 && item.amount > 1){ + val id = if(!item.definition.isUnnoted) item.noteChange else item.id + val (isPlayerStock, shopSlot) = getStockSlot(id) + var amt = item.amount + var inStockAmt = container!![shopSlot]?.amount ?: playerStock.getAmount(id) + while(amt-- > 1) + profit.amount += getGPSell(Item(item.id, 1), if (isPlayerStock) 0 else stock[shopSlot].amount, ++inStockAmt) + } else { + profit.amount = profit.amount * item.amount + } + + if(removeItem(player, item)) + { + if(!hasSpaceFor(player, profit)){ + sendMessage(player, "You don't have enough space to do that.") + addItem(player, item.id, item.amount) + return + } + if(container == playerStock && getAttribute(player, "shop-main", false)){ + showTab(player, false) + } + else if(!getAttribute(player, "shop-main", false) && container != playerStock) + { + showTab(player, true) + } + addItem(player, profit.id, profit.amount) + if(!item.definition.isUnnoted) + { + item.id = item.noteChange + } + container?.add(item) + container?.refresh() + if(getServerConfig().getBoolean(Shops.personalizedShops, false)){ + needsUpdate[player.username.hashCode()] = true + } else { + needsUpdate[ServerConstants.SERVER_NAME.hashCode()] = true + } + } + } + + fun getStockSlot(itemId: Int): Pair + { + var shopSlot: Int = -1 + var isPlayerStock = false + val notechange = itemDefinition(itemId).noteId + for((stockSlot, shopItem) in stock.withIndex()) + { + if(shopItem.itemId == itemId || shopItem.itemId == notechange) + shopSlot = stockSlot + } + if(shopSlot == -1) + { + for((stockSlot, playerStockItem) in playerStock.toArray().withIndex()) + { + if(playerStockItem == null) continue + if(playerStockItem.id == itemId || playerStockItem.id == notechange) { + shopSlot = stockSlot + isPlayerStock = true + } + } + } + + return Pair(isPlayerStock, shopSlot) + } + + companion object { + //General stores globally share player stock (weird quirk, right?) + val generalPlayerStock = Container(40, ContainerType.SHOP) + val listenerInstances = HashMap() + } +} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/global/shops/Shops.kt b/Server/src/main/kotlin/rs09/game/content/global/shops/Shops.kt new file mode 100644 index 000000000..de06090f2 --- /dev/null +++ b/Server/src/main/kotlin/rs09/game/content/global/shops/Shops.kt @@ -0,0 +1,256 @@ +package rs09.game.content.global.shops + +import api.* +import core.game.content.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.crafting.TanningProduct +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import org.rs09.consts.Components +import org.rs09.consts.NPCs +import rs09.ServerConstants +import rs09.game.interaction.InteractionListener +import rs09.game.interaction.InterfaceListener +import rs09.game.system.SystemLogger +import rs09.tools.END_DIALOGUE +import java.io.FileReader + +/** + * The "controller" class for shops. Handles opening shops from various NPC interactions and updating stock, etc. + * Note: If you wish to enable personalized shops, add and set the personalized_shops entry to true in the world section of the server config. + * ex: + * ```toml + * [world] + * personalized_shops = true + * ``` + */ +class Shops : StartupListener, TickListener, InteractionListener, InterfaceListener, Commands { + companion object { + @JvmStatic val personalizedShops = "world.personalized_shops" + @JvmStatic val shopsById = HashMap() + @JvmStatic val shopsByNpc = HashMap() + + @JvmStatic fun openId(player: Player, id: Int) + { + shopsById[id]?.openFor(player) + } + + fun logShop(msg: String) + { + SystemLogger.logInfo("[SHOPS] $msg") + } + } + + override fun startup() { + val path = ServerConstants.CONFIG_PATH + "shops.json" + var shopCount = 0 + logShop("Using JSON path: $path") + + val reader = FileReader(path) + val data = JSONParser().parse(reader) as JSONArray + + fun parseStock(stock: String, id: Int): ArrayList{ + val items = ArrayList() + val idsInStock = HashMap() + if(stock.isEmpty()){ + return items + } + stock.split('-').map { + val tokens = it.replace("{", "").replace("}", "").split(",".toRegex()).toTypedArray() + var amount = tokens[1].trim() + if(amount == "inf") + amount = "-1" + val item = tokens[0].toInt() + if(idsInStock[item] != null) + SystemLogger.logWarn("[SHOPS] MALFORMED STOCK IN SHOP ID $id FOR ITEM $item") + else + items.add(ShopItem(item, amount.toInt(), tokens.getOrNull(2)?.toIntOrNull() ?: 100)) + } + return items + } + + for(rawShop in data) + { + var shop: Shop? + val shopData = rawShop as JSONObject + val id = shopData["id"].toString().toInt() + val title = shopData["title"].toString() + val general = shopData["general_store"].toString().toBoolean() + val stock = parseStock(shopData["stock"].toString(), id).toTypedArray() + val npcs = if(shopData["npcs"].toString().isNotBlank()) shopData["npcs"].toString().split(",").map { it.toInt() }.toIntArray() else intArrayOf() + val currency = shopData["currency"].toString().toInt() + val highAlch = shopData["high_alch"].toString() == "1" + shop = Shop(title, stock, general, currency, highAlch) + + npcs.map { shopsByNpc[it] = shop } + shopsById[id] = shop + ++shopCount + } + + logShop("Parsed $shopCount shops.") + } + + override fun tick() { + shopsById.values.forEach(Shop::restock) + } + + override fun defineListeners() { + on(NPC, "trade", "shop"){player, node -> + val npc = node as NPC + if (npc.id == 2824) { + TanningProduct.open(player, 2824) + return@on true + } + if (npc.id == 7601) { + openInterface(player, 732) + return@on true + } + shopsByNpc[npc.id]?.openFor(player) ?: return@on false + return@on true + } + + on(NPCs.SIEGFRIED_ERKLE_933, NPC, "trade"){ player, node -> + val points = getQP(player) + if(points < 40){ + sendNPCDialogue(player, NPCs.SIEGFRIED_ERKLE_933, "I'm sorry, adventurer, but you need 40 quest points to buy from me.") + return@on true + } + shopsByNpc[node.id]?.openFor(player) + return@on true + } + + on(NPCs.FUR_TRADER_1316, NPC,"trade") { player, node -> + if (!isQuestComplete(player, "Fremennik Trials")) { + sendNPCDialogue(player, NPCs.FUR_TRADER_1316, "I don't sell to outerlanders.", FacialExpression.ANNOYED).also { END_DIALOGUE } + } else { + shopsByNpc[node.id]?.openFor(player) + } + return@on true + } + + on(NPCs.FISH_MONGER_1315, NPC,"trade") { player, node -> + if (!isQuestComplete(player, "Fremennik Trials")) { + sendNPCDialogue(player, NPCs.FISH_MONGER_1315, "I don't sell to outerlanders.", FacialExpression.ANNOYED).also { END_DIALOGUE } + } else { + shopsByNpc[node.id]?.openFor(player) + } + return@on true + } + } + + override fun defineInterfaceListeners() { + on(Components.SHOP_TEMPLATE_620){player, _, opcode, buttonID, slot, _ -> + val OP_VALUE = 155 + val OP_BUY_1 = 196 + val OP_BUY_5 = 124 + val OP_BUY_10 = 199 + val OP_BUY_X = 234 + val OP_EXAMINE = 9 + + val shop = getAttribute(player, "shop", null) ?: return@on false + val isMainStock = getAttribute(player, "shop-main", true) + + when(buttonID) + { + 26 -> shop.showTab(player, false).also { return@on true } + 25 -> shop.showTab(player, true).also { return@on true } + 27,29 -> return@on true + } + + val price = shop.getBuyPrice(player, slot) + + when(opcode) + { + OP_VALUE -> sendMessage(player, "${getItemName(if (isMainStock) shop.stock[slot].itemId else shop.playerStock[slot].id)}: This item currently costs ${price.amount} ${price.name.toLowerCase()}.") + OP_BUY_1 -> shop.buy(player, slot, 1) + OP_BUY_5 -> shop.buy(player, slot, 5) + OP_BUY_10 -> shop.buy(player, slot, 10) + OP_BUY_X -> sendInputDialogue(player, true, "Enter the amount to buy:"){value -> + val amt = value as Int + shop.buy(player, slot, amt) + } + OP_EXAMINE -> sendMessage(player, itemDefinition(if (isMainStock) shop.stock[slot].itemId else shop.playerStock[slot].id).examine) + } + + return@on true + } + + onOpen(Components.SHOP_TEMPLATE_SIDE_621) {player, _ -> + val settings = IfaceSettingsBuilder() + .enableOptions(0 until 9) + .build() + player.packetDispatch.sendIfaceSettings(settings, 0, 621, 0, 28) + player.packetDispatch.sendRunScript(150, "IviiiIsssssssss", "", "", "", "", "Sell X", "Sell 10", "Sell 5", "Sell 1", "Value", -1, 0, 7, 4, 93, 621 shl 16); + return@onOpen true + } + + onClose(Components.SHOP_TEMPLATE_620) { player, _ -> + val shop = getAttribute(player, "shop", null) ?: return@onClose true + val listener = Shop.listenerInstances[player.username.hashCode()] ?: return@onClose true + + if(getServerConfig().getBoolean(personalizedShops, false)) + shop.stockInstances[player.username.hashCode()]?.listeners?.remove(listener) + else + shop.stockInstances[ServerConstants.SERVER_NAME.hashCode()]!!.listeners.remove(listener) + + shop.playerStock.listeners.remove(listener) + player.interfaceManager.closeSingleTab() + return@onClose true + } + + on(Components.SHOP_TEMPLATE_SIDE_621){player, component, opcode, buttonID, slot, itemID -> + val OP_VALUE = 155 + val OP_SELL_1 = 196 + val OP_SELL_5 = 124 + val OP_SELL_10 = 199 + val OP_SELL_X = 234 + + val shop = getAttribute(player, "shop", null) ?: return@on false + + val (_,price) = shop.getSellPrice(player, slot) + + val valueMsg = if(price.amount == -1) "This shop will not buy that item." else "${player.inventory[slot].name}: This shop will buy this item for ${price.amount} ${price.name.toLowerCase()}." + + when(opcode) + { + OP_VALUE -> sendMessage(player, valueMsg) + OP_SELL_1 -> shop.sell(player, slot, 1) + OP_SELL_5 -> shop.sell(player, slot, 5) + OP_SELL_10 -> shop.sell(player, slot, 10) + OP_SELL_X -> sendInputDialogue(player, true, "Enter the amount to sell:"){value -> + val amt = value as Int + shop.sell(player, slot, amt) + } + } + + return@on true + } + } + + override fun defineDestinationOverrides() { + setDest(NPC,"trade","shop"){_,node -> + val npc = node as NPC + if (npc.getAttribute("facing_booth", false)) { + val offsetX = npc.direction.stepX shl 1 + val offsetY = npc.direction.stepY shl 1 + return@setDest npc.location.transform(offsetX, offsetY, 0) + } + return@setDest node.location + } + } + + override fun defineCommands() { + define("openshop") { player, args -> + if(args.size < 2) reject(player, "Usage: ::openshop shopId") + val shopId = args[1].toInt() + shopsById[shopId]?.openFor(player) + } + + define("shopscript") { player, args -> + val arg1 = args[1].toInt() + player.packetDispatch.sendRunScript(25, "vg", arg1, 92) //Run CS2 script 25, with args 868? and 92(our container id) + } + } +} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/christmas/GiftRollPlugin.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/christmas/GiftRollPlugin.kt index 08955ae5e..c2f4bc06a 100644 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/christmas/GiftRollPlugin.kt +++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/christmas/GiftRollPlugin.kt @@ -48,7 +48,7 @@ class GiftRollPlugin : XPGainPlugin() { } } -class XMASMboxHandler : InteractionListener() { +class XMASMboxHandler : InteractionListener { val MBOX = Items.MYSTERY_BOX_6199 override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/easter/EasterEventListeners.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/easter/EasterEventListeners.kt index aae620fba..b6f166fae 100644 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/easter/EasterEventListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/easter/EasterEventListeners.kt @@ -7,7 +7,7 @@ import org.rs09.consts.Items import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener -class EasterEventListeners : InteractionListener() { +class EasterEventListeners : InteractionListener { val EGG_ATTRIBUTE = "/save:easter:eggs" val eggs = intArrayOf(Items.EASTER_EGG_11027, Items.EASTER_EGG_11028, Items.EASTER_EGG_11029, Items.EASTER_EGG_11030) diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/halloween/TrickOrTreatHandler.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/halloween/TrickOrTreatHandler.kt index d40b33533..0420704cc 100644 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/halloween/TrickOrTreatHandler.kt +++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/holiday/halloween/TrickOrTreatHandler.kt @@ -19,7 +19,7 @@ import rs09.game.interaction.InteractionListener import rs09.game.world.GameWorld import rs09.tools.END_DIALOGUE -class TrickOrTreatHandler : InteractionListener() { +class TrickOrTreatHandler : InteractionListener { override fun defineListeners() { on(NPC, "trick-or-treat"){player, node -> val hasDone5 = getDailyTrickOrTreats(player) == 5 diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinSpyingHandler.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinSpyingHandler.kt index a2fbe7656..613ec2246 100644 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinSpyingHandler.kt +++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinSpyingHandler.kt @@ -13,7 +13,7 @@ import core.game.content.quest.PluginInteraction import core.game.content.quest.PluginInteractionManager import rs09.game.interaction.InteractionListener -class PenguinSpyingHandler : InteractionListener(){ +class PenguinSpyingHandler : InteractionListener{ override fun defineListeners() { on(PENGUINS, NPC, "spy-on"){player, node -> diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStar.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStar.kt index 14602254e..c42369962 100644 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStar.kt +++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStar.kt @@ -71,15 +71,15 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando starSprite.location = starObject.location starSprite.init() spriteSpawned = true - ShootingStarEvent.getStoreFile().clear() + ShootingStarPlugin.getStoreFile().clear() return } level = getNextType() maxDust = level.totalStardust dustLeft = level.totalStardust - ShootingStarEvent.getStoreFile()["level"] = level.ordinal - ShootingStarEvent.getStoreFile()["isDiscovered"] = isDiscovered + ShootingStarPlugin.getStoreFile()["level"] = level.ordinal + ShootingStarPlugin.getStoreFile()["isDiscovered"] = isDiscovered val newStar = Scenery(level.objectId, starObject.location) SceneryBuilder.replace(starObject, newStar) @@ -114,10 +114,10 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando * Rebuilds some of the variables with new information. */ fun rebuildVars(){ - if(firstStar && ShootingStarEvent.getStoreFile().isNotEmpty()){ - level = ShootingStarType.values()[ShootingStarEvent.getStoreFile().getInt("level")] - location = ShootingStarEvent.getStoreFile().getString("location") - isDiscovered = ShootingStarEvent.getStoreFile().getBoolean("isDiscovered") + if(firstStar && ShootingStarPlugin.getStoreFile().isNotEmpty()){ + level = ShootingStarType.values()[ShootingStarPlugin.getStoreFile().getInt("level")] + location = ShootingStarPlugin.getStoreFile().getString("location") + isDiscovered = ShootingStarPlugin.getStoreFile().getBoolean("isDiscovered") } else { level = ShootingStarType.values().random() location = crash_locations.entries.random().key @@ -128,9 +128,9 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando dustLeft = level.totalStardust starObject = Scenery(level.objectId, crash_locations.get(location)) - ShootingStarEvent.getStoreFile()["level"] = level.ordinal - ShootingStarEvent.getStoreFile()["location"] = location - ShootingStarEvent.getStoreFile()["isDiscovered"] = false + ShootingStarPlugin.getStoreFile()["level"] = level.ordinal + ShootingStarPlugin.getStoreFile()["location"] = location + ShootingStarPlugin.getStoreFile()["isDiscovered"] = false ticks = 0 firstStar = false diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarCommands.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarCommands.kt deleted file mode 100644 index 3f067b91e..000000000 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarCommands.kt +++ /dev/null @@ -1,40 +0,0 @@ -package rs09.game.content.global.worldevents.shootingstar - -import core.game.node.entity.player.Player -import core.game.system.command.CommandSet -import core.plugin.Plugin -import rs09.game.content.global.worldevents.WorldEvents -import rs09.game.system.command.CommandPlugin -import java.util.concurrent.TimeUnit - -/** - * A few assorted commands for shooting stars. - */ -class ShootingStarCommands : CommandPlugin(){ - override fun newInstance(arg: Any?): Plugin{ - link(CommandSet.DEVELOPER) - return this - } - - override fun parse(player: Player?, name: String?, args: Array?): Boolean { - val star = (WorldEvents.get("shooting-stars") as ShootingStarEvent).star - when (name) { - "tostar" -> { - player!!.teleport(star.starObject.location.transform(1, 1, 0)) - } - "submit" -> { - star.fire() - } - "resettime" -> player!!.savedData.globalData.starSpriteDelay = 0L - "stardust" -> { - val dust = 8 - println("Cosmic Runes: " + 0.76 * dust) - println("Astral runes: " + 0.26 * dust) - println("Gold ores: " + 0.1 * dust) - println("GP: " + 250.1 * dust) - } - "setsprite" -> player!!.savedData.globalData.starSpriteDelay = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1) - } - return true - } -} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarEvent.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarEvent.kt deleted file mode 100644 index bbfe2df56..000000000 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarEvent.kt +++ /dev/null @@ -1,92 +0,0 @@ -package rs09.game.content.global.worldevents.shootingstar - -import core.game.content.global.worldevents.shootingstar.ScoreboardHandler -import core.game.content.global.worldevents.shootingstar.ShootingStarScoreboard -import core.game.content.global.worldevents.shootingstar.StarChartPlugin -import core.game.system.task.Pulse -import org.json.simple.JSONObject -import rs09.ServerStore -import rs09.game.content.global.worldevents.PluginSet -import rs09.game.content.global.worldevents.WorldEvent -import rs09.game.content.global.worldevents.WorldEvents -import rs09.game.world.GameWorld - - -/** - * The world event class for shooting stars. Keeps track of event-related data like the ShootingStar instance. - * Also handles spawning new shooting stars based on time. - * @author Ceikry - */ -class ShootingStarEvent : WorldEvent("shooting-stars") { - val star = ShootingStar() - val tickDelay = if(GameWorld.settings?.isDevMode == true) 200 else 25000 - - - override fun initialize() { - plugins = PluginSet( - ScoreboardHandler(), - ShootingStarScoreboard(), - StarChartPlugin(), - ShootingStarCommands(), - StarSpriteDialogue(), - ShootingStarLogin() - ) - super.initialize() - GameWorld.Pulser.submit(StarPulse()) - log("Shooting Star event has been initialized.") - } - - override fun checkTrigger(): Boolean { - /** - * Spawn a new star only if: star's ticks are greater than the tickDelay and star sprite is not spawned OR, - * neither the star or the sprite are spawned. - */ - star.ticks += 10 - if ((star.ticks >= tickDelay && !star.spriteSpawned) || (!star.isSpawned && !star.spriteSpawned)) { - return true - } - - /** - * Clear the sprite when we have passed the tickDelay + (1/3) of the tickDelay. - * This gives players a little extra time before the star respawns to run to the bank and grab - * stardust or whatever. Once the sprite is cleared a new star will be allowed to spawn. - */ - val maxDelay = tickDelay + (tickDelay / 3) - if(star.ticks > maxDelay && star.spriteSpawned){ - star.clearSprite() - } - - return false - } - - override fun checkActive(): Boolean { - return true //this event is always active. - } - - override fun fireEvent() { - log("Fired new shooting star event.") - star.fire() - } - - /** - * Handles checking star status and spawning new ones if necessary. - */ - class StarPulse : Pulse(10){ - override fun pulse(): Boolean { - val event = WorldEvents.get("shooting-stars") - event ?: return true - - if(event.checkTrigger()){ - event.fireEvent() - } - - return false //always returns false because it needs to run forever. - } - } - - companion object { - fun getStoreFile() : JSONObject { - return ServerStore.getArchive("shooting-star") - } - } -} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarLogin.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarLogin.kt deleted file mode 100644 index 9a2feb669..000000000 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarLogin.kt +++ /dev/null @@ -1,29 +0,0 @@ -package rs09.game.content.global.worldevents.shootingstar - -import core.game.node.entity.player.Player -import core.plugin.Plugin -import core.plugin.PluginManifest -import core.plugin.PluginType -import rs09.game.content.global.worldevents.WorldEvents - -/** - * A plugin that handles the message a player receives on login pertaining to shooting stars. - */ -@PluginManifest(type = PluginType.LOGIN) -class ShootingStarLogin : Plugin { - @Throws(Throwable::class) - override fun newInstance(arg: Player?): Plugin? { - if (arg is Player) { - val star = (WorldEvents.get("shooting-stars") as ShootingStarEvent).star - if (star.isSpawned) { - arg.sendMessage("News: A shooting star (Level " + (star.level.ordinal + 1).toString() + ") has just crashed near the " + star.location + "!") - } - return this - } - return this - } - - override fun fireEvent(identifier: String, vararg args: Any): Any { - return Unit - } -} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarMiningPulse.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarMiningPulse.kt index 5d3f6b27a..1d49f14a4 100644 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarMiningPulse.kt +++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarMiningPulse.kt @@ -1,7 +1,6 @@ package rs09.game.content.global.worldevents.shootingstar import api.* -import core.game.content.global.worldevents.shootingstar.ScoreboardManager import core.game.node.scenery.Scenery import core.game.node.entity.player.Player import core.game.node.entity.skill.SkillPulse @@ -50,7 +49,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin player.incrementAttribute("/save:shooting-star:bonus-xp", bonusXp) Repository.sendNews(player.username + " is the discoverer of the crashed star near " + star.location + "!") player.sendMessage("You have ${player.skills.experienceMutiplier * player.getAttribute("shooting-star:bonus-xp", 0).toDouble()} bonus xp towards mining stardust.") - ScoreboardManager.submit(player) + ShootingStarPlugin.submitScoreBoard(player) star.isDiscovered = true return player.skills.getLevel(Skills.MINING) >= star.miningLevel } @@ -63,7 +62,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin player.packetDispatch.sendMessage("You do not have a pickaxe to use.") return false } - if (player.inventory.freeSlots() < 1 && !player.inventory.contains(ShootingStarOptionHandler.STAR_DUST, 1)) { + if (player.inventory.freeSlots() < 1 && !player.inventory.contains(ShootingStarPlugin.STAR_DUST, 1)) { player.dialogueInterpreter.sendDialogue("Your inventory is too full to hold any more stardust.") return false } @@ -98,8 +97,8 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin } player.skills.addExperience(Skills.MINING, xp) - if (ShootingStarOptionHandler.getStarDust(player) < 200) { - player.inventory.add(Item(ShootingStarOptionHandler.STAR_DUST, 1)) + if (ShootingStarPlugin.getStarDust(player) < 200) { + player.inventory.add(Item(ShootingStarPlugin.STAR_DUST, 1)) } if(!inInventory(player, Items.ANCIENT_BLUEPRINT_14651) && !inBank(player, Items.ANCIENT_BLUEPRINT_14651)){ rollBlueprint(player) diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarOptionHandler.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarOptionHandler.kt deleted file mode 100644 index 8b8fc6cee..000000000 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarOptionHandler.kt +++ /dev/null @@ -1,39 +0,0 @@ -package rs09.game.content.global.worldevents.shootingstar - -import core.game.node.entity.player.Player -import rs09.game.content.global.worldevents.WorldEvents -import rs09.game.interaction.InteractionListener - -/** - * Option handlers for the various shooting star objects. - */ -class ShootingStarOptionHandler : InteractionListener() { - - val SHOOTING_STARS = ShootingStarType.values().map(ShootingStarType::objectId).toIntArray() - - override fun defineListeners() { - on(SHOOTING_STARS,SCENERY,"mine"){ player, _ -> - val star = (WorldEvents.get("shooting-stars") as ShootingStarEvent).star - star.mine(player) - return@on true - } - - on(SHOOTING_STARS,SCENERY,"prospect"){ player, _ -> - val star = (WorldEvents.get("shooting-stars") as ShootingStarEvent).star - star.prospect(player) - return@on true - } - } - - companion object { - const val STAR_DUST = 13727 - /** - * Gets the star dust amount for a player. - * @param player The player. - * @return The stardust amount. - */ - fun getStarDust(player: Player): Int { - return player.inventory.getAmount(STAR_DUST) + player.bank.getAmount(STAR_DUST) - } - } -} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarPlugin.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarPlugin.kt new file mode 100644 index 000000000..d8305627c --- /dev/null +++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/ShootingStarPlugin.kt @@ -0,0 +1,176 @@ +package rs09.game.content.global.worldevents.shootingstar + +import api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.entity.skill.Skills +import org.json.simple.JSONObject +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import rs09.ServerStore +import rs09.ServerStore.Companion.getBoolean +import rs09.game.content.dialogue.DialogueFile +import rs09.game.interaction.InteractionListener +import rs09.game.system.SystemLogger +import rs09.game.system.command.Privilege +import rs09.game.world.GameWorld +import rs09.tools.secondsToTicks + +class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Commands, StartupListener { + override fun login(player: Player) { + if(star.isSpawned && !star.spriteSpawned) + sendMessage(player, "News: A shooting star (Level ${star.level.ordinal + 1}) has just crashed near the ${star.location}!") + } + + override fun tick() { + ++star.ticks + + val maxDelay = tickDelay + (tickDelay / 3) + if(star.ticks > maxDelay && star.spriteSpawned){ + star.clearSprite() + } + + if ((star.ticks >= tickDelay && !star.spriteSpawned) || (!star.isSpawned && !star.spriteSpawned)) { + star.fire() + } + } + + override fun defineListeners() { + on(Scenery.SHOOTING_STAR_NOTICEBOARD_38669, SCENERY, "read") { player, _ -> + var index = 0 + scoreboardEntries.forEach { entry -> + val timeElapsed = secondsToTicks(GameWorld.ticks - entry.time) / 60 + setInterfaceText(player, "$timeElapsed minutes ago", scoreboardIface, index + 6) + setInterfaceText(player, entry.player, scoreboardIface, index + 11) + ++index + } + openInterface(player, scoreboardIface) + return@on true + } + + on(SHOOTING_STARS,SCENERY,"mine"){ player, _ -> + star.mine(player) + return@on true + } + + on(SHOOTING_STARS,SCENERY,"prospect"){ player, _ -> + star.prospect(player) + return@on true + } + + on(RING, ITEM, "rub", "operate"){player, node -> + if(getRingStoreFile().getBoolean(player.username.toLowerCase())){ + sendDialogue(player, "The ring is still recharging.") + return@on true + } + + val condition: (Player) -> Boolean = when(star.location.toLowerCase()){ + "canifis bank" -> { p -> p.questRepository.isComplete("Priest in Peril")} + "crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40) } + "south crandor mining site" -> {p -> p.questRepository.isComplete("Dragon Slayer")} + else -> {_ -> true} + } + + if(!condition.invoke(player) || player.skullManager.isWilderness){ + sendDialogue(player, "Magical forces prevent your teleportation.") + return@on true + } + + val shouldWarn = when(star.location){ + "North Edgeville mining site", + "Southern wilderness mine", + "Pirates' Hideout mine", + "Lava Maze mining site", + "Mage Arena bank" -> true + else -> false + } + + openDialogue(player, RingDialogue(shouldWarn, star)) + + return@on true + } + } + + override fun defineCommands() { + define("tostar", Privilege.ADMIN) { player, _ -> + teleport(player, star.starObject.location.transform(1,1,0)) + } + + define("submit", Privilege.ADMIN) { _, _ -> + star.fire() + } + + define("resetsprite", Privilege.ADMIN) { player, _ -> + player.savedData.globalData.starSpriteDelay = 0L + } + } + + override fun startup() { + SystemLogger.logInfo("Shooting Stars initialized.") + } + + private data class ScoreboardEntry(val player: String, val time: Int) + + private class RingDialogue(val shouldWarn: Boolean, val star: ShootingStar) : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + if(shouldWarn){ + when(stage) { + 0 -> dialogue("WARNING: That mining site is located in the wilderness.").also { stage++ } + 1 -> player!!.dialogueInterpreter.sendOptions("Continue?","Yes","No").also { stage++ } + 2 -> when(buttonID){ + 1 -> teleport(player!!, star).also { end() } + 2 -> end() + } + } + } else { + when(stage){ + 0 -> player!!.dialogueInterpreter.sendOptions("Teleport to the Star?", "Yes", "No").also { stage++ } + 1 -> when(buttonID){ + 1 -> teleport(player!!, star).also { end() } + 2 -> end() + } + } + } + } + + fun teleport(player: Player, star: ShootingStar){ + teleport(player, star.crash_locations[star.location]!!.transform(0, -1, 0), TeleportManager.TeleportType.MINIGAME) + getRingStoreFile()[player.username.toLowerCase()] = true + } + } + + companion object { + private val star = ShootingStar() + private val tickDelay = if(GameWorld.settings?.isDevMode == true) 200 else 25000 + private val scoreboardEntries = ArrayList() + private val scoreboardIface = 787 + val SHOOTING_STARS = ShootingStarType.values().map(ShootingStarType::objectId).toIntArray() + val STAR_DUST = Items.STARDUST_13727 + val RING = Items.RING_OF_THE_STAR_SPRITE_14652 + + + @JvmStatic fun submitScoreBoard(player: Player) + { + if(scoreboardEntries.size == 5) + scoreboardEntries.removeAt(0) + scoreboardEntries.add(ScoreboardEntry(player.username, GameWorld.ticks)) + } + + @JvmStatic fun getStar(): ShootingStar + { + return star + } + + @JvmStatic fun getStoreFile() : JSONObject { + return ServerStore.getArchive("shooting-star") + } + + @JvmStatic fun getRingStoreFile() : JSONObject { + return ServerStore.getArchive("daily-star-ring") + } + + fun getStarDust(player: Player): Int { + return player.inventory.getAmount(STAR_DUST) + player.bank.getAmount(STAR_DUST) + } + } +} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/StarSpriteDialogue.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/StarSpriteDialogue.kt index 10d8cafc3..38b77f9c0 100644 --- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/StarSpriteDialogue.kt +++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/shootingstar/StarSpriteDialogue.kt @@ -7,6 +7,7 @@ import core.game.content.dialogue.FacialExpression import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.item.Item +import core.plugin.Initializable import core.tools.RandomFunction import org.json.simple.JSONObject import org.rs09.consts.Items @@ -21,6 +22,7 @@ import java.util.concurrent.TimeUnit /** * Dialogue for the star sprite. */ +@Initializable class StarSpriteDialogue(player: Player? = null) : DialoguePlugin(player) { /** @@ -70,7 +72,7 @@ class StarSpriteDialogue(player: Player? = null) : DialoguePlugin(player) { } else if (inInventory(player, Items.ANCIENT_BLUEPRINT_14651) && getAttribute(player, "star-ring:bp-shown", false)) { playerl(FacialExpression.HALF_ASKING, "So about those rings...") stage = 2000 - } else if (getStoreFile().getBoolean(player.username.toLowerCase()) || !player.getInventory().contains(ShootingStarOptionHandler.STAR_DUST, 1)) { + } else if (getStoreFile().getBoolean(player.username.toLowerCase()) || !player.getInventory().contains(ShootingStarPlugin.STAR_DUST, 1)) { npc("Hello, strange creature.") stage = 0 } else { @@ -185,8 +187,8 @@ class StarSpriteDialogue(player: Player? = null) : DialoguePlugin(player) { 41 -> end() 50 -> { val wearingRing = inEquipment(player, Items.RING_OF_THE_STAR_SPRITE_14652) - val dust = if (player.getInventory().getAmount(ShootingStarOptionHandler.STAR_DUST) > 200) 200 else player.getInventory().getAmount(ShootingStarOptionHandler.STAR_DUST) - if (player.getInventory().remove(Item(ShootingStarOptionHandler.STAR_DUST, dust))) { + val dust = if (player.getInventory().getAmount(ShootingStarPlugin.STAR_DUST) > 200) 200 else player.getInventory().getAmount(ShootingStarPlugin.STAR_DUST) + if (player.getInventory().remove(Item(ShootingStarPlugin.STAR_DUST, dust))) { val cosmicRunes = (Math.ceil(0.76 * dust) * AMPLIFIER).toInt() val astralRunes = (Math.ceil(0.26 * dust) * AMPLIFIER).toInt() val goldOre = (Math.ceil(0.1 * dust) * AMPLIFIER).toInt() diff --git a/Server/src/main/kotlin/rs09/game/content/jobs/WorkForInteractionListener.kt b/Server/src/main/kotlin/rs09/game/content/jobs/WorkForInteractionListener.kt index 3b3d8d6f0..d40c88e54 100644 --- a/Server/src/main/kotlin/rs09/game/content/jobs/WorkForInteractionListener.kt +++ b/Server/src/main/kotlin/rs09/game/content/jobs/WorkForInteractionListener.kt @@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit * Handles the work-for actions for the NPCs * @author Ceikry */ -class WorkForInteractionListener : InteractionListener(), LoginListener { +class WorkForInteractionListener : InteractionListener, LoginListener { val possibleWeaponLooks = arrayListOf( Items.BRONZE_SCIMITAR_1321, Items.STEEL_SCIMITAR_1325, diff --git a/Server/src/main/kotlin/rs09/game/content/quest/free/dragonslayer/DSEquipListeners.kt b/Server/src/main/kotlin/rs09/game/content/quest/free/dragonslayer/DSEquipListeners.kt index 78cd02f23..55e1fed93 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/free/dragonslayer/DSEquipListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/free/dragonslayer/DSEquipListeners.kt @@ -4,7 +4,7 @@ import api.* import org.rs09.consts.Items import rs09.game.interaction.InteractionListener -class DSEquipListeners : InteractionListener() { +class DSEquipListeners : InteractionListener { private val restrictedItems = intArrayOf( Items.RUNE_PLATEBODY_1127, diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/familycrest/JohnathonAntiPoisonInteraction.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/familycrest/JohnathonAntiPoisonInteraction.kt index 4af81e3db..9476bc3b1 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/familycrest/JohnathonAntiPoisonInteraction.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/familycrest/JohnathonAntiPoisonInteraction.kt @@ -6,7 +6,7 @@ import org.rs09.consts.Items import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener -class JohnathonAntiPosionInteraction: InteractionListener() { +class JohnathonAntiPosionInteraction: InteractionListener { override fun defineListeners() { val poisons = intArrayOf(Items.ANTIPOISON4_2446, Items.ANTIPOISON3_175, Items.ANTIPOISON2_177, Items.ANTIPOISON1_179) diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/familycrest/WitchavenLeverInteraction.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/familycrest/WitchavenLeverInteraction.kt index c74423672..4973bc451 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/familycrest/WitchavenLeverInteraction.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/familycrest/WitchavenLeverInteraction.kt @@ -32,7 +32,7 @@ fun doDoor(player: Player, scenery: Scenery) { } -class WitchavenLeverInteraction : InteractionListener() { +class WitchavenLeverInteraction : InteractionListener { val DOWN_ANIMATION = Animation(2140) val UP_ANIMATION = Animation(2139) diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/BrotherCedricNPC.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/BrotherCedricNPC.kt index 73d322a38..f7325df2a 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/BrotherCedricNPC.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/BrotherCedricNPC.kt @@ -109,7 +109,7 @@ class BrotherCedricDialogue : DialogueFile() { * Handles BrotherCedricListener to launch the dialogue * @author Kya */ -class BrotherCedricListener : InteractionListener() { +class BrotherCedricListener : InteractionListener { override fun defineListeners() { on(NPCs.BROTHER_CEDRIC_280, NPC, "talk-to"){ player, _ -> player.dialogueInterpreter.open(BrotherCedricDialogue(), NPC(NPCs.BROTHER_CEDRIC_280)) diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/BrotherOmadNPC.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/BrotherOmadNPC.kt index ac1856615..2487cbf4f 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/BrotherOmadNPC.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/BrotherOmadNPC.kt @@ -205,7 +205,7 @@ class BrotherOmadDialogue : DialogueFile() { * Handles BrotherCedricListener to launch the dialogue * @author Kya */ -class BrotherOmadListener : InteractionListener() { +class BrotherOmadListener : InteractionListener { override fun defineListeners() { on(NPCs.BROTHER_OMAD_279, NPC, "talk-to"){ player, _ -> player.dialogueInterpreter.open(BrotherOmadDialogue(), NPC(NPCs.BROTHER_OMAD_279)) diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/MonasteryMonkNPC.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/MonasteryMonkNPC.kt index ce26756b6..e4d94c83a 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/MonasteryMonkNPC.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/monksfriend/MonasteryMonkNPC.kt @@ -34,7 +34,7 @@ class MonasteryMonkDialogue : DialogueFile() { * Handles BrotherCedricListener to launch the dialogue * @author Kya */ -class MonasteryMonkListener : InteractionListener() { +class MonasteryMonkListener : InteractionListener { override fun defineListeners() { on(NPCs.MONK_281, NPC, "talk-to"){ player, _ -> player.dialogueInterpreter.open(MonasteryMonkDialogue(), NPC(NPCs.MONK_281)) diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/naturespirit/NSListeners.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/naturespirit/NSListeners.kt index 971d04a4a..0f9cc96a0 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/naturespirit/NSListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/naturespirit/NSListeners.kt @@ -14,13 +14,14 @@ import org.rs09.consts.Items import org.rs09.consts.NPCs import rs09.game.content.dialogue.DialogueFile import rs09.game.content.global.action.PickupHandler +import rs09.game.content.global.shops.Shops import rs09.game.interaction.InteractionListener import rs09.game.node.entity.npc.other.MortMyreGhastNPC import rs09.game.system.SystemLogger import rs09.game.system.config.ShopParser import rs09.tools.END_DIALOGUE -class NSListeners : InteractionListener() { +class NSListeners : InteractionListener { val GROTTO_TREE = 3517 val GROTTO_ENTRANCE = 3516 @@ -101,7 +102,7 @@ class NSListeners : InteractionListener() { on(WISHING_WELL, SCENERY, "make-wish"){player, node -> if(player.questRepository.isComplete("Nature Spirit") && player.questRepository.isComplete("Wolf Whistle")) - ShopParser.openUid(player, 241) + Shops.openId(player, 241) else sendDialogue(player, "You can't do that yet.") diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/HunterTalismanListener.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/HunterTalismanListener.kt index a52a0d5ec..15ff19164 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/HunterTalismanListener.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/HunterTalismanListener.kt @@ -10,7 +10,7 @@ import rs09.game.world.GameWorld.Pulser import kotlin.math.abs import kotlin.math.atan2 -class HunterTalismanListener : InteractionListener() { +class HunterTalismanListener : InteractionListener { val TALISMAN = Items.HUNTERS_TALISMAN_3696 diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/SeerLockInterfaceListener.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/SeerLockInterfaceListener.kt index 04ee4eb96..231266e68 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/SeerLockInterfaceListener.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/SeerLockInterfaceListener.kt @@ -4,9 +4,9 @@ import api.sendMessage import core.game.container.access.BitregisterAssembler import rs09.game.interaction.InterfaceListener -class SeerLockInterfaceListener : InterfaceListener() { +class SeerLockInterfaceListener : InterfaceListener { - override fun defineListeners() { + override fun defineInterfaceListeners() { val LETTERONEBACK = 39 val LETTERONEFORWARD = 40 val LETTERTWOBACK = 35 diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/SeersHouseListeners.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/SeersHouseListeners.kt index 4a78dd024..847115c80 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/SeersHouseListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/SeersHouseListeners.kt @@ -16,7 +16,7 @@ import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InteractionListener import rs09.tools.stringtools.RED -class SeersHouseListeners : InteractionListener() { +class SeersHouseListeners : InteractionListener { val WESTDOOR = 4165 val EASTDOOR = 4166 diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/TFTInteractionListeners.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/TFTInteractionListeners.kt index 883141fa8..9059824a2 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/TFTInteractionListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/thefremenniktrials/TFTInteractionListeners.kt @@ -30,7 +30,7 @@ import rs09.game.system.config.ItemConfigParser import rs09.game.world.GameWorld import rs09.game.world.GameWorld.Pulser -class TFTInteractionListeners : InteractionListener(){ +class TFTInteractionListeners : InteractionListener{ val BEER = Items.BEER_1917 val WORKER = NPCs.COUNCIL_WORKMAN_1287 diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/thelostcity/DramenTreeListener.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/thelostcity/DramenTreeListener.kt index 5b920e067..a631ee612 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/thelostcity/DramenTreeListener.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/thelostcity/DramenTreeListener.kt @@ -7,7 +7,7 @@ import core.game.node.entity.skill.gather.SkillingTool import core.game.world.map.Location import rs09.game.interaction.InteractionListener -class DramenTreeListener : InteractionListener() { +class DramenTreeListener : InteractionListener { val DRAMEN_TREE = 1292 diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/thelosttribe/PickpocketSigmund.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/thelosttribe/PickpocketSigmund.kt index 01fe466b3..d4da27d6b 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/thelosttribe/PickpocketSigmund.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/thelosttribe/PickpocketSigmund.kt @@ -13,7 +13,7 @@ import rs09.game.world.GameWorld * handles pickpocketing sigmund during the lost tribe quest * @author Ceikry */ -class PickpocketSigmund : InteractionListener(){ +class PickpocketSigmund : InteractionListener{ val SIGMUND = NPCs.SIGMUND_2082 override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/tribaltotem/TTDoorCodeInterfaceListener.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/tribaltotem/TTDoorCodeInterfaceListener.kt index da9503696..2b041fc58 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/tribaltotem/TTDoorCodeInterfaceListener.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/tribaltotem/TTDoorCodeInterfaceListener.kt @@ -6,9 +6,9 @@ import api.setInterfaceText import core.game.world.map.Location import rs09.game.interaction.InterfaceListener -class TTDoorCodeInterfaceListener : InterfaceListener() { +class TTDoorCodeInterfaceListener : InterfaceListener { - override fun defineListeners() { + override fun defineInterfaceListeners() { val LETTERONEBACK = 10 val LETTERONEFORWARD = 11 val LETTERTWOBACK = 12 diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/tribaltotem/TribalTotemListeners.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/tribaltotem/TribalTotemListeners.kt index 064132275..cf5325ae6 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/tribaltotem/TribalTotemListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/tribaltotem/TribalTotemListeners.kt @@ -10,7 +10,7 @@ import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import rs09.game.interaction.InteractionListener -class TribalTotemListeners : InteractionListener(){ +class TribalTotemListeners : InteractionListener{ val frontDoor = 2706 val wizCrate = 2707 diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/waterfall/WaterfallListeners.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/waterfall/WaterfallListeners.kt index a2d187a89..9b7ea6c19 100644 --- a/Server/src/main/kotlin/rs09/game/content/quest/members/waterfall/WaterfallListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/waterfall/WaterfallListeners.kt @@ -4,7 +4,7 @@ import core.game.world.map.Location import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener -class WaterfallListeners : InteractionListener(){ +class WaterfallListeners : InteractionListener{ val HUDON = NPCs.HUDON_305 override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialListeners.kt b/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialListeners.kt index 5fde2e1b2..57008405e 100644 --- a/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialListeners.kt +++ b/Server/src/main/kotlin/rs09/game/content/tutorial/TutorialListeners.kt @@ -13,7 +13,7 @@ import rs09.game.interaction.InteractionListener * Handles tutorial-specific node interactions * @author Ceikry */ -class TutorialListeners : InteractionListener() { +class TutorialListeners : InteractionListener { val GUIDE_HOUSE_DOOR = 3014 val COOKS_DOOR = 3017 val COOKS_EXIT = 3018 diff --git a/Server/src/main/kotlin/rs09/game/content/zone/FarmingPatchZone.kt b/Server/src/main/kotlin/rs09/game/content/zone/FarmingPatchZone.kt index 9d97fc2fb..92ac0c0a7 100644 --- a/Server/src/main/kotlin/rs09/game/content/zone/FarmingPatchZone.kt +++ b/Server/src/main/kotlin/rs09/game/content/zone/FarmingPatchZone.kt @@ -6,75 +6,52 @@ import core.game.node.entity.Entity import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills -import core.game.system.task.Pulse -import core.game.world.map.zone.MapZone import core.game.world.map.zone.ZoneBorders -import core.game.world.map.zone.ZoneBuilder -import core.plugin.Initializable -import core.plugin.Plugin import org.rs09.consts.NPCs import rs09.game.content.dialogue.DialogueFile -import rs09.tools.secondsToTicks -import java.util.concurrent.TimeUnit -@Initializable -class FarmingPatchZone : MapZone("farming patch", true), Plugin { +class FarmingPatchZone : MapArea, TickListener { + private val playersInZone = hashMapOf() - val playersInZone = hashMapOf() - - override fun configure() { - registerRegion(12083) - registerRegion(10548) - register(ZoneBorders(3594,3521,3608,3532)) - submitWorldPulse(zonePulse) + override fun defineAreaBorders(): Array { + return arrayOf( + getRegionBorders(12083), + getRegionBorders(10548), + ZoneBorders(3594,3521,3608,3532) + ) } - override fun newInstance(arg: Any?): Plugin { - ZoneBuilder.configure(this) - return this - } - - override fun fireEvent(identifier: String?, vararg args: Any?): Any { - return Unit - } - - override fun enter(e: Entity?): Boolean { - if(e is Player && playersInZone[e] == null && getStatLevel(e, Skills.FARMING) <= 15) { - playersInZone[e] = 0 + override fun areaEnter(entity: Entity) { + if(entity is Player && playersInZone[entity] == null && getStatLevel(entity, Skills.FARMING) <= 15) { + playersInZone[entity] = 0 } - return super.enter(e) } - override fun leave(e: Entity?, logout: Boolean): Boolean { - if(e is Player){ - playersInZone.remove(e) - } - return super.enter(e) + override fun areaLeave(entity: Entity, logout: Boolean) { + if(entity is Player) + playersInZone.remove(entity) } - val zonePulse = object : Pulse(){ - override fun pulse(): Boolean { - playersInZone.toList().forEach { (player, ticks) -> - if(ticks == secondsToTicks(TimeUnit.MINUTES.toSeconds(5).toInt())){ - val npc = NPC(NPCs.GITHAN_7122) - npc.location = player.location - npc.init() - npc.moveStep() - npc.face(player) - openDialogue(player, SpiritDialogue(true), npc) - } else if (ticks == secondsToTicks(TimeUnit.MINUTES.toSeconds(10).toInt())){ - val npc = NPC(NPCs.GITHAN_7122) - npc.location = player.location - npc.init() - npc.moveStep() - npc.face(player) - openDialogue(player, SpiritDialogue(false), npc) - playersInZone.remove(player) - } - - playersInZone[player] = ticks + 1 + override fun tick() { + playersInZone.toList().forEach { (player, ticks) -> + if(ticks == 500){ + val npc = NPC(NPCs.GITHAN_7122) + npc.location = player.location + npc.init() + npc.moveStep() + npc.face(player) + openDialogue(player, SpiritDialogue(true), npc) + } else if (ticks == 1000){ + val npc = NPC(NPCs.GITHAN_7122) + npc.location = player.location + npc.init() + npc.moveStep() + npc.face(player) + openDialogue(player, SpiritDialogue(false), npc) + playersInZone.remove(player) } - return false + + playersInZone[player] = ticks + 1 } } @@ -94,5 +71,4 @@ class FarmingPatchZone : MapZone("farming patch", true), Plugin { poofClear(npc ?: return) } } - } \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/content/zone/YanilleAgilityDungeon.kt b/Server/src/main/kotlin/rs09/game/content/zone/YanilleAgilityDungeon.kt index c8255839d..2a6d955ca 100644 --- a/Server/src/main/kotlin/rs09/game/content/zone/YanilleAgilityDungeon.kt +++ b/Server/src/main/kotlin/rs09/game/content/zone/YanilleAgilityDungeon.kt @@ -34,7 +34,7 @@ import core.tools.RandomFunction */ val SINISTER_CHEST_HERBS = arrayOf(Item(205, 2), Item(207, 3), Item(209), Item(211), Item(213), Item(219)) -public class YanilleAgilityDungeonListeners : InteractionListener() { +public class YanilleAgilityDungeonListeners : InteractionListener { override fun defineListeners() { ZoneBuilder.configure(YanilleAgilityDungeon()); diff --git a/Server/src/main/kotlin/rs09/game/content/zone/keldagrim/OrdanDialogue.kt b/Server/src/main/kotlin/rs09/game/content/zone/keldagrim/OrdanDialogue.kt index 891dbc56c..b13af8880 100644 --- a/Server/src/main/kotlin/rs09/game/content/zone/keldagrim/OrdanDialogue.kt +++ b/Server/src/main/kotlin/rs09/game/content/zone/keldagrim/OrdanDialogue.kt @@ -50,7 +50,7 @@ class OrdanDialogue(player: Player? = null) : DialoguePlugin(player) { * just comment those options out if you don't want em * aka "WOW I CAN'T BELIEVE IT'S ALL CONDITIONALS*/ - class OrdanUnnoteListener : InteractionListener() { + class OrdanUnnoteListener : InteractionListener { val notedOre = intArrayOf( Items.IRON_ORE_441, Items.COPPER_ORE_437, diff --git a/Server/src/main/kotlin/rs09/game/content/zone/phasmatys/bonegrinder/BoneGrinderListener.kt b/Server/src/main/kotlin/rs09/game/content/zone/phasmatys/bonegrinder/BoneGrinderListener.kt index afdeb3ac5..1bc75404b 100644 --- a/Server/src/main/kotlin/rs09/game/content/zone/phasmatys/bonegrinder/BoneGrinderListener.kt +++ b/Server/src/main/kotlin/rs09/game/content/zone/phasmatys/bonegrinder/BoneGrinderListener.kt @@ -24,7 +24,7 @@ private val FILL_ANIM = Animation(1649) private val WIND_ANIM = Animation(1648) private val SCOOP_ANIM = Animation(1650) -class BoneGrinderListener : InteractionListener() { +class BoneGrinderListener : InteractionListener { private val boneIDs = Bones.values().map { it.itemId }.toIntArray() diff --git a/Server/src/main/kotlin/rs09/game/ge/GrandExchangeRecords.kt b/Server/src/main/kotlin/rs09/game/ge/GrandExchangeRecords.kt index 261f9dd13..2a8c43471 100644 --- a/Server/src/main/kotlin/rs09/game/ge/GrandExchangeRecords.kt +++ b/Server/src/main/kotlin/rs09/game/ge/GrandExchangeRecords.kt @@ -2,34 +2,13 @@ package rs09.game.ge import api.* import core.cache.def.impl.ItemDefinition -import core.game.component.CloseEvent import core.game.component.Component -import core.game.component.InterfaceType -import core.game.container.Container -import core.game.container.ContainerEvent -import core.game.container.ContainerListener -import core.game.container.access.BitregisterAssembler -import core.game.container.access.InterfaceContainer -import core.game.ge.GEItemSet -import core.game.ge.GrandExchangeDatabase -import core.game.ge.GrandExchangeEntry import core.game.ge.OfferState import core.game.node.entity.player.Player -import core.game.node.entity.player.link.audio.Audio -import core.game.node.item.Item -import core.game.system.monitor.PlayerMonitor -import core.net.packet.PacketRepository -import core.net.packet.context.ConfigContext -import core.net.packet.context.ContainerContext -import core.net.packet.out.Config -import core.net.packet.out.ContainerPacket import org.json.simple.JSONArray import org.json.simple.JSONObject import org.rs09.consts.Components -import org.rs09.consts.Items -import rs09.game.ai.AIPlayer import rs09.game.system.SystemLogger -import java.text.DecimalFormat import java.text.NumberFormat import java.util.* @@ -98,12 +77,12 @@ class GrandExchangeRecords(private val player: Player? = null) : PersistPlayer, return } player.interfaceManager.openComponent(Components.STOCKCOLLECT_109) - player.packetDispatch.sendAccessMask(6, 18, 109, 0, 2) - player.packetDispatch.sendAccessMask(6, 23, 109, 0, 2) - player.packetDispatch.sendAccessMask(6, 28, 109, 0, 2) - player.packetDispatch.sendAccessMask(6, 36, 109, 0, 2) - player.packetDispatch.sendAccessMask(6, 44, 109, 0, 2) - player.packetDispatch.sendAccessMask(6, 52, 109, 0, 2) + player.packetDispatch.sendIfaceSettings(6, 18, 109, 0, 2) + player.packetDispatch.sendIfaceSettings(6, 23, 109, 0, 2) + player.packetDispatch.sendIfaceSettings(6, 28, 109, 0, 2) + player.packetDispatch.sendIfaceSettings(6, 36, 109, 0, 2) + player.packetDispatch.sendIfaceSettings(6, 44, 109, 0, 2) + player.packetDispatch.sendIfaceSettings(6, 52, 109, 0, 2) visualizeRecords() } diff --git a/Server/src/main/kotlin/rs09/game/interaction/CorporealBeastWarningInterface.kt b/Server/src/main/kotlin/rs09/game/interaction/CorporealBeastWarningInterface.kt index 4772e322a..c259ede92 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/CorporealBeastWarningInterface.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/CorporealBeastWarningInterface.kt @@ -8,11 +8,11 @@ import rs09.game.world.GameWorld * Handles the corporeal beast warning interface * @author Ceikry */ -class CorporealBeastWarningInterface : InterfaceListener(){ +class CorporealBeastWarningInterface : InterfaceListener{ val COMPONENT_ID = 650 - override fun defineListeners() { + override fun defineInterfaceListeners() { on(COMPONENT_ID,17){player,component,_,_,_,_ -> if(player.getAttribute("corp-beast-cave-delay",0) <= GameWorld.ticks) { player.properties.teleportLocation = player.location.transform(4, 0, 0).also { close(player,component) } diff --git a/Server/src/main/kotlin/rs09/game/interaction/InteractionListener.kt b/Server/src/main/kotlin/rs09/game/interaction/InteractionListener.kt index 76113bef4..869f9ba7f 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/InteractionListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/InteractionListener.kt @@ -1,17 +1,21 @@ package rs09.game.interaction +import api.ContentInterface import core.game.node.Node import core.game.node.entity.Entity import core.game.node.entity.player.Player import core.game.world.map.Location -abstract class InteractionListener : Listener{ - companion object { - val ITEM = 0 - val SCENERY = 1 - val NPC = 2 - val GROUNDITEM = 3 - } +interface InteractionListener : ContentInterface{ + val ITEM: Int + get() = 0 + val SCENERY: Int + get() = 1 + val NPC: Int + get() = 2 + val GROUNDITEM: Int + get() = 3 + fun on(id: Int, type: Int, vararg option: String,handler: (player: Player, node: Node) -> Boolean){ InteractionListeners.add(id,type,option,handler) } @@ -65,4 +69,14 @@ abstract class InteractionListener : Listener{ fun onDig(location: Location,method: (player: Player) -> Unit){ SpadeDigListener.registerListener(location,method) } + + fun defineListeners() + + companion object + { + val ITEM = 0 + val SCENERY = 1 + val NPC = 2 + val GROUNDITEM = 3 + } } diff --git a/Server/src/main/kotlin/rs09/game/interaction/InterfaceListener.kt b/Server/src/main/kotlin/rs09/game/interaction/InterfaceListener.kt index b7f38e092..f571de6a8 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/InterfaceListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/InterfaceListener.kt @@ -1,9 +1,17 @@ package rs09.game.interaction +import api.ContentInterface import core.game.component.Component import core.game.node.entity.player.Player -abstract class InterfaceListener : Listener { +/** + * An interface for writing content that allows the class to handle game interface interactions + * + * Interactions should be defined in the required [defineInterfaceListeners] method. + */ +interface InterfaceListener : ContentInterface { + fun defineInterfaceListeners() + fun on(componentID: Int, buttonID: Int, handler: (player: Player, component: Component, opcode: Int, buttonID: Int, slot: Int, itemID: Int) -> Boolean){ InterfaceListeners.add(componentID,buttonID,handler) } diff --git a/Server/src/main/kotlin/rs09/game/interaction/Listener.kt b/Server/src/main/kotlin/rs09/game/interaction/Listener.kt index c576a2f3f..acb46a58b 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/Listener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/Listener.kt @@ -3,8 +3,9 @@ package rs09.game.interaction import api.StartupListener interface Listener : StartupListener { - fun defineListeners() override fun startup() { defineListeners() } + + fun defineListeners() } \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/interaction/inter/CreditShopInterface.kt b/Server/src/main/kotlin/rs09/game/interaction/inter/CreditShopInterface.kt index 781c5c87c..9ecf360ec 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/inter/CreditShopInterface.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/inter/CreditShopInterface.kt @@ -7,12 +7,12 @@ import org.rs09.consts.Components import org.rs09.consts.Items import rs09.game.interaction.InterfaceListener -class CreditShopInterface : InterfaceListener() { +class CreditShopInterface : InterfaceListener { val CREDIT_SHOP = Components.CREDIT_SHOP val TEXT_CHILD = 39 - override fun defineListeners() { + override fun defineInterfaceListeners() { on(CREDIT_SHOP){player, component, opcode, buttonID, slot, itemID -> val item = getItem(buttonID) diff --git a/Server/src/main/kotlin/rs09/game/interaction/inter/FairyRingInterface.kt b/Server/src/main/kotlin/rs09/game/interaction/inter/FairyRingInterface.kt index 800217ab5..4bc6945c7 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/inter/FairyRingInterface.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/inter/FairyRingInterface.kt @@ -21,12 +21,12 @@ val RING_3 = arrayOf('p','s','r','q') * Handles the fairy ring interface * @author Ceikry */ -class FairyRingInterface : InterfaceListener(){ +class FairyRingInterface : InterfaceListener{ val RINGS = 734 val TRAVEL_LOG = 735 - override fun defineListeners() { + override fun defineInterfaceListeners() { onOpen(RINGS){player, _ -> player.interfaceManager.openSingleTab(Component(TRAVEL_LOG)) diff --git a/Server/src/main/kotlin/rs09/game/interaction/inter/MainGameInterface.kt b/Server/src/main/kotlin/rs09/game/interaction/inter/MainGameInterface.kt index 5a8536884..5b8a6cbaf 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/inter/MainGameInterface.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/inter/MainGameInterface.kt @@ -11,14 +11,14 @@ import org.rs09.consts.Components import rs09.game.interaction.InterfaceListener import rs09.game.world.GameWorld.settings -class MainGameInterface : InterfaceListener() { +class MainGameInterface : InterfaceListener { val TOPLEVEL = Components.TOPLEVEL_548 val TOPLEVEL_FS = Components.TOPLEVEL_FULLSCREEN_746 val RUN_BUTTON = Components.TOPSTAT_RUN_750 val FILTER_BUTTONS = Components.FILTERBUTTONS_751 val REPORT_ABUSE = Components.SNAPSHOT_MAIN_553 - override fun defineListeners() { + override fun defineInterfaceListeners() { on(FILTER_BUTTONS){player, _, _, buttonID, _, _ -> if(buttonID == 27) openReport(player) @@ -102,6 +102,7 @@ class MainGameInterface : InterfaceListener() { player.packetDispatch.sendMessage("You can't do this right now.") return } + player.interfaceManager.close() player.interfaceManager.openWindowsPane(Component(755)) val posHash = player.location.z shl 28 or (player.location.x shl 14) or player.location.y player.packetDispatch.sendScriptConfigs(622, posHash, "", 0) diff --git a/Server/src/main/kotlin/rs09/game/interaction/inter/NPCContactInterface.kt b/Server/src/main/kotlin/rs09/game/interaction/inter/NPCContactInterface.kt index f7c1d8ef5..7f49bbe5f 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/inter/NPCContactInterface.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/inter/NPCContactInterface.kt @@ -7,7 +7,7 @@ import org.rs09.consts.NPCs import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InterfaceListener -class NPCContactInterface : InterfaceListener() { +class NPCContactInterface : InterfaceListener { val contactNPCs = arrayOf(NPCs.HONEST_JIMMY_4362, NPCs.BERT_3108, NPCs.ADVISOR_GHRIM_1375, NPCs.TURAEL_8273, NPCs.LANTHUS_1526, NPCs.SUMONA_7780, NPCs.MAZCHNA_8274, NPCs.DURADEL_8275, NPCs.VANNAKA_1597, NPCs.DARK_MAGE_2262, NPCs.CHAELDAR_1598, NPCs.CYRISUS_432, NPCs.LARRY_5424) val DialogueFiles = arrayOf( /*TODO("Honest Jimmy"), @@ -25,7 +25,7 @@ class NPCContactInterface : InterfaceListener() { TODO("Larry")*/ ) val INTER = 429 - override fun defineListeners() { + override fun defineInterfaceListeners() { //Remove a bunch of the buttons/heads so that people don't //waste runes on spells that aren't implemented diff --git a/Server/src/main/kotlin/rs09/game/interaction/inter/RulesAndInfo.kt b/Server/src/main/kotlin/rs09/game/interaction/inter/RulesAndInfo.kt index 7eeac8bdf..6b7e81ad6 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/inter/RulesAndInfo.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/inter/RulesAndInfo.kt @@ -46,9 +46,9 @@ object RulesAndInfo { } } -class RulesListener : InterfaceListener() +class RulesListener : InterfaceListener { - override fun defineListeners() { + override fun defineInterfaceListeners() { onClose(384){player, _ -> if(!getAttribute(player, "rules:confirmed", false)) runTask(player, 1) { RulesAndInfo.openFor(player); sendDialogue(player, "Please read the rules.") } diff --git a/Server/src/main/kotlin/rs09/game/interaction/inter/SilverInterface.kt b/Server/src/main/kotlin/rs09/game/interaction/inter/SilverInterface.kt index 451f8f484..0f5026d75 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/inter/SilverInterface.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/inter/SilverInterface.kt @@ -11,12 +11,12 @@ import org.rs09.consts.Items import rs09.game.interaction.InteractionListener import rs09.game.interaction.InterfaceListener -class SilverInterface : InterfaceListener() { +class SilverInterface : InterfaceListener { val IFACE = Components.CRAFTING_SILVER_CASTING_438 val ANIM = getAnimation(899) - override fun defineListeners() { + override fun defineInterfaceListeners() { onOpen(IFACE){player, _ -> sendItemOnInterface(player, IFACE, 17, 1718) sendItemOnInterface(player, IFACE, 24, 1724) @@ -89,7 +89,7 @@ class SilverInterface : InterfaceListener() { } } -class SilverBarUseWith : InteractionListener() { +class SilverBarUseWith : InteractionListener { val FURNACES = intArrayOf(2966, 3044, 3294, 4304, 6189, 11009, 11010, 11666, 12100, 12809, 18497, 18525, 18526, 21879, 22721, 26814, 28433, 28434, 30021, 30510, 36956, 37651) override fun defineListeners() { onUseWith(SCENERY, Items.SILVER_BAR_2355, *FURNACES){ player, _, _ -> diff --git a/Server/src/main/kotlin/rs09/game/interaction/inter/TeleotherInterface.kt b/Server/src/main/kotlin/rs09/game/interaction/inter/TeleotherInterface.kt index 9c89627cc..53d2589e4 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/inter/TeleotherInterface.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/inter/TeleotherInterface.kt @@ -6,10 +6,10 @@ import core.game.world.update.flag.context.Graphics import org.rs09.consts.Components import rs09.game.interaction.InterfaceListener -class TeleotherInterface : InterfaceListener() { +class TeleotherInterface : InterfaceListener { val IFACE = Components.TELEPORT_OTHER_326 - override fun defineListeners() { + override fun defineInterfaceListeners() { on(IFACE){player, _, _, button, _, _ -> if(button == 5){ player.lock(2) diff --git a/Server/src/main/kotlin/rs09/game/interaction/inter/ge/ExchangeItemSets.kt b/Server/src/main/kotlin/rs09/game/interaction/inter/ge/ExchangeItemSets.kt index 3767b0916..16f307f3c 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/inter/ge/ExchangeItemSets.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/inter/ge/ExchangeItemSets.kt @@ -13,8 +13,8 @@ import core.game.node.entity.player.Player import org.rs09.consts.Components import rs09.game.interaction.InterfaceListener -class ExchangeItemSets : InterfaceListener() { - override fun defineListeners() { +class ExchangeItemSets : InterfaceListener { + override fun defineInterfaceListeners() { onOpen(Components.EXCHANGE_ITEMSETS_645) { player, _ -> val listener: InventoryListener setAttribute(player, "ge-listener", InventoryListener(player).also { listener = it }) diff --git a/Server/src/main/kotlin/rs09/game/interaction/inter/ge/StockMarket.kt b/Server/src/main/kotlin/rs09/game/interaction/inter/ge/StockMarket.kt index c5be8baf6..d5ee5b2d4 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/inter/ge/StockMarket.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/inter/ge/StockMarket.kt @@ -25,12 +25,12 @@ import rs09.game.system.SystemLogger * Handles the grand exchange interface (Stock Market) * @author Ceikry */ -class StockMarket : InterfaceListener() { - override fun defineListeners() { +class StockMarket : InterfaceListener { + override fun defineInterfaceListeners() { onOpen(Components.STOCKMARKET_105){player, _ -> player.packetDispatch.sendInterfaceConfig(105, 193, true) - player.packetDispatch.sendAccessMask(6, 211, 105, -1, -1) - player.packetDispatch.sendAccessMask(6, 209, 105, -1, -1) + player.packetDispatch.sendIfaceSettings(6, 211, 105, -1, -1) + player.packetDispatch.sendIfaceSettings(6, 209, 105, -1, -1) player.varpManager.get(1112).setVarbit(0, -1).send(player) return@onOpen true } diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/BraceletOfClayPlugin.kt b/Server/src/main/kotlin/rs09/game/interaction/item/BraceletOfClayPlugin.kt index 7090cebad..a6024728e 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/BraceletOfClayPlugin.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/BraceletOfClayPlugin.kt @@ -8,7 +8,7 @@ import rs09.game.interaction.InteractionListener * Handles the bracelet of clay operate option. * @author Ceikry */ -class BraceletOfClayPlugin : InteractionListener() { +class BraceletOfClayPlugin : InteractionListener { override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/CadavaPotionListener.kt b/Server/src/main/kotlin/rs09/game/interaction/item/CadavaPotionListener.kt index 54a8b117e..38230812b 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/CadavaPotionListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/CadavaPotionListener.kt @@ -8,7 +8,7 @@ import rs09.game.interaction.InteractionListener * @author bushtail */ -class CadavaPotionListener : InteractionListener() { +class CadavaPotionListener : InteractionListener { var POTION = Items.CADAVA_POTION_756 diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/DrinkBlamishOilListener.kt b/Server/src/main/kotlin/rs09/game/interaction/item/DrinkBlamishOilListener.kt index 443b20f93..5b9df3f41 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/DrinkBlamishOilListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/DrinkBlamishOilListener.kt @@ -4,7 +4,7 @@ import api.* import org.rs09.consts.Items import rs09.game.interaction.InteractionListener -class DrinkBlamishOilListener : InteractionListener() { +class DrinkBlamishOilListener : InteractionListener { override fun defineListeners() { on(Items.BLAMISH_OIL_1582, ITEM, "drink"){player, _ -> diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/EnchantedJewelleryListener.kt b/Server/src/main/kotlin/rs09/game/interaction/item/EnchantedJewelleryListener.kt index f22c93e25..3c01e2780 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/EnchantedJewelleryListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/EnchantedJewelleryListener.kt @@ -9,7 +9,7 @@ import java.util.* * Listener for enchanted jewellery options * @author Ceikry */ -class EnchantedJewelleryListener : InteractionListener() { +class EnchantedJewelleryListener : InteractionListener { val IDs: IntArray init { diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/GodBookListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/item/GodBookListeners.kt index a92ae4090..c030b9b0a 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/GodBookListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/GodBookListeners.kt @@ -9,7 +9,7 @@ import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InteractionListener import rs09.tools.END_DIALOGUE -class GodBookListeners : InteractionListener() { +class GodBookListeners : InteractionListener { val GB_SARADOMIN = Items.HOLY_BOOK_3840 val GB_ZAMORAK = Items.UNHOLY_BOOK_3842 diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/GrandSeedPodHandler.kt b/Server/src/main/kotlin/rs09/game/interaction/item/GrandSeedPodHandler.kt index 9abb38463..cf314a495 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/GrandSeedPodHandler.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/GrandSeedPodHandler.kt @@ -30,7 +30,7 @@ private const val LAUNCH_ANIMATION = 4547 * Handles the grand tree pod options * @author Ceikry */ -class GrandSeedPodHandler : InteractionListener() { +class GrandSeedPodHandler : InteractionListener { override fun defineListeners() { on(Items.GRAND_SEED_POD_9469, ITEM, "squash", "launch"){player, _ -> diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/ImplingJarListener.kt b/Server/src/main/kotlin/rs09/game/interaction/item/ImplingJarListener.kt index c8099c25b..a9730319b 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/ImplingJarListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/ImplingJarListener.kt @@ -9,7 +9,7 @@ import rs09.game.content.global.WeightedItem import rs09.game.interaction.InteractionListener import rs09.game.system.SystemLogger -class ImplingJarListener : InteractionListener() { +class ImplingJarListener : InteractionListener { val JARS = ImplingLoot.values().map { it.jarId }.toIntArray() diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/ItemQuestRequirementListener.kt b/Server/src/main/kotlin/rs09/game/interaction/item/ItemQuestRequirementListener.kt index 4828ad515..25ead72bc 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/ItemQuestRequirementListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/ItemQuestRequirementListener.kt @@ -6,7 +6,7 @@ import org.rs09.consts.Items import rs09.game.interaction.InteractionListener import rs09.game.interaction.InteractionListeners.run -class ItemQuestRequirementListener : InteractionListener() { +class ItemQuestRequirementListener : InteractionListener { private val fremennikIslesEquipment = intArrayOf(Items.HELM_OF_NEITIZNOT_10828, Items.HELM_OF_NEITIZNOT_E_12680, Items.HELM_OF_NEITIZNOT_CHARGED_12681) private val fremennikTrialsEquipment = intArrayOf(Items.BERSERKER_HELM_3751, Items.BERSERKER_HELM_13408, Items.BERSERKER_HELM_E_12674, Items.BERSERKER_HELM_CHARGED_12675, diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/StaffOfTheRaven.kt b/Server/src/main/kotlin/rs09/game/interaction/item/StaffOfTheRaven.kt index 397da4e1a..1ffcc15a9 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/StaffOfTheRaven.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/StaffOfTheRaven.kt @@ -11,7 +11,7 @@ import rs09.tools.END_DIALOGUE /** * Handles the Staff of the Raven's (2021 Hween Reward) Recolor Transformation */ -class StaffOfTheRaven : InteractionListener() { +class StaffOfTheRaven : InteractionListener { val ids = intArrayOf(14654, 14655, 14656) override fun defineListeners() { on(ids, ITEM, "recolor", "operate"){player, node -> diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/StarRingListener.kt b/Server/src/main/kotlin/rs09/game/interaction/item/StarRingListener.kt deleted file mode 100644 index d654b6f09..000000000 --- a/Server/src/main/kotlin/rs09/game/interaction/item/StarRingListener.kt +++ /dev/null @@ -1,94 +0,0 @@ -package rs09.game.interaction.item - -import api.* -import core.game.node.entity.player.Player -import core.game.node.entity.player.link.TeleportManager -import core.game.node.entity.skill.Skills -import core.game.world.map.Location -import org.json.simple.JSONObject -import org.rs09.consts.Items -import rs09.ServerStore -import rs09.ServerStore.Companion.getBoolean -import rs09.game.content.dialogue.DialogueFile -import rs09.game.content.global.worldevents.WorldEvents -import rs09.game.content.global.worldevents.shootingstar.ShootingStar -import rs09.game.content.global.worldevents.shootingstar.ShootingStarEvent -import rs09.game.interaction.InteractionListener -import java.util.concurrent.TimeUnit - -class StarRingListener : InteractionListener(){ - - val RING = Items.RING_OF_THE_STAR_SPRITE_14652 - - override fun defineListeners() { - on(RING, ITEM, "rub", "operate"){player, node -> - val star = WorldEvents.get("shooting-stars") as? ShootingStarEvent - - if(star == null) sendDialogue(player, "There is currently no active star.").also { return@on true } - - if(getStoreFile().getBoolean(player.username.toLowerCase())){ - sendDialogue(player, "The ring is still recharging.") - return@on true - } - - val condition: (Player) -> Boolean = when(star?.star!!.location.toLowerCase()){ - "canifis bank" -> { p -> p.questRepository.isComplete("Priest in Peril")} - "crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40) } - "south crandor mining site" -> {p -> p.questRepository.isComplete("Dragon Slayer")} - else -> {_ -> true} - } - - if(!condition.invoke(player) || player.skullManager.isWilderness){ - sendDialogue(player, "Magical forces prevent your teleportation.") - return@on true - } - - val shouldWarn = when(star.star.location){ - "North Edgeville mining site", - "Southern wilderness mine", - "Pirates' Hideout mine", - "Lava Maze mining site", - "Mage Arena bank" -> true - else -> false - } - - openDialogue(player, RingDialogue(shouldWarn, star.star)) - - return@on true - } - } - - internal class RingDialogue(val shouldWarn: Boolean, val star: ShootingStar) : DialogueFile(){ - override fun handle(componentID: Int, buttonID: Int) { - if(shouldWarn){ - when(stage) { - 0 -> dialogue("WARNING: That mining site is located in the wilderness.").also { stage++ } - 1 -> player!!.dialogueInterpreter.sendOptions("Continue?","Yes","No").also { stage++ } - 2 -> when(buttonID){ - 1 -> teleport(player!!, star).also { end() } - 2 -> end() - } - } - } else { - when(stage){ - 0 -> player!!.dialogueInterpreter.sendOptions("Teleport to the Star?", "Yes", "No").also { stage++ } - 1 -> when(buttonID){ - 1 -> teleport(player!!, star).also { end() } - 2 -> end() - } - } - } - } - - fun teleport(player: Player, star: ShootingStar){ - teleport(player, star.crash_locations[star.location]!!.transform(0, -1, 0), TeleportManager.TeleportType.MINIGAME) - getStoreFile()[player.username.toLowerCase()] = true - } - } - - companion object { - fun getStoreFile(): JSONObject { - return ServerStore.getArchive("daily-star-ring") - } - } -} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/ToyHorseyListener.kt b/Server/src/main/kotlin/rs09/game/interaction/item/ToyHorseyListener.kt index 6938257a2..97a677edc 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/ToyHorseyListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/ToyHorseyListener.kt @@ -11,7 +11,7 @@ import rs09.game.interaction.InteractionListener * Interaction listener for the Toy Horsey item * @author Woah */ -class ToyHorseListener : InteractionListener() { +class ToyHorseListener : InteractionListener { // Map of horse item ids to their correct emote val HORSEY_MAP = mapOf( diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/ToyListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/item/ToyListeners.kt index e1d364e99..b77eb943f 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/ToyListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/ToyListeners.kt @@ -6,7 +6,7 @@ import core.game.world.update.flag.context.Graphics import org.rs09.consts.Items import rs09.game.interaction.InteractionListener -class ToyListeners : InteractionListener() { +class ToyListeners : InteractionListener { companion object { val MARIONETTES = intArrayOf(Items.RED_MARIONETTE_6867, Items.GREEN_MARIONETTE_6866, Items.BLUE_MARIONETTE_6865) private val MARIONETTE_JUMP = Animation(3003) diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withitem/HaySackOnSpear.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/HaySackOnSpear.kt index ef31ceb08..5c6f2fe48 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withitem/HaySackOnSpear.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/HaySackOnSpear.kt @@ -5,7 +5,7 @@ import api.* import org.rs09.consts.Items import rs09.game.interaction.InteractionListener -class HaySackOnSpear : InteractionListener() { +class HaySackOnSpear : InteractionListener { val HAYSACK = Items.HAY_SACK_6057 val SPEAR = Items.BRONZE_SPEAR_1237 diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withitem/OilFishingRodListener.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/OilFishingRodListener.kt index 0fb70022e..9054c7136 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withitem/OilFishingRodListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/OilFishingRodListener.kt @@ -6,7 +6,7 @@ import core.game.world.update.flag.context.Animation import org.rs09.consts.Items import rs09.game.interaction.InteractionListener -class OilFishingRodListener : InteractionListener() { +class OilFishingRodListener : InteractionListener { override fun defineListeners() { onUseWith(ITEM, Items.BLAMISH_OIL_1582, Items.FISHING_ROD_307) {player, used, with -> player.pulseManager.run(object : Pulse() { diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withitem/PoisonedWeaponListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/PoisonedWeaponListeners.kt index d7209e2b3..06fed9836 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withitem/PoisonedWeaponListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/PoisonedWeaponListeners.kt @@ -7,7 +7,7 @@ import rs09.game.interaction.InteractionListener import kotlin.collections.toIntArray import kotlin.math.min -class PoisonedWeaponListeners : InteractionListener() { +class PoisonedWeaponListeners : InteractionListener { override fun defineListeners() { val poisons = intArrayOf(Items.WEAPON_POISON_187, Items.WEAPON_POISON_PLUS_5937, Items.WEAPON_POISON_PLUS_PLUS_5940) val poisonableItems = PoisonSets.itemMap.keys.toIntArray() diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withitem/TOTTHelmOnCape.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/TOTTHelmOnCape.kt index 7693542a5..b6af52e2a 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withitem/TOTTHelmOnCape.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/TOTTHelmOnCape.kt @@ -7,7 +7,7 @@ import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InteractionListener import rs09.tools.END_DIALOGUE -class TOTTHelmOnCape : InteractionListener() { +class TOTTHelmOnCape : InteractionListener { override fun defineListeners() { onUseWith(ITEM, Items.SLAYER_HELMET_13263, Items.SLAYER_CAPE_9786, Items.SLAYER_CAPET_9787){ player, used, with -> val alreadyHasHelm = getAttribute(player, "cape_perks:tott:helmet-stored", false) diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withitem/WatermelonOnSack.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/WatermelonOnSack.kt index 859a8509b..82117f1eb 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withitem/WatermelonOnSack.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/WatermelonOnSack.kt @@ -6,7 +6,7 @@ import core.game.node.entity.skill.Skills import org.rs09.consts.Items import rs09.game.interaction.InteractionListener -class WatermelonOnSack : InteractionListener() { +class WatermelonOnSack : InteractionListener { val SACK = Items.HAY_SACK_6058 val WATERMELON = Items.WATERMELON_5982 diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/ArchaeologicalExpertListener.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/ArchaeologicalExpertListener.kt index dfa9cd1d2..713d59d7e 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/ArchaeologicalExpertListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/ArchaeologicalExpertListener.kt @@ -7,7 +7,7 @@ import org.rs09.consts.NPCs import rs09.game.content.dialogue.region.examcentre.ArchaeologistcalExpertUsedOnDialogueFile import rs09.game.interaction.InteractionListener -open class ArchaeologicalExpertListener() : InteractionListener() { +open class ArchaeologicalExpertListener() : InteractionListener { val staff = Items.ANCIENT_STAFF_4675 val unidentifiedLiquid = Items.UNIDENTIFIED_LIQUID_702 val nitroglycerin = Items.NITROGLYCERIN_703 diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/BonesOnStrayDog.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/BonesOnStrayDog.kt index 0822c89c8..2188bedbe 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/BonesOnStrayDog.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/BonesOnStrayDog.kt @@ -8,7 +8,7 @@ import core.game.node.entity.player.link.diary.DiaryType import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener -class BonesOnStrayDog : InteractionListener() { +class BonesOnStrayDog : InteractionListener { override fun defineListeners() { val bones = Bones.array val dogs = intArrayOf(NPCs.STRAY_DOG_4766, NPCs.STRAY_DOG_4767, NPCs.STRAY_DOG_5917, NPCs.STRAY_DOG_5918) diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/CatOnArdougneCivilian.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/CatOnArdougneCivilian.kt index 181d91f14..db1383c41 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/CatOnArdougneCivilian.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/CatOnArdougneCivilian.kt @@ -6,7 +6,7 @@ import org.rs09.consts.Items import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener -class CatOnArdougneCivilian: InteractionListener() { +class CatOnArdougneCivilian: InteractionListener { private val civilians = intArrayOf( NPCs.CIVILIAN_785, diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/CiderOnForester.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/CiderOnForester.kt index 59cd17f8c..7ab4498e7 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/CiderOnForester.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/CiderOnForester.kt @@ -8,7 +8,7 @@ import org.rs09.consts.Items import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InteractionListener -class CiderOnForester : InteractionListener() { +class CiderOnForester : InteractionListener { override fun defineListeners() { val ids = intArrayOf(1,2,3,4,5) diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/GCItemOnCat.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/GCItemOnCat.kt index f1524b8d7..0e780e870 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/GCItemOnCat.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/GCItemOnCat.kt @@ -10,7 +10,7 @@ import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener import rs09.game.world.GameWorld.Pulser -class GCItemOnCat : InteractionListener() { +class GCItemOnCat : InteractionListener { override fun defineListeners() { val GERTCAT = "Gertrude's Cat" val BEND_DOWN = 827 diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/HatEasterEgg.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/HatEasterEgg.kt index d503b6aac..e95b939c9 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/HatEasterEgg.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/HatEasterEgg.kt @@ -9,7 +9,7 @@ import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InteractionListener val graphics = 482 -class HatEasterEgg : InteractionListener(){ +class HatEasterEgg : InteractionListener { val MACHINE = 20040 val WIZ_HAT = Items.WIZARD_HAT_579 diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/MistagEasterEgg.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/MistagEasterEgg.kt index ce131bc81..e9ac0d973 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/MistagEasterEgg.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/MistagEasterEgg.kt @@ -9,7 +9,7 @@ import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InteractionListener import rs09.tools.END_DIALOGUE -class MistagEasterEgg : InteractionListener() { +class MistagEasterEgg : InteractionListener { val DIAMOND = Items.DIAMOND_1601 val MISTAG = NPCs.MISTAG_2084 val ZANIK_RING = 14649 diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/PoisonChaliceOnKingArthur.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/PoisonChaliceOnKingArthur.kt index fbf80c323..58066c4b2 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/PoisonChaliceOnKingArthur.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/PoisonChaliceOnKingArthur.kt @@ -10,7 +10,7 @@ import org.rs09.consts.NPCs import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InteractionListener -class PoisonChaliceOnKingArthur : InteractionListener() { +class PoisonChaliceOnKingArthur : InteractionListener { override fun defineListeners() { onUseWith(NPC, Items.POISON_CHALICE_197, NPCs.KING_ARTHUR_251){player, used, with -> player.dialogueInterpreter.open(PoisonChaliceOnKingArthurDialogue(),with) diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/RopeOnLadyKeli.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/RopeOnLadyKeli.kt index a9a04823a..548ba5442 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/RopeOnLadyKeli.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/RopeOnLadyKeli.kt @@ -5,7 +5,7 @@ import org.rs09.consts.Items import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener -class RopeOnLadyKeli : InteractionListener() { +class RopeOnLadyKeli : InteractionListener { override fun defineListeners() { val PAR = "Prince Ali Rescue" diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/ZooknockListener.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/ZooknockListener.kt index c3318123a..63a5289fb 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/ZooknockListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withnpc/ZooknockListener.kt @@ -8,7 +8,7 @@ import rs09.game.content.dialogue.region.examcentre.ArchaeologistcalExpertUsedOn import rs09.game.content.dialogue.region.examcentre.ZooknockDialogueFile import rs09.game.interaction.InteractionListener -open class ZooknockListener() : InteractionListener() { +open class ZooknockListener() : InteractionListener { val goldBar = Items.GOLD_BAR_2357 val monkeyAmuletMould = Items.MAMULET_MOULD_4020 val monkeyDentures = Items.MONKEY_DENTURES_4006 diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/AmmoMouldOnFurnace.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/AmmoMouldOnFurnace.kt index 415ba1e06..863a4f6ef 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/AmmoMouldOnFurnace.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/AmmoMouldOnFurnace.kt @@ -12,7 +12,7 @@ import org.rs09.consts.Items import rs09.game.content.dialogue.SkillDialogueHandler import rs09.game.interaction.InteractionListener -class AmmoMouldOnFurnace : InteractionListener(){ +class AmmoMouldOnFurnace : InteractionListener{ private val furnaces = intArrayOf(4304, 6189, 11010, 11666, 12100, 12809, 18497, 26814, 30021, 30510, 36956, 37651) // abstract when smelting converted to kotlin private val levelRequirement = 35 diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/AxeOnTree.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/AxeOnTree.kt index e0ed9c070..07a1abe3c 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/AxeOnTree.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/AxeOnTree.kt @@ -8,7 +8,7 @@ import org.rs09.consts.Items import rs09.ServerConstants import rs09.game.interaction.InteractionListener -class AxeOnTree : InteractionListener(){ +class AxeOnTree : InteractionListener{ val axes = intArrayOf(Items.BRONZE_AXE_1351, Items.MITHRIL_AXE_1355, Items.IRON_AXE_1349, Items.BLACK_AXE_1361, Items.STEEL_AXE_1353, Items.ADAMANT_AXE_1357, Items.RUNE_AXE_1359, Items.DRAGON_AXE_6739, Items.INFERNO_ADZE_13661) val trees = WoodcuttingNode.values().map { it.id }.toIntArray() diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/CoalTrucksHandler.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/CoalTrucksHandler.kt index dfa6ab643..e4be0c19f 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/CoalTrucksHandler.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/CoalTrucksHandler.kt @@ -11,7 +11,7 @@ import java.util.* * Handles coal truck interactions * @author ceik */ -class CoalTruckInteractionListeners : InteractionListener() { +class CoalTruckInteractionListeners : InteractionListener { val SEERS_VILLAGE_COAL_TRUCK_2114 = 2114 val seersVillageTrucks = ZoneBorders(2690,3502,2699,3508) diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/FishEasterEgg.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/FishEasterEgg.kt index 6d90ae74a..db5cc1a23 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/FishEasterEgg.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/FishEasterEgg.kt @@ -5,7 +5,7 @@ import core.game.node.entity.skill.gather.woodcutting.WoodcuttingNode import org.rs09.consts.Items import rs09.game.interaction.InteractionListener -class FishEasterEgg : InteractionListener() { +class FishEasterEgg : InteractionListener { val TREE_IDs = WoodcuttingNode.values().map { it.id }.toIntArray() val fish = intArrayOf(Items.RAW_HERRING_345, Items.HERRING_347) diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/HatStand.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/HatStand.kt index 1e0a7f12f..a7f76b8f6 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/HatStand.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/HatStand.kt @@ -6,7 +6,7 @@ import core.cache.def.impl.ItemDefinition import rs09.game.interaction.InteractionListener import rs09.game.system.SystemLogger -class HatStand : InteractionListener() { +class HatStand : InteractionListener { val hats = ItemDefinition.getDefinitions().values.filter { it.getConfiguration("equipment_slot",0) == EquipmentSlot.HAT.ordinal }.map { it.id }.toIntArray() val hat_stand = 374 diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/SackOnHay.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/SackOnHay.kt index b716ef9a8..8297e0f79 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/SackOnHay.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/SackOnHay.kt @@ -5,7 +5,7 @@ import api.* import org.rs09.consts.Items import rs09.game.interaction.InteractionListener -class SackOnHay : InteractionListener() { +class SackOnHay : InteractionListener { val SACK = Items.EMPTY_SACK_5418 val HAY = intArrayOf(36892, 36894, 36896, 300, 34593, 298, 299) diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/WaterSourceListener.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/WaterSourceListener.kt index 6c0be65fc..e8733591f 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/item/withobject/WaterSourceListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/item/withobject/WaterSourceListener.kt @@ -11,7 +11,7 @@ import rs09.game.interaction.InteractionListener * Handles filling most water sources. * @author Ceikry */ -class WaterSourceListener : InteractionListener() { +class WaterSourceListener : InteractionListener { //this is ugly! private val waterSources = intArrayOf(21355, 16302, 6827, 11661, 24160, 34577, 15936, 15937, 15938, 23920, 35469, 24265, 153, 879, 880, 2864, 6232, 10436, 10437, 10827, 11007, 11759, 21764, 22973, 24161, 24214, 24265, 28662, 30223, 30820, 34579, 36781, 873, 874, 4063, 6151, 8699, 9143, 9684, 10175, 12279, 12974, 13563, 13564, 14868, 14917, 15678, 16704, 16705, 20358, 22715, 24112, 24314, 25729, 25929, 26966, 29105, 33458, 34082, 34411, 34496, 34547, 34566, 35762, 36971, 37154, 37155, 878, 884, 3264, 3305, 3359, 4004, 4005, 6097, 6249, 6549, 8747, 8927, 11793, 12201, 12897, 24166, 26945, 31359, 32023, 32024, 34576, 35671, 40063, 13561, 13563, 13559, 12089) diff --git a/Server/src/main/kotlin/rs09/game/interaction/npc/DecantListener.kt b/Server/src/main/kotlin/rs09/game/interaction/npc/DecantListener.kt index a633eccec..bffc1885f 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/npc/DecantListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/npc/DecantListener.kt @@ -8,7 +8,7 @@ import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InteractionListener import rs09.tools.END_DIALOGUE -class DecantListener : InteractionListener() { +class DecantListener : InteractionListener { override fun defineListeners() { on(NPC,"decant"){player, node -> diff --git a/Server/src/main/kotlin/rs09/game/interaction/npc/NPCDepositListener.kt b/Server/src/main/kotlin/rs09/game/interaction/npc/NPCDepositListener.kt index 8ba51e5e9..023584c53 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/npc/NPCDepositListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/npc/NPCDepositListener.kt @@ -9,7 +9,7 @@ import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener import rs09.tools.END_DIALOGUE -class NPCDepositListener : InteractionListener() { +class NPCDepositListener : InteractionListener { override fun defineListeners() { on(NPCs.PEER_THE_SEER_1288, NPC,"deposit") { player, _ -> diff --git a/Server/src/main/kotlin/rs09/game/interaction/npc/NPCTalkListener.kt b/Server/src/main/kotlin/rs09/game/interaction/npc/NPCTalkListener.kt index f57baf216..59beda1b9 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/npc/NPCTalkListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/npc/NPCTalkListener.kt @@ -13,7 +13,7 @@ import rs09.game.system.SystemLogger * Handles the NPC talk-to option. * @author Ceikry */ -class NPCTalkListener : InteractionListener() { +class NPCTalkListener : InteractionListener { val barCrawlNPCs = intArrayOf(733,848,735,739,737,738,731,568,3217,736,734) diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/DemonTauntHandler.kt b/Server/src/main/kotlin/rs09/game/interaction/object/DemonTauntHandler.kt index 8af5f7612..f7c8bdabf 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/DemonTauntHandler.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/DemonTauntHandler.kt @@ -11,7 +11,7 @@ import rs09.game.interaction.InteractionListener * @author afaroutdude / Ceikry */ private const val BARS = 37668 -class DemonTauntHandler : InteractionListener(){ +class DemonTauntHandler : InteractionListener{ override fun defineListeners() { on(BARS,SCENERY,"taunt-through"){ player, _ -> diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/EnchantedValleyListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/object/EnchantedValleyListeners.kt index 41beb3236..bf5124b4f 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/EnchantedValleyListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/EnchantedValleyListeners.kt @@ -7,7 +7,7 @@ import core.game.system.task.Pulse import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener -class EnchantedValleyListeners : InteractionListener() { +class EnchantedValleyListeners : InteractionListener { val ENCHANTED_V_TREE = 16265 val TREE_SPIRIT_IDS = intArrayOf(NPCs.TREE_SPIRIT_438,NPCs.TREE_SPIRIT_439,NPCs.TREE_SPIRIT_440,NPCs.TREE_SPIRIT_441,NPCs.TREE_SPIRIT_442,NPCs.TREE_SPIRIT_443) override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/FairyRingPlugin.kt b/Server/src/main/kotlin/rs09/game/interaction/object/FairyRingPlugin.kt index 2706f2a45..25067ba9c 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/FairyRingPlugin.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/FairyRingPlugin.kt @@ -15,7 +15,7 @@ private val RINGS = intArrayOf(12003, 12094, 12095, 14058, 14061, 14064, 14067, private const val MAIN_RING = 12128 -class FairyRingPlugin : InteractionListener() { +class FairyRingPlugin : InteractionListener { override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/GutanothChestPlugin.kt b/Server/src/main/kotlin/rs09/game/interaction/object/GutanothChestPlugin.kt index e26c41232..ab6d72adc 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/GutanothChestPlugin.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/GutanothChestPlugin.kt @@ -14,7 +14,7 @@ import rs09.game.world.GameWorld import java.util.concurrent.TimeUnit private const val CHEST = 2827 -class GutanothChestInteractionHandler : InteractionListener(){ +class GutanothChestInteractionHandler : InteractionListener{ override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/JungleBushHandler.kt b/Server/src/main/kotlin/rs09/game/interaction/object/JungleBushHandler.kt index d78b5dd97..555bb3074 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/JungleBushHandler.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/JungleBushHandler.kt @@ -14,7 +14,7 @@ import rs09.game.world.GameWorld * Handles the chopping down of dense jungle, mainly to grant access to the Kharazi Jungle. * @author Ceikry */ -class JungleBushHandler : InteractionListener(){ +class JungleBushHandler : InteractionListener{ val chopped_bush = 2895 val chop_a = Animation(910) val chop_b = Animation(2382) diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/MuddyChestHandler.kt b/Server/src/main/kotlin/rs09/game/interaction/object/MuddyChestHandler.kt index 28f3e7f09..b1ec9a77f 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/MuddyChestHandler.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/MuddyChestHandler.kt @@ -12,7 +12,7 @@ import rs09.game.interaction.InteractionListener * Handles the muddy chest * @author Ceikry */ -class MuddyChestHandler : InteractionListener() { +class MuddyChestHandler : InteractionListener { private val CHEST = 170 diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/TarBarrelListener.kt b/Server/src/main/kotlin/rs09/game/interaction/object/TarBarrelListener.kt index 27f95711b..32b76160d 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/TarBarrelListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/TarBarrelListener.kt @@ -15,7 +15,7 @@ import rs09.game.interaction.InteractionListener * Option(s): * "Take-from" */ -class TarBarrelListener : InteractionListener() { +class TarBarrelListener : InteractionListener { val FULL_TAR_BARREL_16860 = 16860 val EMPTY_TAR_BARREL_16688 = 16688 diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/VarrockGuardSignpost.kt b/Server/src/main/kotlin/rs09/game/interaction/object/VarrockGuardSignpost.kt index f7d897de4..51a5afe9f 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/VarrockGuardSignpost.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/VarrockGuardSignpost.kt @@ -10,7 +10,7 @@ import rs09.GlobalStats import rs09.game.interaction.InteractionListener import rs09.game.system.SystemLogger -class VarrockGuardSignpost : InteractionListener() { +class VarrockGuardSignpost : InteractionListener { override fun defineListeners() { val zone = object : MapZone("Varrock Guards", true){ override fun interact(e: Entity?, target: Node?, option: Option?): Boolean { diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/WizardGuildPortals.kt b/Server/src/main/kotlin/rs09/game/interaction/object/WizardGuildPortals.kt index 8ccabc2ff..6a46c9a1c 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/WizardGuildPortals.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/WizardGuildPortals.kt @@ -4,7 +4,7 @@ import api.* import core.game.world.map.Location import rs09.game.interaction.InteractionListener -class WizardGuildPortals : InteractionListener() { +class WizardGuildPortals : InteractionListener { val WTOWER_PORTAL = 2156 val DWTOWER_PORTAL = 2157 diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/canoestation/CanoeInterfaceListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/object/canoestation/CanoeInterfaceListeners.kt index 5be9fc004..1c461e58a 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/canoestation/CanoeInterfaceListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/canoestation/CanoeInterfaceListeners.kt @@ -17,7 +17,7 @@ import org.rs09.consts.Components import rs09.game.interaction.InterfaceListener import kotlin.math.abs -class CanoeInterfaceListeners : InterfaceListener() { +class CanoeInterfaceListeners : InterfaceListener { val SHAPE_INTERFACE = Components.CANOE_52 val DESTINATION_INTERFACE = Components.CANOE_STATIONS_MAP_53 @@ -26,7 +26,7 @@ class CanoeInterfaceListeners : InterfaceListener() { private val locationChilds = intArrayOf(50, 47, 44, 36) - override fun defineListeners() { + override fun defineInterfaceListeners() { onOpen(SHAPE_INTERFACE){player, _ -> CanoeUtils.checkCanoe(player,Canoe.DUGOUT) diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/canoestation/CanoeStationListener.kt b/Server/src/main/kotlin/rs09/game/interaction/object/canoestation/CanoeStationListener.kt index 857ba683e..a752cae91 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/canoestation/CanoeStationListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/canoestation/CanoeStationListener.kt @@ -8,7 +8,7 @@ import core.game.world.update.flag.context.Animation import org.rs09.consts.Components import rs09.game.interaction.InteractionListener -class CanoeStationListener : InteractionListener() { +class CanoeStationListener : InteractionListener { private val STATION_IDs = intArrayOf(12140, 12141, 12142, 12143, 12144, 12145, 12146, 12147, 12148, 12151, 12152, 12153, 12154, 12155, 12156, 12157, 12158, 12144, 12146, 12149, 12150, 12157) private val STAGE_TREE_NONINTERACTABLE = 9 diff --git a/Server/src/main/kotlin/rs09/game/interaction/object/objects/CrateHandler.kt b/Server/src/main/kotlin/rs09/game/interaction/object/objects/CrateHandler.kt index 8aa99d13e..48364fc2d 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/object/objects/CrateHandler.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/object/objects/CrateHandler.kt @@ -11,7 +11,7 @@ import rs09.game.interaction.`object`.dialogues.CrateDialogues * @author qmqz */ -class CrateHandler : InteractionListener() { +class CrateHandler : InteractionListener { private val monkeyAmuletMouldCrate = 4724 private val threadCrate = 4718 diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/IsafdarListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/region/IsafdarListeners.kt index 18cd96443..2c832b411 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/IsafdarListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/IsafdarListeners.kt @@ -9,7 +9,7 @@ import rs09.game.interaction.InteractionListener * @author Sir Kermit */ -class IsafdarListeners : InteractionListener() { +class IsafdarListeners : InteractionListener { val CAVE_ENTRANCE = 4006 val CAVE_EXIT = 4007 diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/MorytaniaListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/region/MorytaniaListeners.kt index c7676dc36..2ea974f0b 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/MorytaniaListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/MorytaniaListeners.kt @@ -20,7 +20,7 @@ import kotlin.random.Random * @author Sir Kermit */ -class MorytaniaListeners : InteractionListener() { +class MorytaniaListeners : InteractionListener { val SWAMP_GATES = intArrayOf(Scenery.GATE_3506, Scenery.GATE_3507) val GROTTO_EXIT = intArrayOf(3525, 3526) diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/dungeons/brimhaven/BrimhavenDungeonListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/region/dungeons/brimhaven/BrimhavenDungeonListeners.kt index 311f0705f..2894cc215 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/dungeons/brimhaven/BrimhavenDungeonListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/dungeons/brimhaven/BrimhavenDungeonListeners.kt @@ -7,7 +7,7 @@ import core.game.world.update.flag.context.Animation import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener -class BrimhavenDungeonListeners : InteractionListener() { +class BrimhavenDungeonListeners : InteractionListener { val EXIT = 5084 val SANIBOCH = NPCs.SANIBOCH_1595 diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/dungeons/taverley/TaverleyDungeonListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/region/dungeons/taverley/TaverleyDungeonListeners.kt index ed559503e..d445f7e44 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/dungeons/taverley/TaverleyDungeonListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/dungeons/taverley/TaverleyDungeonListeners.kt @@ -6,7 +6,7 @@ import org.rs09.consts.Items import org.rs09.consts.Scenery import rs09.game.interaction.InteractionListener -class TaverleyDungeonListeners : InteractionListener() { +class TaverleyDungeonListeners : InteractionListener { val BD_GATE = Scenery.GATE_2623 val JAIL_DOOR = Scenery.DOOR_31838 diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/falador/WineOfZamorakInteraction.kt b/Server/src/main/kotlin/rs09/game/interaction/region/falador/WineOfZamorakInteraction.kt index ced4bdf72..d160409d8 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/falador/WineOfZamorakInteraction.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/falador/WineOfZamorakInteraction.kt @@ -6,7 +6,7 @@ import org.rs09.consts.Items import rs09.game.content.global.action.PickupHandler import rs09.game.interaction.InteractionListener -class WineOfZamorakInteraction : InteractionListener() { +class WineOfZamorakInteraction : InteractionListener { override fun defineListeners() { on(Items.WINE_OF_ZAMORAK_245,GROUNDITEM,"take"){player, wine -> diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/ChurchSignListener.kt b/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/ChurchSignListener.kt index 25c234b70..6d20582e2 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/ChurchSignListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/ChurchSignListener.kt @@ -5,7 +5,7 @@ import org.rs09.consts.Scenery import rs09.GlobalStats import rs09.game.interaction.InteractionListener -class ChurchSignListener : InteractionListener() { +class ChurchSignListener : InteractionListener { val CHURCH_SIGN = Scenery.SIGNPOST_31299 diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/CowFieldSignListener.kt b/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/CowFieldSignListener.kt index 0f0945499..55107626c 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/CowFieldSignListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/CowFieldSignListener.kt @@ -9,7 +9,7 @@ import rs09.game.interaction.InteractionListener * @author bushtail */ -class CowFieldSignListener : InteractionListener() { +class CowFieldSignListener : InteractionListener { val SIGN = Scenery.SIGNPOST_31297 diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/FredChestListener.kt b/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/FredChestListener.kt index 377743477..4abc44895 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/FredChestListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/FredChestListener.kt @@ -9,7 +9,7 @@ import rs09.game.interaction.InteractionListener * @author bushtail */ -class FredChestListener : InteractionListener() { +class FredChestListener : InteractionListener { val SHUT = Scenery.CLOSED_CHEST_37009 val OPEN = Scenery.OPEN_CHEST_37010 diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/GnomeCopterSignListener.kt b/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/GnomeCopterSignListener.kt index aebf5b4b4..8e696d7d4 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/GnomeCopterSignListener.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/lumbridge/GnomeCopterSignListener.kt @@ -9,7 +9,7 @@ import rs09.game.interaction.InteractionListener * @author bushtail */ -class GnomeCopterSignListener : InteractionListener() { +class GnomeCopterSignListener : InteractionListener { val SIGN = Scenery.ADVERTISEMENT_30037 override fun defineListeners() { on(SIGN, SCENERY, "read") { player, _ -> diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/JatizsoListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/JatizsoListeners.kt index 617828539..da8fc12ad 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/JatizsoListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/JatizsoListeners.kt @@ -13,7 +13,7 @@ import org.rs09.consts.NPCs import rs09.game.content.dialogue.region.jatizso.LeftieRightieDialogue import rs09.game.interaction.InteractionListener -class JatizsoListeners : InteractionListener() { +class JatizsoListeners : InteractionListener { val GATES_CLOSED = intArrayOf(21403,21405) val NORTH_GATE_ZONE = ZoneBorders(2414,3822,2417,3825) val WEST_GATE_ZONE = ZoneBorders(2386,3797,2390,3801) diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/NeitiznotListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/NeitiznotListeners.kt index 316393fc1..ad1f2fb43 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/NeitiznotListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/NeitiznotListeners.kt @@ -12,7 +12,7 @@ import core.game.world.map.zone.ZoneBorders import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener -class NeitiznotListeners : InteractionListener() { +class NeitiznotListeners : InteractionListener { val STUMP = 21305 override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/RellekkaListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/RellekkaListeners.kt index 069389363..63b3443a0 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/RellekkaListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/rellekka/RellekkaListeners.kt @@ -13,7 +13,7 @@ import rs09.game.util.region.rellekka.RellekkaUtils * @author Ceikry */ -class RellekkaListeners : InteractionListener() { +class RellekkaListeners : InteractionListener { val UP1A = Location.create(2715, 3798, 0) val UP1B = Location.create(2716, 3798, 0) diff --git a/Server/src/main/kotlin/rs09/game/interaction/region/wilderness/RoguesCastleListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/region/wilderness/RoguesCastleListeners.kt index c3440ab59..9e5e7142f 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/region/wilderness/RoguesCastleListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/region/wilderness/RoguesCastleListeners.kt @@ -13,7 +13,7 @@ import rs09.game.content.global.WeightBasedTable import rs09.game.content.global.WeightedItem import rs09.game.interaction.InteractionListener -class RoguesCastleListeners : InteractionListener() { +class RoguesCastleListeners : InteractionListener { val CHEST_ANIM = getAnimation(536) val FLOOR_1_CHESTS = intArrayOf(14773, 14774) diff --git a/Server/src/main/kotlin/rs09/game/node/entity/player/diary/seers/SeersCourthouseZone.kt b/Server/src/main/kotlin/rs09/game/node/entity/player/diary/seers/SeersCourthouseZone.kt index 3fc4a872a..6b7815479 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/player/diary/seers/SeersCourthouseZone.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/player/diary/seers/SeersCourthouseZone.kt @@ -1,5 +1,6 @@ package rs09.game.node.entity.player.diary.seers +import api.MapArea import core.game.node.entity.Entity import core.game.node.entity.player.Player import core.game.node.entity.player.link.diary.DiaryType @@ -10,32 +11,16 @@ import core.game.world.map.zone.ZoneBuilder import core.plugin.Initializable import core.plugin.Plugin -@Initializable -class SeersCourthouseZone : MapZone("seers-courthouse", true), Plugin{ - - override fun newInstance(arg: Any?): SeersCourthouseZone { - ZoneBuilder.configure(this) - return this +class SeersCourthouseZone : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2735,3471,2736,3471)) } - override fun configure() { - super.register(ZoneBorders(2735,3471,2736,3471)) - } - - override fun enter(e: Entity?): Boolean { - if(e is Player && !e.isArtificial){ - if(!e.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE,2,3) && e.prayer.active.contains(PrayerType.PIETY)){ - e.achievementDiaryManager.finishTask(e,DiaryType.SEERS_VILLAGE,2,3) + override fun areaEnter(entity: Entity) { + if(entity is Player && !entity.isArtificial){ + if(!entity.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE,2,3) && entity.prayer.active.contains(PrayerType.PIETY)){ + entity.achievementDiaryManager.finishTask(entity,DiaryType.SEERS_VILLAGE,2,3) } } - return super.enter(e) - } - - override fun fireEvent(identifier: String?, vararg args: Any?): Any { - return Unit - } - - override fun leave(e: Entity?, logout: Boolean): Boolean { - return super.leave(e, logout) } } \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/node/entity/player/info/stats/StatsCommandSet.kt b/Server/src/main/kotlin/rs09/game/node/entity/player/info/stats/StatsCommandSet.kt index 7ab9afc06..a15251e52 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/player/info/stats/StatsCommandSet.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/player/info/stats/StatsCommandSet.kt @@ -199,10 +199,10 @@ class StatsCommandSet : CommandSet(Privilege.STANDARD) { } -class StatsInterface : InterfaceListener() { +class StatsInterface : InterfaceListener { val COMPONENT_ID = 26 - override fun defineListeners() { + override fun defineInterfaceListeners() { on(COMPONENT_ID, 61) { player, _, _, _, _, _ -> val info: StatsPageInfo? = player.getAttribute("stats-page-info", null) if(info != null) { diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/AttackListener.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/AttackListener.kt index c3787f435..0f00f1e7c 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/AttackListener.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/AttackListener.kt @@ -3,7 +3,7 @@ package rs09.game.node.entity.skill import core.game.node.entity.combat.CombatStyle import rs09.game.interaction.InteractionListener -class AttackListener : InteractionListener() { +class AttackListener : InteractionListener { override fun defineListeners() { on(NPC, "attack"){player, npc -> //Makes sure player uses correct attack styles for lumbridge dummies diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/chapel/BurnerListener.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/chapel/BurnerListener.kt index 1f4c227a0..176881a95 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/chapel/BurnerListener.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/chapel/BurnerListener.kt @@ -11,7 +11,7 @@ import rs09.game.interaction.InteractionListener * Handles the lighting of the torches of the Chapel. * @author Splinter */ -class BurnerListener : InteractionListener() { +class BurnerListener : InteractionListener { val IDs = intArrayOf(13202,13203,13204,13205,13206,13207,13208,13209,13210,13211,13212,13213) diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/questhall/MountedGlory.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/questhall/MountedGlory.kt index e8de88232..8c3bfc7b6 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/questhall/MountedGlory.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/questhall/MountedGlory.kt @@ -11,7 +11,7 @@ import rs09.game.interaction.InteractionListener import java.util.concurrent.Executors import java.util.concurrent.TimeUnit -class MountedGlory : InteractionListener() { +class MountedGlory : InteractionListener { val MOUNTED_GLORY = 13523 diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/study/TelescopePlugin.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/study/TelescopePlugin.kt index fee31ef24..731efa14d 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/study/TelescopePlugin.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/construction/decoration/study/TelescopePlugin.kt @@ -11,8 +11,7 @@ import core.game.world.update.flag.context.Animation import core.plugin.Initializable import core.plugin.Plugin import core.tools.RandomFunction -import rs09.game.content.global.worldevents.WorldEvents -import rs09.game.content.global.worldevents.shootingstar.ShootingStarEvent +import rs09.game.content.global.worldevents.shootingstar.ShootingStarPlugin import rs09.game.world.GameWorld.Pulser import java.util.concurrent.TimeUnit @@ -27,7 +26,7 @@ class TelescopePlugin : OptionHandler() { } override fun handle(player: Player?, node: Node?, option: String?): Boolean { - val star = (WorldEvents.get("shooting-stars") as ShootingStarEvent).star + val star = ShootingStarPlugin.getStar() val delay: Int = 25000 + (25000 / 3) val timeLeft = delay - star.ticks val fakeTimeLeftBecauseFuckPlayers = TimeUnit.MILLISECONDS.toMinutes(timeLeft * 600L) + if(RandomFunction.random(0,100) % 2 == 0) 2 else -2 diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/cooking/DoughMakingListener.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/cooking/DoughMakingListener.kt index 839022e16..0709d4f9d 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/cooking/DoughMakingListener.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/cooking/DoughMakingListener.kt @@ -7,7 +7,7 @@ import org.rs09.consts.Items import rs09.game.content.dialogue.DialogueFile import rs09.game.interaction.InteractionListener -class DoughMakingListener : InteractionListener() { +class DoughMakingListener : InteractionListener { val sourceReturnMap = hashMapOf( Items.BUCKET_OF_WATER_1929 to Items.BUCKET_1925, Items.BOWL_OF_WATER_1921 to Items.BOWL_1923, diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/FarmerPayOptionHandler.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/FarmerPayOptionHandler.kt index 4fa8515ae..b957769d9 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/FarmerPayOptionHandler.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/FarmerPayOptionHandler.kt @@ -4,7 +4,7 @@ import core.game.node.Node import core.game.node.entity.player.Player import rs09.game.interaction.InteractionListener -class FarmerPayOptionHandler : InteractionListener() { +class FarmerPayOptionHandler : InteractionListener { override fun defineListeners() { on(NPC,"pay","pay (north)","pay (north-west)"){player,node -> diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/LeprechaunNoter.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/LeprechaunNoter.kt index 53b74294b..2c8124cfc 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/LeprechaunNoter.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/LeprechaunNoter.kt @@ -8,7 +8,7 @@ import core.plugin.Initializable import org.rs09.consts.NPCs import rs09.game.interaction.InteractionListener -class LeprechaunNoter : InteractionListener() { +class LeprechaunNoter : InteractionListener { val CROPS = Plantable.values().map{ it.harvestItem }.toIntArray() val LEPRECHAUNS = intArrayOf(NPCs.TOOL_LEPRECHAUN_3021,NPCs.GOTH_LEPRECHAUN_8000,NPCs.TOOL_LEPRECHAUN_4965,NPCs.TECLYN_2861) diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/ToolLeprechaunHandler.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/ToolLeprechaunHandler.kt index c769ccc1e..fd2e480fa 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/ToolLeprechaunHandler.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/ToolLeprechaunHandler.kt @@ -11,6 +11,7 @@ import core.plugin.Initializable import core.plugin.Plugin import org.rs09.consts.Components import org.rs09.consts.NPCs +import rs09.game.content.activity.vinesweeper.Vinesweeper val TL_IDS = arrayOf(NPCs.TOOL_LEPRECHAUN_3021,NPCs.GOTH_LEPRECHAUN_8000,NPCs.TOOL_LEPRECHAUN_4965,NPCs.TECLYN_2861) @Initializable @@ -28,7 +29,7 @@ class ToolLeprechaunHandler : OptionHandler() { node ?: return false when(option){ "exchange" -> player?.interfaceManager?.open(Component(Components.FARMING_TOOLS_125)) - "teleport" -> VinesweeperTeleport.teleport(node!! as NPC, player!!) + "teleport" -> Vinesweeper.Companion.VinesweeperTeleport.teleport(node!! as NPC, player!!) } return true } diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/ToolLeprechaunInterface.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/ToolLeprechaunInterface.kt index 7c25ee698..5978653a8 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/ToolLeprechaunInterface.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/ToolLeprechaunInterface.kt @@ -10,12 +10,12 @@ import org.rs09.consts.Items import rs09.game.interaction.InterfaceListener private const val varp = 615 -class ToolLeprechaunInterface : InterfaceListener() { +class ToolLeprechaunInterface : InterfaceListener { private val FARMING_TOOLS = Components.FARMING_TOOLS_125 private val TOOLS_SIDE = Components.FARMING_TOOLS_SIDE_126 - override fun defineListeners() { + override fun defineInterfaceListeners() { onOpen(FARMING_TOOLS){player, component -> player.varpManager?.flagSave(varp) diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/fletching/FletchingListeners.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/fletching/FletchingListeners.kt index 97dde77f3..4867fbdf8 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/fletching/FletchingListeners.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/fletching/FletchingListeners.kt @@ -21,7 +21,7 @@ import org.rs09.consts.Items.YELLOW_FEATHER_10090 import rs09.game.content.dialogue.SkillDialogueHandler import rs09.game.interaction.InteractionListener -class FletchingListeners : InteractionListener() { +class FletchingListeners : InteractionListener { val LIMBIDs = Fletching.Limb.values().map(Fletching.Limb::limb).toIntArray() val STOCKIDs = Fletching.Limb.values().map(Fletching.Limb::stock).toIntArray() diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/GatheringSkillOptionListeners.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/GatheringSkillOptionListeners.kt index efc3903cb..3e7abf503 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/GatheringSkillOptionListeners.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/GatheringSkillOptionListeners.kt @@ -11,7 +11,7 @@ import rs09.game.content.dialogue.KjallakOnChopDialogue import rs09.game.interaction.InteractionListener import rs09.game.node.entity.skill.gather.mining.MiningSkillPulse -class GatheringSkillOptionListeners : InteractionListener() { +class GatheringSkillOptionListeners : InteractionListener { val ETCETERIA_REGION = 10300 diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/fishing/barbfishing/BarbFishInteractionListeners.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/fishing/barbfishing/BarbFishInteractionListeners.kt index 9892ac65d..d016f5e6f 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/fishing/barbfishing/BarbFishInteractionListeners.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/fishing/barbfishing/BarbFishInteractionListeners.kt @@ -3,7 +3,7 @@ package rs09.game.node.entity.skill.gather.fishing.barbfishing import core.game.node.item.Item import rs09.game.interaction.InteractionListener -class BarbFishInteractionListeners : InteractionListener() { +class BarbFishInteractionListeners : InteractionListener { override fun defineListeners() { on(25268,SCENERY,"search"){ player, _ -> diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/mining/ProspectListener.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/mining/ProspectListener.kt index 6d2853798..9ef542b2e 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/mining/ProspectListener.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/gather/mining/ProspectListener.kt @@ -10,7 +10,7 @@ import rs09.game.interaction.InteractionListener * @author: bushtail */ -class ProspectListener : InteractionListener() { +class ProspectListener : InteractionListener { override fun defineListeners() { on(SCENERY, "prospect") { player, node -> diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/hunter/pitfall/HunterPitfall.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/hunter/pitfall/HunterPitfall.kt index d9a0c7de7..19460c562 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/hunter/pitfall/HunterPitfall.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/hunter/pitfall/HunterPitfall.kt @@ -148,7 +148,7 @@ val GRAAHK_PIT = 19231 val LARUPIA_PIT = 19232 val KYATT_PIT = 19233 -class PitfallListeners : InteractionListener() { +class PitfallListeners : InteractionListener { override fun defineListeners() { setDest(SCENERY, intArrayOf(PIT, SPIKED_PIT, LARUPIA_PIT, GRAAHK_PIT, KYATT_PIT), "trap", "jump", "dismantle") { player, node -> diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellTablets.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellTablets.kt index 39eefc17f..ded43db37 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellTablets.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/magic/SpellTablets.kt @@ -7,7 +7,7 @@ import org.rs09.consts.Items import rs09.game.interaction.InteractionListener import rs09.game.node.entity.skill.magic.spellconsts.Modern -class SpellTablets : InteractionListener() { +class SpellTablets : InteractionListener { val B2P_TABLET = Items.BONES_TO_PEACHES_8015 val B2B_TABLET = Items.BONES_TO_BANANAS_8014 override fun defineListeners() { diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/runecrafting/abyss/AbyssPlugin.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/runecrafting/abyss/AbyssPlugin.kt index 57ec46268..1a91840a9 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/runecrafting/abyss/AbyssPlugin.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/runecrafting/abyss/AbyssPlugin.kt @@ -24,7 +24,7 @@ import rs09.game.world.GameWorld * A plugin used to handle the abyss. * @author cfunny */ -class AbyssPlugin : InteractionListener() { +class AbyssPlugin : InteractionListener { val OBSTACLE = AbbysalObstacle.values().filter { it != AbbysalObstacle.MINE && it != AbbysalObstacle.SQUEEZE && it != AbbysalObstacle.PASSAGE && it != AbbysalObstacle.CHOP }.map { it.option }.toTypedArray() val miningObstacle = 7158 diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/thieving/ThievingListeners.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/thieving/ThievingListeners.kt index 9a9c25bc9..38ce80ea5 100644 --- a/Server/src/main/kotlin/rs09/game/node/entity/skill/thieving/ThievingListeners.kt +++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/thieving/ThievingListeners.kt @@ -13,7 +13,7 @@ import rs09.game.interaction.InteractionListener import rs09.game.system.SystemLogger import rs09.tools.secondsToTicks -class ThievingListeners : InteractionListener() { +class ThievingListeners : InteractionListener { private val PICKPOCKET_ANIM = Animation(881,Animator.Priority.HIGH) private val NPC_ANIM = Animation(422) diff --git a/Server/src/main/kotlin/rs09/game/system/config/ShopParser.kt b/Server/src/main/kotlin/rs09/game/system/config/ShopParser.kt index 3a0768eeb..08c6b6ac2 100644 --- a/Server/src/main/kotlin/rs09/game/system/config/ShopParser.kt +++ b/Server/src/main/kotlin/rs09/game/system/config/ShopParser.kt @@ -1,6 +1,5 @@ package rs09.game.system.config -import core.game.content.global.shop.Shop import core.game.node.entity.player.Player import core.game.node.item.Item import org.json.simple.JSONArray @@ -14,12 +13,12 @@ class ShopParser{ val parser = JSONParser() var reader: FileReader? = null - companion object{ - val SHOPS = HashMap() - val UID_SHOPS = HashMap() + companion object { +/* val SHOPS = HashMap() + val UID_SHOPS = HashMap()*/ fun openUid(player: Player,uid: Int): Boolean { - val shop = UID_SHOPS[uid] ?: return false; - shop.open(player); +/* val shop = UID_SHOPS[uid] ?: return false; + shop.open(player);*/ return true; } } @@ -29,42 +28,9 @@ class ShopParser{ reader = FileReader(ServerConstants.CONFIG_PATH + "shops.json") val configlist = parser.parse(reader) as JSONArray for(config in configlist){ - var shop: Shop? - val e = config as JSONObject - val id = e["id"].toString().toInt() - val title = e["title"].toString() - val general = e["general_store"].toString().toBoolean() - val stock = parseStock(e["stock"].toString()).toTypedArray() - val npcs = if(e["npcs"].toString().isNotBlank()) e["npcs"].toString().split(",").map { it.toInt() }.toIntArray() else intArrayOf() - val currency = e["currency"].toString().toInt() - val highAlch = e["high_alch"].toString() == "1" - if(general && stock.isEmpty()){ - shop = Shop(title,true,currency,highAlch) - } else { - shop = Shop(title, stock, general, currency, highAlch) - } - if(npcs.isNotEmpty()){ - npcs.map { SHOPS[it] = shop } - } else { - UID_SHOPS[id] = shop - } + count++ } SystemLogger.logInfo("Parsed $count shops.") } - - fun parseStock(stock: String): ArrayList{ - val items = ArrayList() - if(stock.isEmpty()){ - return items - } - stock.split('-').map { - val tokens = it.replace("{", "").replace("}", "").split(",".toRegex()).toTypedArray() - var amount = tokens[1].trim() - if(amount == "inf") - amount = "-1" - items.add(Item(tokens[0].trim().toInt(),amount.toInt())) - } - return items - } } \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/plugin/ClassScanner.kt b/Server/src/main/kotlin/rs09/plugin/ClassScanner.kt index 9e9dcb2fe..4d5bf1c90 100644 --- a/Server/src/main/kotlin/rs09/plugin/ClassScanner.kt +++ b/Server/src/main/kotlin/rs09/plugin/ClassScanner.kt @@ -4,9 +4,14 @@ import api.* import core.game.content.activity.ActivityManager import core.game.content.activity.ActivityPlugin import core.game.content.dialogue.DialoguePlugin +import core.game.node.entity.Entity import core.game.node.entity.player.info.login.LoginConfiguration import core.game.node.entity.player.link.quest.Quest import core.game.node.entity.player.link.quest.QuestRepository +import core.game.world.map.Location +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBuilder +import core.game.world.map.zone.ZoneMonitor import core.plugin.Plugin import core.plugin.PluginManifest import core.plugin.PluginType @@ -15,10 +20,12 @@ import io.github.classgraph.ClassInfo import rs09.game.ai.general.scriptrepository.PlayerScripts import rs09.game.interaction.InteractionListener import rs09.game.interaction.InterfaceListener +import rs09.game.interaction.Listener import rs09.game.node.entity.player.info.login.PlayerSaveParser import rs09.game.node.entity.player.info.login.PlayerSaver import rs09.game.node.entity.skill.magic.SpellListener import rs09.game.system.SystemLogger +import rs09.game.system.command.Command import rs09.game.world.GameWorld import java.util.* import java.util.function.Consumer @@ -67,14 +74,50 @@ object ClassScanner { fun load() { val result = ClassGraph().enableClassInfo().enableAnnotationInfo().scan() result.getClassesWithAnnotation("core.plugin.Initializable").forEach(Consumer { p: ClassInfo -> + val clazz = p.loadClass().newInstance() + if(clazz is Plugin<*>) definePlugin(clazz) + }) + result.getClassesImplementing("api.ContentInterface").filter { !it.isAbstract }.forEach { try { - definePlugin(p.loadClass().newInstance() as Plugin) - } catch (e: InstantiationException) { - e.printStackTrace() - } catch (e: IllegalAccessException) { + val clazz = it.loadClass().newInstance() + if(clazz is LoginListener) GameWorld.loginListeners.add(clazz) + if(clazz is LogoutListener) GameWorld.logoutListeners.add(clazz) + if(clazz is TickListener) GameWorld.tickListeners.add(clazz) + if(clazz is StartupListener) GameWorld.startupListeners.add(clazz) + if(clazz is ShutdownListener) GameWorld.shutdownListeners.add(clazz) + if(clazz is InteractionListener) clazz.defineListeners().also { clazz.defineDestinationOverrides() } + if(clazz is InterfaceListener) clazz.defineInterfaceListeners() + if(clazz is Commands) clazz.defineCommands() + if(clazz is PersistPlayer) { + PlayerSaver.contentHooks.add(clazz) + PlayerSaveParser.contentHooks.add(clazz) + } + if(clazz is MapArea) + { + val zone = object : MapZone(clazz.javaClass.simpleName + "MapArea", true, *clazz.getRestrictions()){ + override fun enter(e: Entity?): Boolean { + clazz.areaEnter(e ?: return super.enter(null)) + return super.enter(e) + } + + override fun leave(e: Entity?, logout: Boolean): Boolean { + clazz.areaLeave(e ?: return super.leave(null, logout), logout) + return super.leave(e, logout) + } + + override fun move(e: Entity?, from: Location?, to: Location?): Boolean { + if(e != null && from != null && to != null) clazz.entityStep(e, to, from) + return super.move(e, from, to) + } + } + for(border in clazz.defineAreaBorders()) zone.register(border) + ZoneBuilder.configure(zone) + } + } catch (e: Exception) { + SystemLogger.logErr("Error loading content: ${it.simpleName}, ${e.localizedMessage}") e.printStackTrace() } - }) + } result.getClassesWithAnnotation("rs09.game.ai.general.scriptrepository.PlayerCompatible").forEach { res -> val description = res.getAnnotationInfo("rs09.game.ai.general.scriptrepository.ScriptDescription").parameterValues[0].value as Array val identifier = res.getAnnotationInfo("rs09.game.ai.general.scriptrepository.ScriptIdentifier").parameterValues[0].value.toString() @@ -82,41 +125,6 @@ object ClassScanner { PlayerScripts.identifierMap[identifier] = PlayerScripts.PlayerScript(identifier, description, name, res.loadClass()) } - result.getClassesImplementing("api.StartupListener").filter { !it.isAbstract }.forEach { - try { - val clazz = it.loadClass().newInstance() as StartupListener - GameWorld.startupListeners.add(clazz) - } catch (e: Exception) - { - SystemLogger.logErr("Error loading startup listener: ${it.simpleName}, ${e.localizedMessage}") - e.printStackTrace() - } - } - result.getClassesImplementing("api.ShutdownListener").filter { !it.isAbstract }.forEach { - val clazz = it.loadClass().newInstance() as ShutdownListener - GameWorld.shutdownListeners.add(clazz) - } - result.getClassesImplementing("api.LoginListener").filter { !it.isAbstract }.forEach { - val clazz = it.loadClass().newInstance() as LoginListener - GameWorld.loginListeners.add(clazz) - } - result.getClassesImplementing("api.LogoutListener").filter { !it.isAbstract }.forEach { - val clazz = it.loadClass().newInstance() as LogoutListener - GameWorld.logoutListeners.add(clazz) - } - result.getClassesImplementing("api.TickListener").filter { !it.isAbstract }.forEach { - val clazz = it.loadClass().newInstance() as TickListener - GameWorld.tickListeners.add(clazz) - } - result.getClassesImplementing("api.PersistPlayer").filter { !it.isAbstract }.forEach { - val clazz = it.loadClass().newInstance() as PersistPlayer - PlayerSaver.contentHooks.add(clazz) - PlayerSaveParser.contentHooks.add(clazz) - } - result.getClassesImplementing("api.PersistWorld").filter { !it.isAbstract }.forEach { - val clazz = it.loadClass().newInstance() as PersistPlayer - PlayerSaver.contentHooks.add(clazz) - } } /**