Addeds arrow api, quest helper plugin, changed raids etc (#81)
* add a skull timer * fix the feature and check edge cases * Add config option and a check for deadman worlds * add support for NPE * Add reskulling on players and the BH shop skull option * Add skull notifier plugin * move to idle notification plugin * remove old plugin * fix plugin and change default config option to false * fix to try and fix travis * should fix travis * indentation fix and adds a method for the logic * fix config * fix config #2 * Stop a NPE from happening on log in * actually fix NPE * fix notifications on first tick * Remove raids timer infobox and add tooltip to points widget * Add get widget overlay * client: add custom arrow API Currently supports: Minimap Arbitrary World Point NPCs (by ID, and multiple per arrow) Objects (by ID, and multiple per arrow) TODO: Add world map point support * Add quest helper * Add Npc Talk Step to quest helper * Add Cooks Assistant quest helper * Add Imp Catcher to quest helper * Add Dig Step to quest helper * Add X Marks The Spot to quest helper * Adds back skull timer
This commit is contained in:
@@ -25,169 +25,168 @@
|
|||||||
package net.runelite.api;
|
package net.runelite.api;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public enum Quest
|
public enum Quest
|
||||||
{
|
{
|
||||||
//Free Quests
|
//Free Quests
|
||||||
BLACK_KNIGHTS_FORTRESS(299, "Black Knights' Fortress"),
|
BLACK_KNIGHTS_FORTRESS(299, "Black Knights' Fortress", VarPlayer.QUEST_BLACK_KNIGHTS_FORTRESS),
|
||||||
COOKS_ASSISTANT(300, "Cook's Assistant"),
|
COOKS_ASSISTANT(300, "Cook's Assistant", VarPlayer.QUEST_COOKS_ASSISTANT),
|
||||||
THE_CORSAIR_CURSE(301, "The Corsair Curse"),
|
THE_CORSAIR_CURSE(301, "The Corsair Curse", Varbits.QUEST_THE_CORSAIR_CURSE),
|
||||||
DEMON_SLAYER(302, "Demon Slayer"),
|
DEMON_SLAYER(302, "Demon Slayer", Varbits.QUEST_DEMON_SLAYER),
|
||||||
DORICS_QUEST(303, "Doric's Quest"),
|
DORICS_QUEST(303, "Doric's Quest", VarPlayer.QUEST_DORICS_QUEST),
|
||||||
DRAGON_SLAYER(304, "Dragon Slayer"),
|
DRAGON_SLAYER(304, "Dragon Slayer", VarPlayer.QUEST_DRAGON_SLAYER),
|
||||||
ERNEST_THE_CHICKEN(305, "Ernest the Chicken"),
|
ERNEST_THE_CHICKEN(305, "Ernest the Chicken", VarPlayer.QUEST_ERNEST_THE_CHICKEN),
|
||||||
GOBLIN_DIPLOMACY(306, "Goblin Diplomacy"),
|
GOBLIN_DIPLOMACY(306, "Goblin Diplomacy", Varbits.QUEST_GOBLIN_DIPLOMACY),
|
||||||
IMP_CATCHER(307, "Imp Catcher"),
|
IMP_CATCHER(307, "Imp Catcher", VarPlayer.QUEST_IMP_CATCHER),
|
||||||
THE_KNIGHTS_SWORD(308, "The Knight's Sword"),
|
THE_KNIGHTS_SWORD(308, "The Knight's Sword", VarPlayer.QUEST_THE_KNIGHTS_SWORD),
|
||||||
MISTHALIN_MYSTERY(309, "Misthalin Mystery"),
|
MISTHALIN_MYSTERY(309, "Misthalin Mystery", Varbits.QUEST_MISTHALIN_MYSTERY),
|
||||||
PIRATES_TREASURE(310, "Pirate's Treasure"),
|
PIRATES_TREASURE(310, "Pirate's Treasure", VarPlayer.QUEST_PIRATES_TREASURE),
|
||||||
PRINCE_ALI_RESCUE(311, "Prince Ali Rescue"),
|
PRINCE_ALI_RESCUE(311, "Prince Ali Rescue", VarPlayer.QUEST_PRINCE_ALI_RESCUE),
|
||||||
THE_RESTLESS_GHOST(312, "The Restless Ghost"),
|
THE_RESTLESS_GHOST(312, "The Restless Ghost", VarPlayer.QUEST_THE_RESTLESS_GHOST),
|
||||||
ROMEO__JULIET(313, "Romeo & Juliet"),
|
ROMEO__JULIET(313, "Romeo & Juliet", VarPlayer.QUEST_ROMEO_AND_JULIET),
|
||||||
RUNE_MYSTERIES(314, "Rune Mysteries"),
|
RUNE_MYSTERIES(314, "Rune Mysteries", VarPlayer.QUEST_RUNE_MYSTERIES),
|
||||||
SHEEP_SHEARER(315, "Sheep Shearer"),
|
SHEEP_SHEARER(315, "Sheep Shearer", VarPlayer.QUEST_SHEEP_SHEARER),
|
||||||
SHIELD_OF_ARRAV(316, "Shield of Arrav"),
|
SHIELD_OF_ARRAV(316, "Shield of Arrav", VarPlayer.QUEST_SHIELD_OF_ARRAV),
|
||||||
VAMPIRE_SLAYER(317, "Vampire Slayer"),
|
VAMPIRE_SLAYER(317, "Vampire Slayer", VarPlayer.QUEST_VAMPIRE_SLAYER),
|
||||||
WITCHS_POTION(318, "Witch's Potion"),
|
WITCHS_POTION(318, "Witch's Potion", VarPlayer.QUEST_WITCHS_POTION),
|
||||||
|
X_MARKS_THE_SPOT(550, "X Marks the Spot", Varbits.QUEST_X_MARKS_THE_SPOT),
|
||||||
|
|
||||||
//Members' Quests
|
//Members' Quests
|
||||||
ANIMAL_MAGNETISM(331, "Animal Magnetism"),
|
ANIMAL_MAGNETISM(331, "Animal Magnetism", Varbits.QUEST_ANIMAL_MAGNETISM),
|
||||||
ANOTHER_SLICE_OF_HAM(332, "Another Slice of H.A.M."),
|
ANOTHER_SLICE_OF_HAM(332, "Another Slice of H.A.M.", Varbits.QUEST_ANOTHER_SLICE_OF_HAM),
|
||||||
BETWEEN_A_ROCK(333, "Between a Rock..."),
|
BETWEEN_A_ROCK(333, "Between a Rock...", Varbits.QUEST_BETWEEN_A_ROCK),
|
||||||
BIG_CHOMPY_BIRD_HUNTING(334, "Big Chompy Bird Hunting"),
|
BIG_CHOMPY_BIRD_HUNTING(334, "Big Chompy Bird Hunting", VarPlayer.QUEST_BIG_CHOMPY_BIRD_HUNTING),
|
||||||
BIOHAZARD(335, "Biohazard"),
|
BIOHAZARD(335, "Biohazard", VarPlayer.QUEST_BIOHAZARD),
|
||||||
CABIN_FEVER(336, "Cabin Fever"),
|
CABIN_FEVER(336, "Cabin Fever", VarPlayer.QUEST_CABIN_FEVER),
|
||||||
CLOCK_TOWER(337, "Clock Tower"),
|
CLOCK_TOWER(337, "Clock Tower", VarPlayer.QUEST_CLOCK_TOWER),
|
||||||
COLD_WAR(338, "Cold War"),
|
COLD_WAR(338, "Cold War", Varbits.QUEST_COLD_WAR),
|
||||||
CONTACT(339, "Contact!"),
|
CONTACT(339, "Contact!", Varbits.QUEST_CONTACT),
|
||||||
CREATURE_OF_FENKENSTRAIN(340, "Creature of Fenkenstrain"),
|
CREATURE_OF_FENKENSTRAIN(340, "Creature of Fenkenstrain", VarPlayer.QUEST_CREATURE_OF_FENKENSTRAIN),
|
||||||
DARKNESS_OF_HALLOWVALE(341, "Darkness of Hallowvale"),
|
DARKNESS_OF_HALLOWVALE(341, "Darkness of Hallowvale", Varbits.QUEST_DARKNESS_OF_HALLOWVALE),
|
||||||
DEATH_PLATEAU(342, "Death Plateau"),
|
DEATH_PLATEAU(342, "Death Plateau", VarPlayer.QUEST_DEATH_PLATEAU),
|
||||||
DEATH_TO_THE_DORGESHUUN(343, "Death to the Dorgeshuun"),
|
DEATH_TO_THE_DORGESHUUN(343, "Death to the Dorgeshuun", Varbits.QUEST_DEATH_TO_THE_DORGESHUUN),
|
||||||
THE_DEPTHS_OF_DESPAIR(344, "The Depths of Despair"),
|
THE_DEPTHS_OF_DESPAIR(344, "The Depths of Despair", Varbits.QUEST_THE_DEPTHS_OF_DESPAIR),
|
||||||
DESERT_TREASURE(345, "Desert Treasure"),
|
DESERT_TREASURE(345, "Desert Treasure", Varbits.QUEST_DESERT_TREASURE),
|
||||||
DEVIOUS_MINDS(346, "Devious Minds"),
|
DEVIOUS_MINDS(346, "Devious Minds", Varbits.QUEST_DEVIOUS_MINDS),
|
||||||
THE_DIG_SITE(347, "The Dig Site"),
|
THE_DIG_SITE(347, "The Dig Site", VarPlayer.QUEST_THE_DIG_SITE),
|
||||||
DRAGON_SLAYER_II(348, "Dragon Slayer II"),
|
DRAGON_SLAYER_II(348, "Dragon Slayer II", Varbits.QUEST_DRAGON_SLAYER_II),
|
||||||
DREAM_MENTOR(349, "Dream Mentor"),
|
DREAM_MENTOR(349, "Dream Mentor", Varbits.QUEST_DREAM_MENTOR),
|
||||||
DRUIDIC_RITUAL(350, "Druidic Ritual"),
|
DRUIDIC_RITUAL(350, "Druidic Ritual", VarPlayer.QUEST_DRUIDIC_RITUAL),
|
||||||
DWARF_CANNON(351, "Dwarf Cannon"),
|
DWARF_CANNON(351, "Dwarf Cannon", Varbits.QUEST_THE_GIANT_DWARF),
|
||||||
EADGARS_RUSE(352, "Eadgar's Ruse"),
|
EADGARS_RUSE(352, "Eadgar's Ruse", VarPlayer.QUEST_EADGARS_RUSE),
|
||||||
EAGLES_PEAK(353, "Eagles' Peak"),
|
EAGLES_PEAK(353, "Eagles' Peak", Varbits.QUEST_EAGLES_PEAK),
|
||||||
ELEMENTAL_WORKSHOP_I(354, "Elemental Workshop I"),
|
ELEMENTAL_WORKSHOP_I(354, "Elemental Workshop I", VarPlayer.QUEST_ELEMENTAL_WORKSHOP_I),
|
||||||
ELEMENTAL_WORKSHOP_II(355, "Elemental Workshop II"),
|
ELEMENTAL_WORKSHOP_II(355, "Elemental Workshop II", Varbits.QUEST_ELEMENTAL_WORKSHOP_II),
|
||||||
ENAKHRAS_LAMENT(356, "Enakhra's Lament"),
|
ENAKHRAS_LAMENT(356, "Enakhra's Lament", Varbits.QUEST_ENAKHRAS_LAMENT),
|
||||||
ENLIGHTENED_JOURNEY(357, "Enlightened Journey"),
|
ENLIGHTENED_JOURNEY(357, "Enlightened Journey", Varbits.QUEST_ENLIGHTENED_JOURNEY),
|
||||||
THE_EYES_OF_GLOUPHRIE(358, "The Eyes of Glouphrie"),
|
THE_EYES_OF_GLOUPHRIE(358, "The Eyes of Glouphrie", Varbits.QUEST_THE_EYES_OF_GLOUPHRIE),
|
||||||
FAIRYTALE_I__GROWING_PAINS(359, "Fairytale I - Growing Pains"),
|
FAIRYTALE_I__GROWING_PAINS(359, "Fairytale I - Growing Pains", Varbits.QUEST_FAIRYTALE_I_GROWING_PAINS),
|
||||||
FAIRYTALE_II__CURE_A_QUEEN(360, "Fairytale II - Cure a Queen"),
|
FAIRYTALE_II__CURE_A_QUEEN(360, "Fairytale II - Cure a Queen", Varbits.QUEST_FAIRYTALE_II_CURE_A_QUEEN),
|
||||||
FAMILY_CREST(361, "Family Crest"),
|
FAMILY_CREST(361, "Family Crest", VarPlayer.QUEST_FAMILY_CREST),
|
||||||
THE_FEUD(362, "The Feud"),
|
THE_FEUD(362, "The Feud", Varbits.QUEST_THE_FEUD),
|
||||||
FIGHT_ARENA(363, "Fight Arena"),
|
FIGHT_ARENA(363, "Fight Arena", VarPlayer.QUEST_FIGHT_ARENA),
|
||||||
FISHING_CONTEST(364, "Fishing Contest"),
|
FISHING_CONTEST(364, "Fishing Contest", VarPlayer.QUEST_FISHING_CONTEST),
|
||||||
FORGETTABLE_TALE(365, "Forgettable Tale..."),
|
FORGETTABLE_TALE(365, "Forgettable Tale...", Varbits.QUEST_FORGETTABLE_TALE),
|
||||||
BONE_VOYAGE(366, "Bone Voyage"),
|
BONE_VOYAGE(366, "Bone Voyage", Varbits.QUEST_BONE_VOYAGE),
|
||||||
THE_FREMENNIK_ISLES(367, "The Fremennik Isles"),
|
THE_FREMENNIK_ISLES(367, "The Fremennik Isles", Varbits.QUEST_THE_FREMENNIK_ISLES),
|
||||||
THE_FREMENNIK_TRIALS(368, "The Fremennik Trials"),
|
THE_FREMENNIK_TRIALS(368, "The Fremennik Trials", VarPlayer.QUEST_THE_FREMENNIK_TRIALS),
|
||||||
GARDEN_OF_TRANQUILLITY(369, "Garden of Tranquillity"),
|
GARDEN_OF_TRANQUILLITY(369, "Garden of Tranquillity", Varbits.QUEST_GARDEN_OF_TRANQUILLITY),
|
||||||
GERTRUDES_CAT(370, "Gertrude's Cat"),
|
GERTRUDES_CAT(370, "Gertrude's Cat", VarPlayer.QUEST_GERTRUDES_CAT),
|
||||||
GHOSTS_AHOY(371, "Ghosts Ahoy"),
|
GHOSTS_AHOY(371, "Ghosts Ahoy", Varbits.QUEST_GHOSTS_AHOY),
|
||||||
THE_GIANT_DWARF(372, "The Giant Dwarf"),
|
THE_GIANT_DWARF(372, "The Giant Dwarf", Varbits.QUEST_THE_GIANT_DWARF),
|
||||||
THE_GOLEM(373, "The Golem"),
|
THE_GOLEM(373, "The Golem", Varbits.QUEST_THE_GOLEM),
|
||||||
THE_GRAND_TREE(374, "The Grand Tree"),
|
THE_GRAND_TREE(374, "The Grand Tree", VarPlayer.QUEST_THE_GRAND_TREE),
|
||||||
THE_GREAT_BRAIN_ROBBERY(375, "The Great Brain Robbery"),
|
THE_GREAT_BRAIN_ROBBERY(375, "The Great Brain Robbery", VarPlayer.QUEST_THE_GREAT_BRAIN_ROBBERY),
|
||||||
GRIM_TALES(376, "Grim Tales"),
|
GRIM_TALES(376, "Grim Tales", Varbits.QUEST_GRIM_TALES),
|
||||||
THE_HAND_IN_THE_SAND(377, "The Hand in the Sand"),
|
THE_HAND_IN_THE_SAND(377, "The Hand in the Sand", Varbits.QUEST_THE_HAND_IN_THE_SAND),
|
||||||
HAUNTED_MINE(378, "Haunted Mine"),
|
HAUNTED_MINE(378, "Haunted Mine", VarPlayer.QUEST_HAUNTED_MINE),
|
||||||
HAZEEL_CULT(379, "Hazeel Cult"),
|
HAZEEL_CULT(379, "Hazeel Cult", VarPlayer.QUEST_HAZEEL_CULT),
|
||||||
HEROES_QUEST(380, "Heroes' Quest"),
|
HEROES_QUEST(380, "Heroes' Quest", VarPlayer.QUEST_HEROES_QUEST),
|
||||||
HOLY_GRAIL(381, "Holy Grail"),
|
HOLY_GRAIL(381, "Holy Grail", VarPlayer.QUEST_HOLY_GRAIL),
|
||||||
HORROR_FROM_THE_DEEP(382, "Horror from the Deep"),
|
HORROR_FROM_THE_DEEP(382, "Horror from the Deep", Varbits.QUEST_HORROR_FROM_THE_DEEP),
|
||||||
ICTHLARINS_LITTLE_HELPER(383, "Icthlarin's Little Helper"),
|
ICTHLARINS_LITTLE_HELPER(383, "Icthlarin's Little Helper", Varbits.QUEST_ICTHLARINS_LITTLE_HELPER),
|
||||||
IN_AID_OF_THE_MYREQUE(384, "In Aid of the Myreque"),
|
IN_AID_OF_THE_MYREQUE(384, "In Aid of the Myreque", Varbits.QUEST_IN_AID_OF_THE_MYREQUE),
|
||||||
IN_SEARCH_OF_THE_MYREQUE(385, "In Search of the Myreque"),
|
IN_SEARCH_OF_THE_MYREQUE(385, "In Search of the Myreque", VarPlayer.QUEST_IN_SEARCH_OF_THE_MYREQUE),
|
||||||
JUNGLE_POTION(386, "Jungle Potion"),
|
JUNGLE_POTION(386, "Jungle Potion", VarPlayer.QUEST_JUNGLE_POTION),
|
||||||
KINGS_RANSOM(387, "King's Ransom"),
|
KINGS_RANSOM(387, "King's Ransom", Varbits.QUEST_KINGS_RANSOM),
|
||||||
LEGENDS_QUEST(388, "Legends' Quest"),
|
LEGENDS_QUEST(388, "Legends' Quest", VarPlayer.QUEST_LEGENDS_QUEST),
|
||||||
LOST_CITY(389, "Lost City"),
|
LOST_CITY(389, "Lost City", VarPlayer.QUEST_LOST_CITY),
|
||||||
THE_LOST_TRIBE(390, "The Lost Tribe"),
|
THE_LOST_TRIBE(390, "The Lost Tribe", Varbits.QUEST_THE_LOST_TRIBE),
|
||||||
LUNAR_DIPLOMACY(391, "Lunar Diplomacy"),
|
LUNAR_DIPLOMACY(391, "Lunar Diplomacy", Varbits.QUEST_LUNAR_DIPLOMACY),
|
||||||
MAKING_FRIENDS_WITH_MY_ARM(392, "Making Friends with My Arm"),
|
MAKING_FRIENDS_WITH_MY_ARM(392, "Making Friends with My Arm", Varbits.QUEST_MAKING_FRIENDS_WITH_MY_ARM),
|
||||||
MAKING_HISTORY(393, "Making History"),
|
MAKING_HISTORY(393, "Making History", Varbits.QUEST_MAKING_HISTORY),
|
||||||
MERLINS_CRYSTAL(394, "Merlin's Crystal"),
|
MERLINS_CRYSTAL(394, "Merlin's Crystal", VarPlayer.QUEST_MERLINS_CRYSTAL),
|
||||||
MONKEY_MADNESS_I(395, "Monkey Madness I"),
|
MONKEY_MADNESS_I(395, "Monkey Madness I", VarPlayer.QUEST_MONKEY_MADNESS_I),
|
||||||
MONKEY_MADNESS_II(396, "Monkey Madness II"),
|
MONKEY_MADNESS_II(396, "Monkey Madness II", Varbits.QUEST_MONKEY_MADNESS_II),
|
||||||
MONKS_FRIEND(397, "Monk's Friend"),
|
MONKS_FRIEND(397, "Monk's Friend", VarPlayer.QUEST_MONKS_FRIEND),
|
||||||
MOUNTAIN_DAUGHTER(398, "Mountain Daughter"),
|
MOUNTAIN_DAUGHTER(398, "Mountain Daughter", Varbits.QUEST_MOUNTAIN_DAUGHTER),
|
||||||
MOURNINGS_ENDS_PART_I(399, "Mourning's Ends Part I"),
|
MOURNINGS_ENDS_PART_I(399, "Mourning's Ends Part I", VarPlayer.QUEST_MOURNINGS_ENDS_PART_I),
|
||||||
MOURNINGS_ENDS_PART_II(400, "Mourning's Ends Part II"),
|
MOURNINGS_ENDS_PART_II(400, "Mourning's Ends Part II", Varbits.QUEST_MOURNINGS_ENDS_PART_II),
|
||||||
MURDER_MYSTERY(401, "Murder Mystery"),
|
MURDER_MYSTERY(401, "Murder Mystery", VarPlayer.QUEST_MURDER_MYSTERY),
|
||||||
MY_ARMS_BIG_ADVENTURE(402, "My Arm's Big Adventure"),
|
MY_ARMS_BIG_ADVENTURE(402, "My Arm's Big Adventure", Varbits.QUEST_MY_ARMS_BIG_ADVENTURE),
|
||||||
NATURE_SPIRIT(403, "Nature Spirit"),
|
NATURE_SPIRIT(403, "Nature Spirit", VarPlayer.QUEST_NATURE_SPIRIT),
|
||||||
OBSERVATORY_QUEST(404, "Observatory Quest"),
|
OBSERVATORY_QUEST(404, "Observatory Quest", VarPlayer.QUEST_OBSERVATORY_QUEST),
|
||||||
OLAFS_QUEST(405, "Olaf's Quest"),
|
OLAFS_QUEST(405, "Olaf's Quest", Varbits.QUEST_OLAFS_QUEST),
|
||||||
ONE_SMALL_FAVOUR(406, "One Small Favour"),
|
ONE_SMALL_FAVOUR(406, "One Small Favour", VarPlayer.QUEST_ONE_SMALL_FAVOUR),
|
||||||
PLAGUE_CITY(407, "Plague City"),
|
PLAGUE_CITY(407, "Plague City", VarPlayer.QUEST_PLAGUE_CITY),
|
||||||
PRIEST_IN_PERIL(408, "Priest in Peril"),
|
PRIEST_IN_PERIL(408, "Priest in Peril", VarPlayer.QUEST_PRIEST_IN_PERIL),
|
||||||
THE_QUEEN_OF_THIEVES(409, "The Queen of Thieves"),
|
THE_QUEEN_OF_THIEVES(409, "The Queen of Thieves", Varbits.QUEST_THE_QUEEN_OF_THIEVES),
|
||||||
RAG_AND_BONE_MAN(410, "Rag and Bone Man"),
|
RAG_AND_BONE_MAN(410, "Rag and Bone Man", VarPlayer.QUEST_RAG_AND_BONE_MAN),
|
||||||
RAG_AND_BONE_MAN_II(411, "Rag and Bone Man II"),
|
RAG_AND_BONE_MAN_II(411, "Rag and Bone Man II", VarPlayer.QUEST_RAG_AND_BONE_MAN_II),
|
||||||
RATCATCHERS(412, "Ratcatchers"),
|
RATCATCHERS(412, "Ratcatchers", Varbits.QUEST_RATCATCHERS),
|
||||||
RECIPE_FOR_DISASTER(413, "Recipe for Disaster"),
|
RECIPE_FOR_DISASTER(413, "Recipe for Disaster", Varbits.QUEST_RECIPE_FOR_DISASTER),
|
||||||
RECRUITMENT_DRIVE(414, "Recruitment Drive"),
|
RECRUITMENT_DRIVE(414, "Recruitment Drive", Varbits.QUEST_RECRUITMENT_DRIVE),
|
||||||
REGICIDE(415, "Regicide"),
|
REGICIDE(415, "Regicide", VarPlayer.QUEST_REGICIDE),
|
||||||
ROVING_ELVES(416, "Roving Elves"),
|
ROVING_ELVES(416, "Roving Elves", VarPlayer.QUEST_ROVING_ELVES),
|
||||||
ROYAL_TROUBLE(417, "Royal Trouble"),
|
ROYAL_TROUBLE(417, "Royal Trouble", Varbits.QUEST_ROYAL_TROUBLE),
|
||||||
RUM_DEAL(418, "Rum Deal"),
|
RUM_DEAL(418, "Rum Deal", VarPlayer.QUEST_RUM_DEAL),
|
||||||
SCORPION_CATCHER(419, "Scorpion Catcher"),
|
SCORPION_CATCHER(419, "Scorpion Catcher", VarPlayer.QUEST_SCORPION_CATCHER),
|
||||||
SEA_SLUG(420, "Sea Slug"),
|
SEA_SLUG(420, "Sea Slug", VarPlayer.QUEST_SEA_SLUG),
|
||||||
SHADES_OF_MORTTON(421, "Shades of Mort'ton"),
|
SHADES_OF_MORTTON(421, "Shades of Mort'ton", VarPlayer.QUEST_SHADES_OF_MORTTON),
|
||||||
SHADOW_OF_THE_STORM(422, "Shadow of the Storm"),
|
SHADOW_OF_THE_STORM(422, "Shadow of the Storm", Varbits.QUEST_SHADOW_OF_THE_STORM),
|
||||||
SHEEP_HERDER(423, "Sheep Herder"),
|
SHEEP_HERDER(423, "Sheep Herder", VarPlayer.QUEST_SHEEP_HERDER),
|
||||||
SHILO_VILLAGE(424, "Shilo Village"),
|
SHILO_VILLAGE(424, "Shilo Village", VarPlayer.QUEST_SHILO_VILLAGE),
|
||||||
THE_SLUG_MENACE(425, "The Slug Menace"),
|
THE_SLUG_MENACE(425, "The Slug Menace", Varbits.QUEST_THE_SLUG_MENACE),
|
||||||
A_SOULS_BANE(426, "A Soul's Bane"),
|
A_SOULS_BANE(426, "A Soul's Bane", Varbits.QUEST_A_SOULS_BANE),
|
||||||
SPIRITS_OF_THE_ELID(427, "Spirits of the Elid"),
|
SPIRITS_OF_THE_ELID(427, "Spirits of the Elid", Varbits.QUEST_SPIRITS_OF_THE_ELID),
|
||||||
SWAN_SONG(428, "Swan Song"),
|
SWAN_SONG(428, "Swan Song", Varbits.QUEST_SWAN_SONG),
|
||||||
TAI_BWO_WANNAI_TRIO(429, "Tai Bwo Wannai Trio"),
|
TAI_BWO_WANNAI_TRIO(429, "Tai Bwo Wannai Trio", VarPlayer.QUEST_TAI_BWO_WANNAI_TRIO),
|
||||||
A_TAIL_OF_TWO_CATS(430, "A Tail of Two Cats"),
|
A_TAIL_OF_TWO_CATS(430, "A Tail of Two Cats", Varbits.QUEST_A_TAIL_OF_TWO_CATS),
|
||||||
TALE_OF_THE_RIGHTEOUS(431, "Tale of the Righteous"),
|
TALE_OF_THE_RIGHTEOUS(431, "Tale of the Righteous", Varbits.QUEST_TALE_OF_THE_RIGHTEOUS),
|
||||||
A_TASTE_OF_HOPE(432, "A Taste of Hope"),
|
A_TASTE_OF_HOPE(432, "A Taste of Hope", Varbits.QUEST_A_TASTE_OF_HOPE),
|
||||||
TEARS_OF_GUTHIX(433, "Tears of Guthix"),
|
TEARS_OF_GUTHIX(433, "Tears of Guthix", Varbits.QUEST_TEARS_OF_GUTHIX),
|
||||||
TEMPLE_OF_IKOV(434, "Temple of Ikov"),
|
TEMPLE_OF_IKOV(434, "Temple of Ikov", VarPlayer.QUEST_TEMPLE_OF_IKOV),
|
||||||
THRONE_OF_MISCELLANIA(435, "Throne of Miscellania"),
|
THRONE_OF_MISCELLANIA(435, "Throne of Miscellania", VarPlayer.QUEST_THRONE_OF_MISCELLANIA),
|
||||||
THE_TOURIST_TRAP(436, "The Tourist Trap"),
|
THE_TOURIST_TRAP(436, "The Tourist Trap", VarPlayer.QUEST_THE_TOURIST_TRAP),
|
||||||
TOWER_OF_LIFE(437, "Tower of Life"),
|
TOWER_OF_LIFE(437, "Tower of Life", Varbits.QUEST_TOWER_OF_LIFE),
|
||||||
TREE_GNOME_VILLAGE(438, "Tree Gnome Village"),
|
TREE_GNOME_VILLAGE(438, "Tree Gnome Village", VarPlayer.QUEST_TREE_GNOME_VILLAGE),
|
||||||
TRIBAL_TOTEM(439, "Tribal Totem"),
|
TRIBAL_TOTEM(439, "Tribal Totem", VarPlayer.QUEST_TRIBAL_TOTEM),
|
||||||
TROLL_ROMANCE(440, "Troll Romance"),
|
TROLL_ROMANCE(440, "Troll Romance", VarPlayer.QUEST_TROLL_ROMANCE),
|
||||||
TROLL_STRONGHOLD(441, "Troll Stronghold"),
|
TROLL_STRONGHOLD(441, "Troll Stronghold", VarPlayer.QUEST_TROLL_STRONGHOLD),
|
||||||
UNDERGROUND_PASS(442, "Underground Pass"),
|
UNDERGROUND_PASS(442, "Underground Pass", VarPlayer.QUEST_UNDERGROUND_PASS),
|
||||||
CLIENT_OF_KOUREND(443, "Client of Kourend"),
|
CLIENT_OF_KOUREND(443, "Client of Kourend", Varbits.QUEST_CLIENT_OF_KOUREND),
|
||||||
WANTED(444, "Wanted!"),
|
WANTED(444, "Wanted!", Varbits.QUEST_WANTED),
|
||||||
WATCHTOWER(445, "Watchtower"),
|
WATCHTOWER(445, "Watchtower", VarPlayer.QUEST_WATCHTOWER),
|
||||||
WATERFALL_QUEST(446, "Waterfall Quest"),
|
WATERFALL_QUEST(446, "Waterfall Quest", VarPlayer.QUEST_WATERFALL_QUEST),
|
||||||
WHAT_LIES_BELOW(447, "What Lies Below"),
|
WHAT_LIES_BELOW(447, "What Lies Below", Varbits.QUEST_WHAT_LIES_BELOW),
|
||||||
WITCHS_HOUSE(448, "Witch's House"),
|
WITCHS_HOUSE(448, "Witch's House", VarPlayer.QUEST_WITCHS_HOUSE),
|
||||||
ZOGRE_FLESH_EATERS(449, "Zogre Flesh Eaters"),
|
ZOGRE_FLESH_EATERS(449, "Zogre Flesh Eaters", Varbits.QUEST_ZOGRE_FLESH_EATERS),
|
||||||
THE_ASCENT_OF_ARCEUUS(542, "The Ascent of Arceuus"),
|
THE_ASCENT_OF_ARCEUUS(542, "The Ascent of Arceuus", Varbits.QUEST_THE_ASCENT_OF_ARCEUUS),
|
||||||
THE_FORSAKEN_TOWER(543, "The Forsaken Tower"),
|
THE_FORSAKEN_TOWER(543, "The Forsaken Tower", Varbits.QUEST_THE_FORSAKEN_TOWER),
|
||||||
|
|
||||||
//Miniquests
|
//Miniquests
|
||||||
ENTER_THE_ABYSS(319, "Enter the Abyss"),
|
ENTER_THE_ABYSS(319, "Enter the Abyss", VarPlayer.QUEST_ENTER_THE_ABYSS),
|
||||||
ARCHITECTURAL_ALLIANCE(320, "Architectural Alliance"),
|
ARCHITECTURAL_ALLIANCE(320, "Architectural Alliance", Varbits.QUEST_ARCHITECTURAL_ALLIANCE),
|
||||||
BEAR_YOUR_SOUL(321, "Bear your Soul"),
|
BEAR_YOUR_SOUL(321, "Bear your Soul", Varbits.QUEST_BEAR_YOUR_SOUL),
|
||||||
ALFRED_GRIMHANDS_BARCRAWL(322, "Alfred Grimhand's Barcrawl"),
|
ALFRED_GRIMHANDS_BARCRAWL(322, "Alfred Grimhand's Barcrawl", VarPlayer.QUEST_ALFRED_GRIMHANDS_BARCRAWL),
|
||||||
CURSE_OF_THE_EMPTY_LORD(323, "Curse of the Empty Lord"),
|
CURSE_OF_THE_EMPTY_LORD(323, "Curse of the Empty Lord", Varbits.QUEST_CURSE_OF_THE_EMPTY_LORD),
|
||||||
ENCHANTED_KEY(324, "Enchanted Key"),
|
ENCHANTED_KEY(324, "Enchanted Key", Varbits.QUEST_ENCHANTED_KEY),
|
||||||
THE_GENERALS_SHADOW(325, "The General's Shadow"),
|
THE_GENERALS_SHADOW(325, "The General's Shadow", Varbits.QUEST_THE_GENERALS_SHADOW),
|
||||||
SKIPPY_AND_THE_MOGRES(326, "Skippy and the Mogres"),
|
SKIPPY_AND_THE_MOGRES(326, "Skippy and the Mogres", Varbits.QUEST_SKIPPY_AND_THE_MOGRES),
|
||||||
THE_MAGE_ARENA(327, "The Mage Arena"),
|
THE_MAGE_ARENA(327, "The Mage Arena", VarPlayer.QUEST_THE_MAGE_ARENA),
|
||||||
LAIR_OF_TARN_RAZORLOR(328, "Lair of Tarn Razorlor"),
|
LAIR_OF_TARN_RAZORLOR(328, "Lair of Tarn Razorlor", Varbits.QUEST_LAIR_OF_TARN_RAZORLOR),
|
||||||
FAMILY_PEST(329, "Family Pest"),
|
FAMILY_PEST(329, "Family Pest", Varbits.QUEST_FAMILY_PEST),
|
||||||
THE_MAGE_ARENA_II(330, "The Mage Arena II");
|
THE_MAGE_ARENA_II(330, "The Mage Arena II", Varbits.QUEST_THE_MAGE_ARENA_II);
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final int id;
|
private final int id;
|
||||||
@@ -195,6 +194,26 @@ public enum Quest
|
|||||||
@Getter
|
@Getter
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
|
private final Varbits varbit;
|
||||||
|
|
||||||
|
private final VarPlayer varPlayer;
|
||||||
|
|
||||||
|
Quest(int id, String name, Varbits varbit)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.varbit = varbit;
|
||||||
|
this.varPlayer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quest(int id, String name, VarPlayer varPlayer)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.varbit = null;
|
||||||
|
this.varPlayer = varPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
public QuestState getState(Client client)
|
public QuestState getState(Client client)
|
||||||
{
|
{
|
||||||
client.runScript(ScriptID.QUESTLIST_PROGRESS, id);
|
client.runScript(ScriptID.QUESTLIST_PROGRESS, id);
|
||||||
@@ -208,4 +227,16 @@ public enum Quest
|
|||||||
return QuestState.IN_PROGRESS;
|
return QuestState.IN_PROGRESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getVar(Client client)
|
||||||
|
{
|
||||||
|
if (varbit != null)
|
||||||
|
{
|
||||||
|
return client.getVar(varbit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return client.getVar(varPlayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,7 +163,101 @@ public enum VarPlayer
|
|||||||
MUSIC_TRACKS_UNLOCKED_16(1009),
|
MUSIC_TRACKS_UNLOCKED_16(1009),
|
||||||
MUSIC_TRACKS_UNLOCKED_17(1338),
|
MUSIC_TRACKS_UNLOCKED_17(1338),
|
||||||
MUSIC_TRACKS_UNLOCKED_18(1681),
|
MUSIC_TRACKS_UNLOCKED_18(1681),
|
||||||
MUSIC_TRACKS_UNLOCKED_19(2065);
|
MUSIC_TRACKS_UNLOCKED_19(2065),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* f2p Quest varbits, these don't hold the completion value.
|
||||||
|
*/
|
||||||
|
QUEST_BLACK_KNIGHTS_FORTRESS(130),
|
||||||
|
QUEST_COOKS_ASSISTANT(29),
|
||||||
|
QUEST_DORICS_QUEST(31),
|
||||||
|
QUEST_DRAGON_SLAYER(176),
|
||||||
|
QUEST_ERNEST_THE_CHICKEN(32),
|
||||||
|
QUEST_IMP_CATCHER(160),
|
||||||
|
QUEST_THE_KNIGHTS_SWORD(122),
|
||||||
|
QUEST_PIRATES_TREASURE(71),
|
||||||
|
QUEST_PRINCE_ALI_RESCUE(273),
|
||||||
|
QUEST_THE_RESTLESS_GHOST(107),
|
||||||
|
QUEST_ROMEO_AND_JULIET(144),
|
||||||
|
QUEST_RUNE_MYSTERIES(63),
|
||||||
|
QUEST_SHEEP_SHEARER(179),
|
||||||
|
QUEST_SHIELD_OF_ARRAV(145),
|
||||||
|
QUEST_SHIELD_OF_ARRAV_STATE_146(146),
|
||||||
|
QUEST_VAMPIRE_SLAYER(178),
|
||||||
|
QUEST_WITCHS_POTION(67),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* member Quest varbits, these don't hold the completion value.
|
||||||
|
*/
|
||||||
|
QUEST_BIG_CHOMPY_BIRD_HUNTING(293),
|
||||||
|
QUEST_BIOHAZARD(68),
|
||||||
|
QUEST_CABIN_FEVER(655),
|
||||||
|
QUEST_CLOCK_TOWER(10),
|
||||||
|
QUEST_CREATURE_OF_FENKENSTRAIN(399),
|
||||||
|
QUEST_DEATH_PLATEAU(314),
|
||||||
|
QUEST_THE_DIG_SITE(131),
|
||||||
|
QUEST_DRUIDIC_RITUAL(80),
|
||||||
|
QUEST_DWARF_CANNON(0),
|
||||||
|
QUEST_EADGARS_RUSE(335),
|
||||||
|
QUEST_ELEMENTAL_WORKSHOP_I(299),
|
||||||
|
QUEST_FAMILY_CREST(148),
|
||||||
|
QUEST_FIGHT_ARENA(17),
|
||||||
|
QUEST_FISHING_CONTEST(11),
|
||||||
|
QUEST_THE_FREMENNIK_TRIALS(347),
|
||||||
|
QUEST_WATERFALL_QUEST(65),
|
||||||
|
QUEST_GERTRUDES_CAT(180),
|
||||||
|
QUEST_THE_GRAND_TREE(150),
|
||||||
|
QUEST_HAUNTED_MINE(382),
|
||||||
|
QUEST_HAZEEL_CULT(223),
|
||||||
|
QUEST_HEROES_QUEST(188),
|
||||||
|
QUEST_HOLY_GRAIL(5),
|
||||||
|
QUEST_IN_SEARCH_OF_THE_MYREQUE(387),
|
||||||
|
QUEST_JUNGLE_POTION(175),
|
||||||
|
QUEST_LEGENDS_QUEST(139),
|
||||||
|
QUEST_LOST_CITY(147),
|
||||||
|
QUEST_MERLINS_CRYSTAL(14),
|
||||||
|
QUEST_MONKEY_MADNESS_I(365),
|
||||||
|
QUEST_MONKS_FRIEND(30),
|
||||||
|
QUEST_MOURNINGS_ENDS_PART_I(517),
|
||||||
|
QUEST_MURDER_MYSTERY(192),
|
||||||
|
QUEST_NATURE_SPIRIT(307),
|
||||||
|
QUEST_OBSERVATORY_QUEST(112),
|
||||||
|
QUEST_ONE_SMALL_FAVOUR(416),
|
||||||
|
QUEST_PLAGUE_CITY(165),
|
||||||
|
QUEST_PRIEST_IN_PERIL(302),
|
||||||
|
QUEST_RAG_AND_BONE_MAN(714),
|
||||||
|
QUEST_REGICIDE(328),
|
||||||
|
QUEST_ROVING_ELVES(402),
|
||||||
|
QUEST_RUM_DEAL(600),
|
||||||
|
QUEST_SCORPION_CATCHER(76),
|
||||||
|
QUEST_SEA_SLUG(159),
|
||||||
|
QUEST_SHADES_OF_MORTTON(339),
|
||||||
|
QUEST_SHEEP_HERDER(60),
|
||||||
|
QUEST_SHILO_VILLAGE(116),
|
||||||
|
QUEST_TAI_BWO_WANNAI_TRIO(320),
|
||||||
|
QUEST_TEMPLE_OF_IKOV(26),
|
||||||
|
QUEST_THRONE_OF_MISCELLANIA(359),
|
||||||
|
QUEST_THE_TOURIST_TRAP(197),
|
||||||
|
QUEST_WITCHS_HOUSE(226),
|
||||||
|
QUEST_TREE_GNOME_VILLAGE(111),
|
||||||
|
QUEST_TRIBAL_TOTEM(200),
|
||||||
|
QUEST_TROLL_ROMANCE(385),
|
||||||
|
QUEST_TROLL_STRONGHOLD(317),
|
||||||
|
QUEST_UNDERGROUND_PASS(161),
|
||||||
|
QUEST_UNDERGROUND_PASS_STATE_162(162),
|
||||||
|
QUEST_WATCHTOWER(212),
|
||||||
|
QUEST_THE_GREAT_BRAIN_ROBBERY(980),
|
||||||
|
QUEST_RAG_AND_BONE_MAN_II(714),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mini-quest varbits, these don't hold the completion value.
|
||||||
|
*/
|
||||||
|
QUEST_ENTER_THE_ABYSS(492),
|
||||||
|
QUEST_ALFRED_GRIMHANDS_BARCRAWL(77),
|
||||||
|
QUEST_ALFRED_GRIMHANDS_BARCRAWL_STATE_76(76),
|
||||||
|
QUEST_THE_MAGE_ARENA(267);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -503,7 +503,95 @@ public enum Varbits
|
|||||||
TREK_STARTED(1956),
|
TREK_STARTED(1956),
|
||||||
TREK_EVENT(1958),
|
TREK_EVENT(1958),
|
||||||
TREK_STATUS(6719),
|
TREK_STATUS(6719),
|
||||||
BLOAT_ENTERED_ROOM(6447);
|
BLOAT_ENTERED_ROOM(6447),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* f2p Quest varbits, these don't hold the completion value.
|
||||||
|
*/
|
||||||
|
QUEST_DEMON_SLAYER(2561),
|
||||||
|
QUEST_GOBLIN_DIPLOMACY(2378),
|
||||||
|
QUEST_MISTHALIN_MYSTERY(3468),
|
||||||
|
QUEST_THE_CORSAIR_CURSE(6071),
|
||||||
|
QUEST_X_MARKS_THE_SPOT(8063),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* member Quest varbits, these don't hold the completion value.
|
||||||
|
*/
|
||||||
|
QUEST_ANIMAL_MAGNETISM(3185),
|
||||||
|
QUEST_BETWEEN_A_ROCK(299),
|
||||||
|
QUEST_CONTACT(3274),
|
||||||
|
QUEST_ZOGRE_FLESH_EATERS(487),
|
||||||
|
QUEST_DARKNESS_OF_HALLOWVALE(2573),
|
||||||
|
QUEST_DEATH_TO_THE_DORGESHUUN(2258),
|
||||||
|
QUEST_DESERT_TREASURE(358),
|
||||||
|
QUEST_DEVIOUS_MINDS(1465),
|
||||||
|
QUEST_EAGLES_PEAK(2780),
|
||||||
|
QUEST_ELEMENTAL_WORKSHOP_II(2639),
|
||||||
|
QUEST_ENAKHRAS_LAMENT(1560),
|
||||||
|
QUEST_ENLIGHTENED_JOURNEY(2866),
|
||||||
|
QUEST_THE_EYES_OF_GLOUPHRIE(2497),
|
||||||
|
QUEST_FAIRYTALE_I_GROWING_PAINS(1803),
|
||||||
|
QUEST_FAIRYTALE_II_CURE_A_QUEEN(2326),
|
||||||
|
QUEST_THE_FEUD(334),
|
||||||
|
QUEST_FORGETTABLE_TALE(822),
|
||||||
|
QUEST_GARDEN_OF_TRANQUILLITY(961),
|
||||||
|
QUEST_GHOSTS_AHOY(217),
|
||||||
|
QUEST_THE_GIANT_DWARF(571),
|
||||||
|
QUEST_THE_GOLEM(346),
|
||||||
|
QUEST_HORROR_FROM_THE_DEEP(34),
|
||||||
|
QUEST_ICTHLARINS_LITTLE_HELPER(418),
|
||||||
|
QUEST_IN_AID_OF_THE_MYREQUE(1990),
|
||||||
|
QUEST_THE_LOST_TRIBE(532),
|
||||||
|
QUEST_LUNAR_DIPLOMACY(2448),
|
||||||
|
QUEST_MAKING_HISTORY(1383),
|
||||||
|
QUEST_MOUNTAIN_DAUGHTER(260),
|
||||||
|
QUEST_MOURNINGS_ENDS_PART_II(1103),
|
||||||
|
QUEST_MY_ARMS_BIG_ADVENTURE(2790),
|
||||||
|
QUEST_RATCATCHERS(1404),
|
||||||
|
QUEST_RECIPE_FOR_DISASTER(1850),
|
||||||
|
QUEST_RECRUITMENT_DRIVE(657),
|
||||||
|
QUEST_ROYAL_TROUBLE(2140),
|
||||||
|
QUEST_THE_SLUG_MENACE(2610),
|
||||||
|
QUEST_SHADOW_OF_THE_STORM(1372),
|
||||||
|
QUEST_A_SOULS_BANE(2011),
|
||||||
|
QUEST_SPIRITS_OF_THE_ELID(1444),
|
||||||
|
QUEST_SWAN_SONG(2098),
|
||||||
|
QUEST_A_TAIL_OF_TWO_CATS(1028),
|
||||||
|
QUEST_TEARS_OF_GUTHIX(451),
|
||||||
|
QUEST_WANTED(1051),
|
||||||
|
QUEST_COLD_WAR(3293),
|
||||||
|
QUEST_THE_FREMENNIK_ISLES(3311),
|
||||||
|
QUEST_TOWER_OF_LIFE(3337),
|
||||||
|
QUEST_WHAT_LIES_BELOW(3523),
|
||||||
|
QUEST_OLAFS_QUEST(3534),
|
||||||
|
QUEST_ANOTHER_SLICE_OF_HAM(3550),
|
||||||
|
QUEST_DREAM_MENTOR(3618),
|
||||||
|
QUEST_GRIM_TALES(2783),
|
||||||
|
QUEST_KINGS_RANSOM(3888),
|
||||||
|
QUEST_MONKEY_MADNESS_II(5027),
|
||||||
|
QUEST_CLIENT_OF_KOUREND(5619),
|
||||||
|
QUEST_BONE_VOYAGE(5795),
|
||||||
|
QUEST_THE_QUEEN_OF_THIEVES(6037),
|
||||||
|
QUEST_THE_DEPTHS_OF_DESPAIR(6027),
|
||||||
|
QUEST_DRAGON_SLAYER_II(6104),
|
||||||
|
QUEST_TALE_OF_THE_RIGHTEOUS(6358),
|
||||||
|
QUEST_A_TASTE_OF_HOPE(6396),
|
||||||
|
QUEST_MAKING_FRIENDS_WITH_MY_ARM(6528),
|
||||||
|
QUEST_THE_ASCENT_OF_ARCEUUS(7856),
|
||||||
|
QUEST_THE_FORSAKEN_TOWER(7796),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mini-quest varbits, these don't hold the completion value.
|
||||||
|
*/
|
||||||
|
QUEST_ARCHITECTURAL_ALLIANCE(4982),
|
||||||
|
QUEST_BEAR_YOUR_SOUL(5078),
|
||||||
|
QUEST_CURSE_OF_THE_EMPTY_LORD(821),
|
||||||
|
QUEST_ENCHANTED_KEY(1391),
|
||||||
|
QUEST_THE_GENERALS_SHADOW(3330),
|
||||||
|
QUEST_SKIPPY_AND_THE_MOGRES(1344),
|
||||||
|
QUEST_LAIR_OF_TARN_RAZORLOR(3290),
|
||||||
|
QUEST_FAMILY_PEST(5347),
|
||||||
|
QUEST_THE_MAGE_ARENA_II(6067);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The raw varbit ID.
|
* The raw varbit ID.
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ import net.runelite.client.ui.RuneLiteSplashScreen;
|
|||||||
import net.runelite.client.ui.overlay.OverlayManager;
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
import net.runelite.client.ui.overlay.OverlayRenderer;
|
import net.runelite.client.ui.overlay.OverlayRenderer;
|
||||||
import net.runelite.client.ui.overlay.WidgetOverlay;
|
import net.runelite.client.ui.overlay.WidgetOverlay;
|
||||||
|
import net.runelite.client.ui.overlay.arrow.ArrowMinimapOverlay;
|
||||||
|
import net.runelite.client.ui.overlay.arrow.ArrowWorldOverlay;
|
||||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||||
import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay;
|
import net.runelite.client.ui.overlay.infobox.InfoBoxOverlay;
|
||||||
import net.runelite.client.ui.overlay.tooltip.TooltipOverlay;
|
import net.runelite.client.ui.overlay.tooltip.TooltipOverlay;
|
||||||
@@ -148,6 +150,12 @@ public class RuneLite
|
|||||||
@Inject
|
@Inject
|
||||||
private Provider<WorldMapOverlay> worldMapOverlay;
|
private Provider<WorldMapOverlay> worldMapOverlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Provider<ArrowWorldOverlay> arrowWorldOverlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Provider<ArrowMinimapOverlay> arrowMinimapOverlay;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Provider<LootManager> lootManager;
|
private Provider<LootManager> lootManager;
|
||||||
|
|
||||||
@@ -323,6 +331,8 @@ public class RuneLite
|
|||||||
overlayManager.add(infoBoxOverlay.get());
|
overlayManager.add(infoBoxOverlay.get());
|
||||||
overlayManager.add(worldMapOverlay.get());
|
overlayManager.add(worldMapOverlay.get());
|
||||||
overlayManager.add(tooltipOverlay.get());
|
overlayManager.add(tooltipOverlay.get());
|
||||||
|
overlayManager.add(arrowWorldOverlay.get());
|
||||||
|
overlayManager.add(arrowMinimapOverlay.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start plugins
|
// Start plugins
|
||||||
|
|||||||
@@ -0,0 +1,162 @@
|
|||||||
|
package net.runelite.client.plugins.example;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.GameState;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.SpriteID;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.client.callback.ClientThread;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.game.SpriteManager;
|
||||||
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
|
import net.runelite.client.plugins.cluescrolls.clues.emote.STASHUnit;
|
||||||
|
import net.runelite.client.ui.overlay.arrow.ArrowPoint;
|
||||||
|
import net.runelite.client.ui.overlay.arrow.ArrowPointManager;
|
||||||
|
import net.runelite.client.ui.overlay.arrow.ArrowType;
|
||||||
|
|
||||||
|
@PluginDescriptor(
|
||||||
|
name = "ArrowTest",
|
||||||
|
developerPlugin = true
|
||||||
|
)
|
||||||
|
public class ExamplePlugin extends Plugin
|
||||||
|
{
|
||||||
|
@Inject
|
||||||
|
private ArrowPointManager arrowPointManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SpriteManager spriteManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ItemManager itemManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ClientThread clientThread;
|
||||||
|
|
||||||
|
private boolean firstLogin = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startUp() throws Exception
|
||||||
|
{
|
||||||
|
clientThread.invokeLater(this::loadArrows);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutDown()
|
||||||
|
{
|
||||||
|
arrowPointManager.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadArrows()
|
||||||
|
{
|
||||||
|
if (client.getGameState() != GameState.LOGGED_IN)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedImage i = spriteManager.getSprite(SpriteID.MINIMAP_GUIDE_ARROW_YELLOW, 0);
|
||||||
|
|
||||||
|
BufferedImage i3 = spriteManager.getSprite(SpriteID.RED_GUIDE_ARROW, 0);
|
||||||
|
AffineTransform at = new AffineTransform();
|
||||||
|
at.concatenate(AffineTransform.getScaleInstance(1, -1));
|
||||||
|
at.concatenate(AffineTransform.getTranslateInstance(0, -i3.getHeight()));
|
||||||
|
BufferedImage i4 = new BufferedImage(i3.getWidth(), i3.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D g = i4.createGraphics();
|
||||||
|
g.transform(at);
|
||||||
|
g.drawImage(i3, 0, 0, null);
|
||||||
|
g.dispose();
|
||||||
|
|
||||||
|
Point i3Offset = new Point(0, i3.getHeight() / -2);
|
||||||
|
|
||||||
|
ArrowPoint one = ArrowPoint.builder()
|
||||||
|
.worldPoint(new WorldPoint(1554, 3551, 0))
|
||||||
|
.minimapImage(i4)
|
||||||
|
.worldImage(i)
|
||||||
|
.minimapImageOffset(i3Offset)
|
||||||
|
.types(EnumSet.of(ArrowType.MINIMAP, ArrowType.WORLD_POINT))
|
||||||
|
.build();
|
||||||
|
//arrowPointManager.add(this, one);
|
||||||
|
|
||||||
|
ArrowPoint two = ArrowPoint.builder()
|
||||||
|
.worldPoint(new WorldPoint(1544, 3580, 0))
|
||||||
|
.minimapImage(i4)
|
||||||
|
.worldImage(i)
|
||||||
|
.minimapImageOffset(i3Offset)
|
||||||
|
.types(EnumSet.of(ArrowType.MINIMAP, ArrowType.WORLD_POINT))
|
||||||
|
.build();
|
||||||
|
//arrowPointManager.add(this, two);
|
||||||
|
|
||||||
|
ArrowPoint three = ArrowPoint.builder()
|
||||||
|
.worldPoint(new WorldPoint(1571, 3541, 0))
|
||||||
|
.minimapImage(i4)
|
||||||
|
.worldImage(i)
|
||||||
|
.minimapImageOffset(i3Offset)
|
||||||
|
.types(EnumSet.of(ArrowType.MINIMAP, ArrowType.WORLD_POINT))
|
||||||
|
.build();
|
||||||
|
//arrowPointManager.add(this, three);
|
||||||
|
|
||||||
|
HashSet<Integer> NPCs = new HashSet<>();
|
||||||
|
NPCs.add(6910);
|
||||||
|
|
||||||
|
ArrowPoint npcone = ArrowPoint.builder()
|
||||||
|
.worldPoint(new WorldPoint(1545, 3595, 0))
|
||||||
|
.minimapImage(i4)
|
||||||
|
.worldImage(i)
|
||||||
|
.minimapImageOffset(i3Offset)
|
||||||
|
.npcIDs(NPCs)
|
||||||
|
.types(EnumSet.of(ArrowType.MINIMAP, ArrowType.NPC))
|
||||||
|
.build();
|
||||||
|
//arrowPointManager.add(this, npcone);
|
||||||
|
|
||||||
|
HashSet<Integer> NPCs2 = new HashSet<>();
|
||||||
|
NPCs2.add(6889);
|
||||||
|
NPCs2.add(6883);
|
||||||
|
NPCs2.add(6885);
|
||||||
|
|
||||||
|
ArrowPoint npctwo = ArrowPoint.builder()
|
||||||
|
.worldPoint(new WorldPoint(1551, 3561, 0))
|
||||||
|
.minimapImage(i4)
|
||||||
|
.worldImage(i)
|
||||||
|
.minimapImageOffset(i3Offset)
|
||||||
|
.worldImageOffset(new Point(0, -i4.getHeight()))
|
||||||
|
.npcIDs(NPCs2)
|
||||||
|
.types(EnumSet.of(ArrowType.MINIMAP, ArrowType.NPC))
|
||||||
|
.build();
|
||||||
|
//arrowPointManager.add(this, npctwo);
|
||||||
|
|
||||||
|
HashSet<Integer> OBJs = new HashSet<>();
|
||||||
|
OBJs.add(STASHUnit.SHAYZIEN_WAR_TENT);
|
||||||
|
|
||||||
|
ArrowPoint objone = ArrowPoint.builder()
|
||||||
|
.worldPoint(new WorldPoint(1550, 3541, 0))
|
||||||
|
.minimapImage(i4)
|
||||||
|
.worldImage(i)
|
||||||
|
.minimapImageOffset(i3Offset)
|
||||||
|
.worldImageOffset(new Point(0, -i4.getHeight()))
|
||||||
|
.objectIDs(OBJs)
|
||||||
|
.types(EnumSet.of(ArrowType.MINIMAP, ArrowType.OBJECT))
|
||||||
|
.build();
|
||||||
|
arrowPointManager.add(this, objone);
|
||||||
|
|
||||||
|
BufferedImage i5 = itemManager.getImage(ItemID.BONES);
|
||||||
|
|
||||||
|
ArrowPoint four = ArrowPoint.builder()
|
||||||
|
.worldPoint(new WorldPoint(1517, 3553, 0))
|
||||||
|
.minimapImage(i5)
|
||||||
|
.worldImage(i5)
|
||||||
|
.minimapImagePointToTarget(false)
|
||||||
|
.types(EnumSet.of(ArrowType.MINIMAP, ArrowType.WORLD_POINT))
|
||||||
|
.build();
|
||||||
|
//arrowPointManager.add(this, four);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -64,11 +64,33 @@ public interface IdleNotifierConfig extends Config
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 4,
|
||||||
|
keyName = "skullNotification",
|
||||||
|
name = "Skull Notification",
|
||||||
|
description = "Receive a notification when you skull."
|
||||||
|
)
|
||||||
|
default boolean showSkullNotification()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 5,
|
||||||
|
keyName = "unskullNotification",
|
||||||
|
name = "Unskull Notification",
|
||||||
|
description = "Receive a notification when you unskull."
|
||||||
|
)
|
||||||
|
default boolean showUnskullNotification()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "timeout",
|
keyName = "timeout",
|
||||||
name = "Idle Notification Delay (ms)",
|
name = "Idle Notification Delay (ms)",
|
||||||
description = "The notification delay after the player is idle",
|
description = "The notification delay after the player is idle",
|
||||||
position = 4
|
position = 6
|
||||||
)
|
)
|
||||||
default int getIdleNotificationDelay()
|
default int getIdleNotificationDelay()
|
||||||
{
|
{
|
||||||
@@ -79,7 +101,7 @@ public interface IdleNotifierConfig extends Config
|
|||||||
keyName = "hitpoints",
|
keyName = "hitpoints",
|
||||||
name = "Hitpoints Notification Threshold",
|
name = "Hitpoints Notification Threshold",
|
||||||
description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.",
|
description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.",
|
||||||
position = 5
|
position = 7
|
||||||
)
|
)
|
||||||
default int getHitpointsThreshold()
|
default int getHitpointsThreshold()
|
||||||
{
|
{
|
||||||
@@ -90,7 +112,7 @@ public interface IdleNotifierConfig extends Config
|
|||||||
keyName = "prayer",
|
keyName = "prayer",
|
||||||
name = "Prayer Notification Threshold",
|
name = "Prayer Notification Threshold",
|
||||||
description = "The amount of prayer points to send a notification at. A value of 0 will disable notification.",
|
description = "The amount of prayer points to send a notification at. A value of 0 will disable notification.",
|
||||||
position = 6
|
position = 8
|
||||||
)
|
)
|
||||||
default int getPrayerThreshold()
|
default int getPrayerThreshold()
|
||||||
{
|
{
|
||||||
@@ -100,7 +122,7 @@ public interface IdleNotifierConfig extends Config
|
|||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "oxygen",
|
keyName = "oxygen",
|
||||||
name = "Oxygen Notification Threshold",
|
name = "Oxygen Notification Threshold",
|
||||||
position = 7,
|
position = 9,
|
||||||
description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification."
|
description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification."
|
||||||
)
|
)
|
||||||
default int getOxygenThreshold()
|
default int getOxygenThreshold()
|
||||||
@@ -111,7 +133,7 @@ public interface IdleNotifierConfig extends Config
|
|||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "spec",
|
keyName = "spec",
|
||||||
name = "Special Attack Energy Notification Threshold",
|
name = "Special Attack Energy Notification Threshold",
|
||||||
position = 8,
|
position = 10,
|
||||||
description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification."
|
description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification."
|
||||||
)
|
)
|
||||||
default int getSpecEnergyThreshold()
|
default int getSpecEnergyThreshold()
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import java.awt.*;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import net.runelite.api.Actor;
|
import net.runelite.api.Actor;
|
||||||
@@ -44,8 +45,10 @@ import net.runelite.api.NPC;
|
|||||||
import net.runelite.api.NPCComposition;
|
import net.runelite.api.NPCComposition;
|
||||||
import net.runelite.api.Player;
|
import net.runelite.api.Player;
|
||||||
import net.runelite.api.Skill;
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.api.SkullIcon;
|
||||||
import net.runelite.api.VarPlayer;
|
import net.runelite.api.VarPlayer;
|
||||||
import net.runelite.api.Varbits;
|
import net.runelite.api.Varbits;
|
||||||
|
import net.runelite.api.WorldType;
|
||||||
import net.runelite.api.events.AnimationChanged;
|
import net.runelite.api.events.AnimationChanged;
|
||||||
import net.runelite.api.events.GameStateChanged;
|
import net.runelite.api.events.GameStateChanged;
|
||||||
import net.runelite.api.events.GameTick;
|
import net.runelite.api.events.GameTick;
|
||||||
@@ -100,6 +103,8 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
private Instant sixHourWarningTime;
|
private Instant sixHourWarningTime;
|
||||||
private boolean ready;
|
private boolean ready;
|
||||||
private boolean lastInteractWasCombat;
|
private boolean lastInteractWasCombat;
|
||||||
|
private SkullIcon lastTickSkull = null;
|
||||||
|
private boolean isFirstTick = true;
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
IdleNotifierConfig provideConfig(ConfigManager configManager)
|
IdleNotifierConfig provideConfig(ConfigManager configManager)
|
||||||
@@ -327,9 +332,13 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
case LOGIN_SCREEN:
|
case LOGIN_SCREEN:
|
||||||
resetTimers();
|
resetTimers();
|
||||||
|
isFirstTick = true;
|
||||||
|
break;
|
||||||
|
case HOPPING:
|
||||||
|
isFirstTick = true;
|
||||||
|
ready = true;
|
||||||
break;
|
break;
|
||||||
case LOGGING_IN:
|
case LOGGING_IN:
|
||||||
case HOPPING:
|
|
||||||
case CONNECTION_LOST:
|
case CONNECTION_LOST:
|
||||||
ready = true;
|
ready = true;
|
||||||
break;
|
break;
|
||||||
@@ -381,6 +390,8 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
@Subscribe
|
@Subscribe
|
||||||
public void onGameTick(GameTick event)
|
public void onGameTick(GameTick event)
|
||||||
{
|
{
|
||||||
|
skullNotifier();
|
||||||
|
|
||||||
final Player local = client.getLocalPlayer();
|
final Player local = client.getLocalPlayer();
|
||||||
final Duration waitDuration = Duration.ofMillis(config.getIdleNotificationDelay());
|
final Duration waitDuration = Duration.ofMillis(config.getIdleNotificationDelay());
|
||||||
lastCombatCountdown = Math.max(lastCombatCountdown - 1, 0);
|
lastCombatCountdown = Math.max(lastCombatCountdown - 1, 0);
|
||||||
@@ -666,4 +677,31 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
lastInteract = null;
|
lastInteract = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void skullNotifier()
|
||||||
|
{
|
||||||
|
final Player local = client.getLocalPlayer();
|
||||||
|
SkullIcon currentTickSkull = local.getSkullIcon();
|
||||||
|
EnumSet worldTypes = client.getWorldType();
|
||||||
|
if (!(worldTypes.contains(WorldType.DEADMAN) || worldTypes.contains(WorldType.SEASONAL_DEADMAN)))
|
||||||
|
{
|
||||||
|
if (!isFirstTick)
|
||||||
|
{
|
||||||
|
if (config.showSkullNotification() && lastTickSkull == null && currentTickSkull == SkullIcon.SKULL)
|
||||||
|
{
|
||||||
|
notifier.notify("[" + local.getName() + "] is now skulled!");
|
||||||
|
}
|
||||||
|
else if (config.showUnskullNotification() && lastTickSkull == SkullIcon.SKULL && currentTickSkull == null)
|
||||||
|
{
|
||||||
|
notifier.notify("[" + local.getName() + "] is now unskulled!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isFirstTick = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTickSkull = currentTickSkull;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.InventoryID;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
|
||||||
|
public class ItemRequirement
|
||||||
|
{
|
||||||
|
@Getter
|
||||||
|
private int id;
|
||||||
|
@Getter
|
||||||
|
private int quantity;
|
||||||
|
private boolean equip;
|
||||||
|
|
||||||
|
public ItemRequirement(int id)
|
||||||
|
{
|
||||||
|
this(id, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemRequirement(int id, int quantity)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
this.quantity = quantity;
|
||||||
|
equip = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemRequirement(int id, int quantity, boolean equip)
|
||||||
|
{
|
||||||
|
this(id, quantity);
|
||||||
|
this.equip = equip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean check(Client client)
|
||||||
|
{
|
||||||
|
Item[] items;
|
||||||
|
if (equip)
|
||||||
|
{
|
||||||
|
items = client.getItemContainer(InventoryID.EQUIPMENT).getItems();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
items = client.getItemContainer(InventoryID.INVENTORY).getItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
int tempQuantity = quantity;
|
||||||
|
for (Item item : items)
|
||||||
|
{
|
||||||
|
if (item.getId() == id)
|
||||||
|
{
|
||||||
|
if (item.getQuantity() >= tempQuantity)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tempQuantity -= item.getQuantity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import net.runelite.api.Quest;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface QuestDescriptor
|
||||||
|
{
|
||||||
|
Quest quest();
|
||||||
|
}
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper;
|
||||||
|
|
||||||
|
import com.google.inject.Binder;
|
||||||
|
import com.google.inject.CreationException;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Quest;
|
||||||
|
import net.runelite.api.QuestState;
|
||||||
|
import net.runelite.client.eventbus.EventBus;
|
||||||
|
import net.runelite.client.plugins.questhelper.steps.QuestStep;
|
||||||
|
|
||||||
|
public abstract class QuestHelper implements Module
|
||||||
|
{
|
||||||
|
@Inject
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private EventBus eventBus;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
protected QuestStep currentStep;
|
||||||
|
|
||||||
|
protected Map<Integer, QuestStep> steps;
|
||||||
|
protected Injector injector;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private Quest quest;
|
||||||
|
protected int var;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(Binder binder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void startUp() throws Exception
|
||||||
|
{
|
||||||
|
steps = loadSteps();
|
||||||
|
instantiateSteps();
|
||||||
|
var = getVar();
|
||||||
|
startUpStep(var);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void shutDown() throws Exception
|
||||||
|
{
|
||||||
|
steps = null;
|
||||||
|
shutDownStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void startUpStep(int i) throws Exception
|
||||||
|
{
|
||||||
|
if (steps.containsKey(i))
|
||||||
|
{
|
||||||
|
QuestStep step = steps.get(i);
|
||||||
|
currentStep = step;
|
||||||
|
eventBus.register(currentStep);
|
||||||
|
currentStep.startUp();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentStep = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void shutDownStep() throws Exception
|
||||||
|
{
|
||||||
|
if (currentStep != null)
|
||||||
|
{
|
||||||
|
eventBus.unregister(currentStep);
|
||||||
|
currentStep.shutDown();
|
||||||
|
currentStep = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateQuest() throws Exception
|
||||||
|
{
|
||||||
|
shutDownStep();
|
||||||
|
if (!isCompleted())
|
||||||
|
{
|
||||||
|
currentStep = steps.get(getVar());
|
||||||
|
currentStep.startUp();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentStep = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void instantiateSteps()
|
||||||
|
{
|
||||||
|
for (QuestStep step : steps.values())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
injector.injectMembers(step);
|
||||||
|
}
|
||||||
|
catch (CreationException ex)
|
||||||
|
{
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isCompleted()
|
||||||
|
{
|
||||||
|
return (quest.getState(client) == QuestState.FINISHED);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getVar()
|
||||||
|
{
|
||||||
|
return quest.getVar(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Map<Integer, QuestStep> loadSteps();
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2017, Seth <Sethtroll3@gmail.com>
|
||||||
|
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||||
|
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||||
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
|
|
||||||
|
public class QuestHelperOverlay extends Overlay
|
||||||
|
{
|
||||||
|
public static final Color TITLED_CONTENT_COLOR = new Color(190, 190, 190);
|
||||||
|
|
||||||
|
private final QuestHelperPlugin plugin;
|
||||||
|
private final PanelComponent panelComponent = new PanelComponent();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public QuestHelperOverlay(QuestHelperPlugin plugin)
|
||||||
|
{
|
||||||
|
this.plugin = plugin;
|
||||||
|
setPriority(OverlayPriority.LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
QuestHelper questHelper = plugin.getSelectedQuest();
|
||||||
|
|
||||||
|
if (questHelper == null || questHelper.getCurrentStep() == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
panelComponent.getChildren().clear();
|
||||||
|
panelComponent.setPreferredSize(new Dimension(ComponentConstants.STANDARD_WIDTH, 0));
|
||||||
|
|
||||||
|
questHelper.getCurrentStep().makeOverlayHint(panelComponent, plugin);
|
||||||
|
|
||||||
|
return panelComponent.render(graphics);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.reflect.ClassPath;
|
||||||
|
import com.google.inject.Binder;
|
||||||
|
import com.google.inject.CreationException;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.GameState;
|
||||||
|
import net.runelite.api.Quest;
|
||||||
|
import net.runelite.api.events.GameStateChanged;
|
||||||
|
import net.runelite.api.events.VarbitChanged;
|
||||||
|
import net.runelite.api.events.WidgetLoaded;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetID;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.RuneLite;
|
||||||
|
import net.runelite.client.eventbus.EventBus;
|
||||||
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
|
import net.runelite.client.util.Text;
|
||||||
|
|
||||||
|
@PluginDescriptor(
|
||||||
|
name = "Quest Helper",
|
||||||
|
description = "Helps you with your quests"
|
||||||
|
)
|
||||||
|
@Slf4j
|
||||||
|
public class QuestHelperPlugin extends Plugin
|
||||||
|
{
|
||||||
|
@Inject
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private EventBus eventBus;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private QuestHelperOverlay questHelperOverlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private QuestHelperWorldOverlay questHelperWorldOverlay;
|
||||||
|
|
||||||
|
private static final String QUEST_PACKAGE = "net.runelite.client.plugins.questhelper.quests";
|
||||||
|
private Map<String, QuestHelper> quests;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private QuestHelper selectedQuest = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startUp() throws IOException
|
||||||
|
{
|
||||||
|
if (client.getGameState() == GameState.LOGGED_IN)
|
||||||
|
{
|
||||||
|
if (quests == null)
|
||||||
|
{
|
||||||
|
quests = scanAndInstantiate(getClass().getClassLoader(), QUEST_PACKAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
overlayManager.add(questHelperOverlay);
|
||||||
|
overlayManager.add(questHelperWorldOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void shutDown() throws Exception
|
||||||
|
{
|
||||||
|
overlayManager.remove(questHelperOverlay);
|
||||||
|
overlayManager.remove(questHelperWorldOverlay);
|
||||||
|
quests = null;
|
||||||
|
shutDownQuest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onWidgetLoaded(WidgetLoaded event) throws Exception
|
||||||
|
{
|
||||||
|
int groupId = event.getGroupId();
|
||||||
|
if (groupId == WidgetID.DIARY_QUEST_GROUP_ID)
|
||||||
|
{
|
||||||
|
Widget widget = client.getWidget(WidgetInfo.DIARY_QUEST_WIDGET_TITLE);
|
||||||
|
String questname = Text.removeTags(widget.getText());
|
||||||
|
if (quests.containsKey(questname))
|
||||||
|
{
|
||||||
|
QuestHelper widgetQuest = quests.get(questname);
|
||||||
|
if (selectedQuest == null || !selectedQuest.equals(widgetQuest))
|
||||||
|
{
|
||||||
|
shutDownQuest();
|
||||||
|
startUpQuest(widgetQuest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGameStateChanged(GameStateChanged event) throws IOException
|
||||||
|
{
|
||||||
|
if (event.getGameState() == GameState.LOGGED_IN)
|
||||||
|
{
|
||||||
|
if (quests == null)
|
||||||
|
{
|
||||||
|
quests = scanAndInstantiate(getClass().getClassLoader(), QUEST_PACKAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onVarbitChanged(VarbitChanged event) throws Exception
|
||||||
|
{
|
||||||
|
if (selectedQuest != null && selectedQuest.var != selectedQuest.getVar())
|
||||||
|
{
|
||||||
|
selectedQuest.var = selectedQuest.getVar();
|
||||||
|
selectedQuest.updateQuest();
|
||||||
|
if (selectedQuest.getCurrentStep() == null)
|
||||||
|
{
|
||||||
|
shutDownQuest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startUpQuest(QuestHelper questHelper) throws Exception
|
||||||
|
{
|
||||||
|
if (!questHelper.isCompleted())
|
||||||
|
{
|
||||||
|
selectedQuest = questHelper;
|
||||||
|
eventBus.register(selectedQuest);
|
||||||
|
selectedQuest.startUp();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selectedQuest = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shutDownQuest() throws Exception
|
||||||
|
{
|
||||||
|
if (selectedQuest != null)
|
||||||
|
{
|
||||||
|
selectedQuest.shutDown();
|
||||||
|
eventBus.unregister(selectedQuest);
|
||||||
|
selectedQuest = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, QuestHelper> scanAndInstantiate(ClassLoader classLoader, String packageName) throws IOException
|
||||||
|
{
|
||||||
|
Map<Quest, Class<? extends QuestHelper>> quests = new HashMap<>();
|
||||||
|
|
||||||
|
Map<String, QuestHelper> scannedQuests = new HashMap<>();
|
||||||
|
ClassPath classPath = ClassPath.from(classLoader);
|
||||||
|
|
||||||
|
ImmutableSet<ClassPath.ClassInfo> classes = packageName == null ? classPath.getAllClasses()
|
||||||
|
: classPath.getTopLevelClassesRecursive(packageName);
|
||||||
|
for (ClassPath.ClassInfo classInfo : classes)
|
||||||
|
{
|
||||||
|
Class<?> clazz = classInfo.load();
|
||||||
|
QuestDescriptor questDescriptor = clazz.getAnnotation(QuestDescriptor.class);
|
||||||
|
|
||||||
|
if (questDescriptor == null)
|
||||||
|
{
|
||||||
|
if (clazz.getSuperclass() == QuestHelper.class)
|
||||||
|
{
|
||||||
|
log.warn("Class {} is a quest helper, but has no quest descriptor",
|
||||||
|
clazz);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clazz.getSuperclass() != QuestHelper.class)
|
||||||
|
{
|
||||||
|
log.warn("Class {} has quest descriptor, but is not a quest helper",
|
||||||
|
clazz);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<QuestHelper> questClass = (Class<QuestHelper>) clazz;
|
||||||
|
quests.put(questDescriptor.quest(), questClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<Quest, Class<? extends QuestHelper>> questClazz : quests.entrySet())
|
||||||
|
{
|
||||||
|
QuestHelper questHelper;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
questHelper = instantiate((Class<QuestHelper>) questClazz.getValue(), questClazz.getKey());
|
||||||
|
}
|
||||||
|
catch (QuestInstantiationException ex)
|
||||||
|
{
|
||||||
|
log.warn("Error instantiating quest helper!", ex);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
scannedQuests.put(questClazz.getKey().getName(), questHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
return scannedQuests;
|
||||||
|
}
|
||||||
|
|
||||||
|
private QuestHelper instantiate(Class<QuestHelper> clazz, Quest quest) throws QuestInstantiationException
|
||||||
|
{
|
||||||
|
QuestHelper questHelper;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
questHelper = clazz.newInstance();
|
||||||
|
questHelper.setQuest(quest);
|
||||||
|
}
|
||||||
|
catch (InstantiationException | IllegalAccessException ex)
|
||||||
|
{
|
||||||
|
throw new QuestInstantiationException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Module questModule = (Binder binder) ->
|
||||||
|
{
|
||||||
|
binder.bind(clazz).toInstance(questHelper);
|
||||||
|
binder.install(questHelper);
|
||||||
|
};
|
||||||
|
Injector questInjector = RuneLite.getInjector().createChildInjector(questModule);
|
||||||
|
questInjector.injectMembers(questHelper);
|
||||||
|
questHelper.injector = questInjector;
|
||||||
|
}
|
||||||
|
catch (CreationException ex)
|
||||||
|
{
|
||||||
|
throw new QuestInstantiationException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("Loaded quest helper {}", clazz.getSimpleName());
|
||||||
|
return questHelper;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Morgan Lewis <https://github.com/MESLewis>
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper;
|
||||||
|
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.client.ui.overlay.worldmap.WorldMapPoint;
|
||||||
|
import net.runelite.client.util.ImageUtil;
|
||||||
|
|
||||||
|
public class QuestHelperWorldMapPoint extends WorldMapPoint
|
||||||
|
{
|
||||||
|
private final BufferedImage questWorldImage;
|
||||||
|
private final Point questWorldImagePoint;
|
||||||
|
private final BufferedImage questImage;
|
||||||
|
|
||||||
|
public QuestHelperWorldMapPoint(final WorldPoint worldPoint, BufferedImage image)
|
||||||
|
{
|
||||||
|
super(worldPoint, null);
|
||||||
|
|
||||||
|
BufferedImage mapArrow = ImageUtil.getResourceStreamFromClass(getClass(), "/util/clue_arrow.png");
|
||||||
|
questWorldImage = new BufferedImage(mapArrow.getWidth(), mapArrow.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics graphics = questWorldImage.getGraphics();
|
||||||
|
graphics.drawImage(mapArrow, 0, 0, null);
|
||||||
|
int buffer = mapArrow.getWidth() / 2 - image.getWidth() / 2;
|
||||||
|
buffer = buffer < 0 ? 0 : buffer;
|
||||||
|
graphics.drawImage(image, buffer, buffer, null);
|
||||||
|
questWorldImagePoint = new Point(questWorldImage.getWidth() / 2, questWorldImage.getHeight());
|
||||||
|
|
||||||
|
this.questImage = image;
|
||||||
|
this.setSnapToEdge(true);
|
||||||
|
this.setJumpOnClick(true);
|
||||||
|
this.setImage(questWorldImage);
|
||||||
|
this.setImagePoint(questWorldImagePoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEdgeSnap()
|
||||||
|
{
|
||||||
|
this.setImage(questImage);
|
||||||
|
this.setImagePoint(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEdgeUnsnap()
|
||||||
|
{
|
||||||
|
this.setImage(questWorldImage);
|
||||||
|
this.setImagePoint(questWorldImagePoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
|
|
||||||
|
public class QuestHelperWorldOverlay extends Overlay
|
||||||
|
{
|
||||||
|
public static final int IMAGE_Z_OFFSET = 30;
|
||||||
|
|
||||||
|
public static final Color CLICKBOX_BORDER_COLOR = Color.CYAN;
|
||||||
|
public static final Color CLICKBOX_HOVER_BORDER_COLOR = CLICKBOX_BORDER_COLOR.darker();
|
||||||
|
public static final Color CLICKBOX_FILL_COLOR = new Color(0, 255, 0, 20);
|
||||||
|
|
||||||
|
private final QuestHelperPlugin plugin;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public QuestHelperWorldOverlay(QuestHelperPlugin plugin)
|
||||||
|
{
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
QuestHelper quest = plugin.getSelectedQuest();
|
||||||
|
|
||||||
|
if (quest != null && quest.getCurrentStep() != null)
|
||||||
|
{
|
||||||
|
quest.getCurrentStep().makeWorldOverlayHint(graphics, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper;
|
||||||
|
|
||||||
|
public class QuestInstantiationException extends Exception
|
||||||
|
{
|
||||||
|
public QuestInstantiationException(Throwable cause)
|
||||||
|
{
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper.quests.cooksassistant;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
import net.runelite.api.NpcID;
|
||||||
|
import net.runelite.api.Quest;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.client.plugins.questhelper.ItemRequirement;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestHelper;
|
||||||
|
import net.runelite.client.plugins.questhelper.steps.NpcTalkStep;
|
||||||
|
import net.runelite.client.plugins.questhelper.steps.QuestStep;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestDescriptor;
|
||||||
|
|
||||||
|
@QuestDescriptor(
|
||||||
|
quest = Quest.COOKS_ASSISTANT
|
||||||
|
)
|
||||||
|
public class CooksAssistant extends QuestHelper
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected Map<Integer, QuestStep> loadSteps()
|
||||||
|
{
|
||||||
|
Map<Integer, QuestStep> steps = new HashMap<>();
|
||||||
|
|
||||||
|
steps.put(0, new NpcTalkStep(this, NpcID.COOK_4626, new WorldPoint(3206, 3214, 0),
|
||||||
|
"Give the Cook in Lumbridge Castle's kitchen the required items to finish the quest.",
|
||||||
|
new ItemRequirement(ItemID.BUCKET_OF_MILK), new ItemRequirement(ItemID.POT_OF_FLOUR),
|
||||||
|
new ItemRequirement(ItemID.EGG)));
|
||||||
|
|
||||||
|
steps.put(1, steps.get(0));
|
||||||
|
|
||||||
|
return steps;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper.quests.impcatcher;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
import net.runelite.api.NpcID;
|
||||||
|
import net.runelite.api.Quest;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.client.plugins.questhelper.ItemRequirement;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestHelper;
|
||||||
|
import net.runelite.client.plugins.questhelper.steps.NpcTalkStep;
|
||||||
|
import net.runelite.client.plugins.questhelper.steps.QuestStep;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestDescriptor;
|
||||||
|
|
||||||
|
@QuestDescriptor(
|
||||||
|
quest = Quest.IMP_CATCHER
|
||||||
|
)
|
||||||
|
public class ImpCatcher extends QuestHelper
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected Map<Integer, QuestStep> loadSteps()
|
||||||
|
{
|
||||||
|
Map<Integer, QuestStep> steps = new HashMap<>();
|
||||||
|
|
||||||
|
steps.put(0, new NpcTalkStep(this, NpcID.WIZARD_MIZGOG, new WorldPoint(3103, 3163, 2),
|
||||||
|
"Talk to Wizard Mizgog on the top floor of the Wizards' Tower with the required items to finish the quest.",
|
||||||
|
new ItemRequirement(ItemID.BLACK_BEAD), new ItemRequirement(ItemID.WHITE_BEAD),
|
||||||
|
new ItemRequirement(ItemID.RED_BEAD), new ItemRequirement(ItemID.YELLOW_BEAD)));
|
||||||
|
|
||||||
|
steps.put(1, steps.get(0));
|
||||||
|
|
||||||
|
return steps;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper.quests.xmarksthespot;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
import net.runelite.api.NpcID;
|
||||||
|
import net.runelite.api.Quest;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.client.plugins.questhelper.ItemRequirement;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestHelper;
|
||||||
|
import net.runelite.client.plugins.questhelper.steps.DigStep;
|
||||||
|
import net.runelite.client.plugins.questhelper.steps.NpcTalkStep;
|
||||||
|
import net.runelite.client.plugins.questhelper.steps.QuestStep;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestDescriptor;
|
||||||
|
|
||||||
|
@QuestDescriptor(
|
||||||
|
quest = Quest.X_MARKS_THE_SPOT
|
||||||
|
)
|
||||||
|
public class XMarksTheSpot extends QuestHelper
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected Map<Integer, QuestStep> loadSteps()
|
||||||
|
{
|
||||||
|
Map<Integer, QuestStep> steps = new HashMap<>();
|
||||||
|
|
||||||
|
steps.put(0, new NpcTalkStep(this, NpcID.VEOS_8484, new WorldPoint(3228, 3242, 0),
|
||||||
|
"Talk to Veos in The Sheared Ram pub in Lumbridge to start the quest."));
|
||||||
|
|
||||||
|
steps.put(1, steps.get(0));
|
||||||
|
|
||||||
|
steps.put(2, new DigStep(this, new WorldPoint(3230, 3209, 0),
|
||||||
|
"Dig north of Bob's Brilliant Axes, on the west side of the plant against the wall of his house.",
|
||||||
|
new ItemRequirement(ItemID.TREASURE_SCROLL)));
|
||||||
|
|
||||||
|
steps.put(3, new DigStep(this, new WorldPoint(3203, 3212, 0),
|
||||||
|
"Dig behind Lumbridge Castle, just outside the kitchen door.",
|
||||||
|
new ItemRequirement(ItemID.TREASURE_SCROLL_23068)));
|
||||||
|
|
||||||
|
steps.put(4, new DigStep(this, new WorldPoint(3109, 3264, 0),
|
||||||
|
"Dig north-west of the Draynor Village jail, just by the wheat farm.",
|
||||||
|
new ItemRequirement(ItemID.MYSTERIOUS_ORB_23069)));
|
||||||
|
|
||||||
|
steps.put(5, new DigStep(this, new WorldPoint(3078, 3259, 0),
|
||||||
|
"Dig in the pig pen just west where Martin the Master Gardener is.",
|
||||||
|
new ItemRequirement(ItemID.TREASURE_SCROLL_23070)));
|
||||||
|
|
||||||
|
steps.put(6, new NpcTalkStep(this, NpcID.VEOS_8484, new WorldPoint(3054, 3245, 0),
|
||||||
|
"Talk to Veos directly south of the Rusty Anchor Inn in Port Sarim to finish the quest.",
|
||||||
|
new ItemRequirement(ItemID.ANCIENT_CASKET)));
|
||||||
|
|
||||||
|
steps.put(7, new NpcTalkStep(this, NpcID.VEOS_8484, new WorldPoint(3054, 3245, 0),
|
||||||
|
"Talk to Veos directly south of the Rusty Anchor Inn in Port Sarim to finish the quest."));
|
||||||
|
|
||||||
|
return steps;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper.steps;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
import net.runelite.api.coords.LocalPoint;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.plugins.questhelper.ItemRequirement;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestHelper;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestHelperPlugin;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestHelperWorldMapPoint;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||||
|
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||||
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
|
import net.runelite.client.ui.overlay.worldmap.WorldMapPointManager;
|
||||||
|
|
||||||
|
public class DigStep extends QuestStep
|
||||||
|
{
|
||||||
|
@Inject
|
||||||
|
Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ItemManager itemManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
WorldMapPointManager worldMapPointManager;
|
||||||
|
|
||||||
|
private final WorldPoint worldPoint;
|
||||||
|
private final List<ItemRequirement> itemRequirements = new ArrayList<>();
|
||||||
|
|
||||||
|
public DigStep(QuestHelper questHelper, WorldPoint worldPoint, String text, ItemRequirement... itemRequirements)
|
||||||
|
{
|
||||||
|
super(questHelper, text);
|
||||||
|
this.worldPoint = worldPoint;
|
||||||
|
this.itemRequirements.add(0, new ItemRequirement(ItemID.SPADE));
|
||||||
|
Collections.addAll(this.itemRequirements, itemRequirements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startUp() throws Exception
|
||||||
|
{
|
||||||
|
worldMapPointManager.add(new QuestHelperWorldMapPoint(worldPoint, getQuestImage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutDown() throws Exception
|
||||||
|
{
|
||||||
|
worldMapPointManager.removeIf(QuestHelperWorldMapPoint.class::isInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void makeOverlayHint(PanelComponent panelComponent, QuestHelperPlugin plugin)
|
||||||
|
{
|
||||||
|
super.makeOverlayHint(panelComponent, plugin);
|
||||||
|
|
||||||
|
panelComponent.getChildren().add(LineComponent.builder().left("Required Items:").build());
|
||||||
|
for (ItemRequirement itemRequirement : itemRequirements)
|
||||||
|
{
|
||||||
|
String text = itemRequirement.getQuantity() + " x " + itemManager.getItemComposition(itemRequirement.getId()).getName();
|
||||||
|
Color color;
|
||||||
|
if (itemRequirement.check(client))
|
||||||
|
{
|
||||||
|
color = Color.GREEN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color = Color.RED;
|
||||||
|
}
|
||||||
|
panelComponent.getChildren().add(LineComponent.builder()
|
||||||
|
.left(text)
|
||||||
|
.leftColor(color)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin)
|
||||||
|
{
|
||||||
|
LocalPoint localLocation = LocalPoint.fromWorld(client, worldPoint);
|
||||||
|
|
||||||
|
if (localLocation == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayUtil.renderTileOverlay(client, graphics, localLocation, getSpadeImage(), Color.ORANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BufferedImage getSpadeImage()
|
||||||
|
{
|
||||||
|
return itemManager.getImage(ItemID.SPADE);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper.steps;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.NPC;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.api.events.NpcDespawned;
|
||||||
|
import net.runelite.api.events.NpcSpawned;
|
||||||
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.plugins.questhelper.ItemRequirement;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestHelper;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestHelperPlugin;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestHelperWorldMapPoint;
|
||||||
|
import static net.runelite.client.plugins.questhelper.QuestHelperWorldOverlay.IMAGE_Z_OFFSET;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||||
|
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||||
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
|
import net.runelite.client.ui.overlay.worldmap.WorldMapPointManager;
|
||||||
|
|
||||||
|
public class NpcTalkStep extends QuestStep
|
||||||
|
{
|
||||||
|
@Inject
|
||||||
|
protected Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected ItemManager itemManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected WorldMapPointManager worldMapPointManager;
|
||||||
|
|
||||||
|
private int npcID;
|
||||||
|
private WorldPoint worldPoint;
|
||||||
|
private List<NPC> npcsToHighlight = new ArrayList<>();
|
||||||
|
List<ItemRequirement> itemRequirements;
|
||||||
|
|
||||||
|
public NpcTalkStep(QuestHelper questHelper, int npcID, WorldPoint worldPoint, String text, ItemRequirement... itemRequirements)
|
||||||
|
{
|
||||||
|
super(questHelper, text);
|
||||||
|
this.npcID = npcID;
|
||||||
|
this.worldPoint = worldPoint;
|
||||||
|
this.itemRequirements = Arrays.asList(itemRequirements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startUp() throws Exception
|
||||||
|
{
|
||||||
|
for (NPC npc : client.getNpcs())
|
||||||
|
{
|
||||||
|
if (npcID == npc.getId())
|
||||||
|
{
|
||||||
|
npcsToHighlight.add(npc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
worldMapPointManager.add(new QuestHelperWorldMapPoint(worldPoint, getQuestImage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutDown() throws Exception
|
||||||
|
{
|
||||||
|
npcsToHighlight.clear();
|
||||||
|
worldMapPointManager.removeIf(QuestHelperWorldMapPoint.class::isInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onNpcSpawned(NpcSpawned event)
|
||||||
|
{
|
||||||
|
if (event.getNpc().getId() == npcID)
|
||||||
|
{
|
||||||
|
npcsToHighlight.add(event.getNpc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onNpcDespawned(NpcDespawned event)
|
||||||
|
{
|
||||||
|
if (npcsToHighlight.contains(event.getNpc()))
|
||||||
|
{
|
||||||
|
npcsToHighlight.remove(event.getNpc());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void makeOverlayHint(PanelComponent panelComponent, QuestHelperPlugin plugin)
|
||||||
|
{
|
||||||
|
super.makeOverlayHint(panelComponent, plugin);
|
||||||
|
|
||||||
|
if (itemRequirements.isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
panelComponent.getChildren().add(LineComponent.builder().left("Required Items:").build());
|
||||||
|
for (ItemRequirement itemRequirement : itemRequirements)
|
||||||
|
{
|
||||||
|
String text = itemRequirement.getQuantity() + " x " + itemManager.getItemComposition(itemRequirement.getId()).getName();
|
||||||
|
Color color;
|
||||||
|
if (itemRequirement.check(client))
|
||||||
|
{
|
||||||
|
color = Color.GREEN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color = Color.RED;
|
||||||
|
}
|
||||||
|
panelComponent.getChildren().add(LineComponent.builder()
|
||||||
|
.left(text)
|
||||||
|
.leftColor(color)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin)
|
||||||
|
{
|
||||||
|
if (!worldPoint.isInScene(client))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (npcsToHighlight.isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NPC npc : npcsToHighlight)
|
||||||
|
{
|
||||||
|
OverlayUtil.renderActorOverlayImage(graphics, npc, getQuestImage(), Color.CYAN, IMAGE_Z_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Trevor <https://github.com/Trevor159>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.questhelper.steps;
|
||||||
|
|
||||||
|
import com.google.inject.Binder;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import net.runelite.api.SpriteID;
|
||||||
|
import net.runelite.client.game.SpriteManager;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestHelper;
|
||||||
|
import static net.runelite.client.plugins.questhelper.QuestHelperOverlay.TITLED_CONTENT_COLOR;
|
||||||
|
import net.runelite.client.plugins.questhelper.QuestHelperPlugin;
|
||||||
|
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||||
|
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||||
|
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||||
|
|
||||||
|
public abstract class QuestStep implements Module
|
||||||
|
{
|
||||||
|
@Inject
|
||||||
|
SpriteManager spriteManager;
|
||||||
|
|
||||||
|
private final String text;
|
||||||
|
private final QuestHelper questHelper;
|
||||||
|
|
||||||
|
public QuestStep(QuestHelper questHelper, String text)
|
||||||
|
{
|
||||||
|
this.text = text;
|
||||||
|
this.questHelper = questHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(Binder binder)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startUp() throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutDown() throws Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void makeOverlayHint(PanelComponent panelComponent, QuestHelperPlugin plugin)
|
||||||
|
{
|
||||||
|
panelComponent.getChildren().add(TitleComponent.builder().text(questHelper.getQuest().getName()).build());
|
||||||
|
|
||||||
|
panelComponent.getChildren().add(LineComponent.builder().left("Step:").build());
|
||||||
|
panelComponent.getChildren().add(LineComponent.builder()
|
||||||
|
.left(text)
|
||||||
|
.leftColor(TITLED_CONTENT_COLOR)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void makeWorldOverlayHint(Graphics2D graphics, QuestHelperPlugin plugin);
|
||||||
|
|
||||||
|
public BufferedImage getQuestImage()
|
||||||
|
{
|
||||||
|
return spriteManager.getSprite(SpriteID.TAB_QUESTS, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,8 +38,8 @@ public interface RaidsConfig extends Config
|
|||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
position = 0,
|
position = 0,
|
||||||
keyName = "raidsTimer",
|
keyName = "raidsTimer",
|
||||||
name = "Display elapsed raid time",
|
name = "Level time tooltip",
|
||||||
description = "Display elapsed raid time"
|
description = "Displays your level times as a tooltip on the points overlay"
|
||||||
)
|
)
|
||||||
default boolean raidsTimer()
|
default boolean raidsTimer()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import java.awt.Graphics2D;
|
|||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -57,11 +56,13 @@ import net.runelite.api.Tile;
|
|||||||
import net.runelite.api.VarPlayer;
|
import net.runelite.api.VarPlayer;
|
||||||
import net.runelite.api.Varbits;
|
import net.runelite.api.Varbits;
|
||||||
import net.runelite.api.events.ChatMessage;
|
import net.runelite.api.events.ChatMessage;
|
||||||
|
import net.runelite.api.events.ClientTick;
|
||||||
import net.runelite.api.events.ConfigChanged;
|
import net.runelite.api.events.ConfigChanged;
|
||||||
import net.runelite.api.events.VarbitChanged;
|
import net.runelite.api.events.VarbitChanged;
|
||||||
import net.runelite.api.events.WidgetHiddenChanged;
|
import net.runelite.api.events.WidgetHiddenChanged;
|
||||||
import net.runelite.api.widgets.Widget;
|
import net.runelite.api.widgets.Widget;
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
import net.runelite.client.callback.ClientThread;
|
import net.runelite.client.callback.ClientThread;
|
||||||
import net.runelite.client.chat.ChatColorType;
|
import net.runelite.client.chat.ChatColorType;
|
||||||
import net.runelite.client.chat.ChatMessageBuilder;
|
import net.runelite.client.chat.ChatMessageBuilder;
|
||||||
@@ -81,9 +82,13 @@ import net.runelite.client.plugins.raids.solver.RotationSolver;
|
|||||||
import net.runelite.client.ui.DrawManager;
|
import net.runelite.client.ui.DrawManager;
|
||||||
import net.runelite.client.ui.FontManager;
|
import net.runelite.client.ui.FontManager;
|
||||||
import net.runelite.client.ui.overlay.OverlayManager;
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
|
import net.runelite.client.ui.overlay.WidgetOverlay;
|
||||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||||
|
import net.runelite.client.ui.overlay.tooltip.Tooltip;
|
||||||
|
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
||||||
import net.runelite.client.util.Text;
|
import net.runelite.client.util.Text;
|
||||||
import net.runelite.client.util.HotkeyListener;
|
import net.runelite.client.util.HotkeyListener;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Chambers Of Xeric",
|
name = "Chambers Of Xeric",
|
||||||
@@ -95,9 +100,6 @@ import net.runelite.client.util.HotkeyListener;
|
|||||||
public class RaidsPlugin extends Plugin
|
public class RaidsPlugin extends Plugin
|
||||||
{
|
{
|
||||||
private static final int LOBBY_PLANE = 3;
|
private static final int LOBBY_PLANE = 3;
|
||||||
private static final String RAID_START_MESSAGE = "The raid has begun!";
|
|
||||||
private static final String LEVEL_COMPLETE_MESSAGE = "level complete!";
|
|
||||||
private static final String RAID_COMPLETE_MESSAGE = "Congratulations - your raid is complete!";
|
|
||||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###.##");
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###.##");
|
||||||
static final DecimalFormat POINTS_FORMAT = new DecimalFormat("#,###");
|
static final DecimalFormat POINTS_FORMAT = new DecimalFormat("#,###");
|
||||||
private static final String SPLIT_REGEX = "\\s*,\\s*";
|
private static final String SPLIT_REGEX = "\\s*,\\s*";
|
||||||
@@ -106,6 +108,8 @@ public class RaidsPlugin extends Plugin
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ItemManager itemManager;
|
private ItemManager itemManager;
|
||||||
|
private static final Pattern LEVEL_COMPLETE_REGEX = Pattern.compile("(.+) level complete! Duration: ([0-9:]+)");
|
||||||
|
private static final Pattern RAID_COMPLETE_REGEX = Pattern.compile("Congratulations - your raid is complete! Duration: ([0-9:]+)");
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ChatMessageManager chatMessageManager;
|
private ChatMessageManager chatMessageManager;
|
||||||
@@ -146,6 +150,9 @@ public class RaidsPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private KeyManager keyManager;
|
private KeyManager keyManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TooltipManager tooltipManager;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final ArrayList<String> roomWhitelist = new ArrayList<>();
|
private final ArrayList<String> roomWhitelist = new ArrayList<>();
|
||||||
|
|
||||||
@@ -167,7 +174,12 @@ public class RaidsPlugin extends Plugin
|
|||||||
@Getter
|
@Getter
|
||||||
private boolean inRaidChambers;
|
private boolean inRaidChambers;
|
||||||
|
|
||||||
private RaidsTimer timer;
|
private int upperTime = -1;
|
||||||
|
private int middleTime = -1;
|
||||||
|
private int lowerTime = -1;
|
||||||
|
private int raidTime = -1;
|
||||||
|
private WidgetOverlay widgetOverlay;
|
||||||
|
private String tooltip;
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
RaidsConfig provideConfig(ConfigManager configManager)
|
RaidsConfig provideConfig(ConfigManager configManager)
|
||||||
@@ -188,6 +200,7 @@ public class RaidsPlugin extends Plugin
|
|||||||
overlayManager.add(pointsOverlay);
|
overlayManager.add(pointsOverlay);
|
||||||
updateLists();
|
updateLists();
|
||||||
clientThread.invokeLater(() -> checkRaidPresence(true));
|
clientThread.invokeLater(() -> checkRaidPresence(true));
|
||||||
|
widgetOverlay = overlayManager.getWidgetOverlay(WidgetInfo.RAIDS_POINTS_INFOBOX);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -195,16 +208,16 @@ public class RaidsPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
overlayManager.remove(overlay);
|
overlayManager.remove(overlay);
|
||||||
overlayManager.remove(pointsOverlay);
|
overlayManager.remove(pointsOverlay);
|
||||||
infoBoxManager.removeInfoBox(timer);
|
|
||||||
inRaidChambers = false;
|
inRaidChambers = false;
|
||||||
|
widgetOverlay = null;
|
||||||
raid = null;
|
raid = null;
|
||||||
timer = null;
|
|
||||||
|
|
||||||
final Widget widget = client.getWidget(WidgetInfo.RAIDS_POINTS_INFOBOX);
|
final Widget widget = client.getWidget(WidgetInfo.RAIDS_POINTS_INFOBOX);
|
||||||
if (widget != null)
|
if (widget != null)
|
||||||
{
|
{
|
||||||
widget.setHidden(false);
|
widget.setHidden(false);
|
||||||
}
|
}
|
||||||
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -215,12 +228,6 @@ public class RaidsPlugin extends Plugin
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.getKey().equals("raidsTimer"))
|
|
||||||
{
|
|
||||||
updateInfoBoxState();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateLists();
|
updateLists();
|
||||||
clientThread.invokeLater(() -> checkRaidPresence(true));
|
clientThread.invokeLater(() -> checkRaidPresence(true));
|
||||||
}
|
}
|
||||||
@@ -253,25 +260,33 @@ public class RaidsPlugin extends Plugin
|
|||||||
if (inRaidChambers && event.getType() == ChatMessageType.FRIENDSCHATNOTIFICATION)
|
if (inRaidChambers && event.getType() == ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||||
{
|
{
|
||||||
String message = Text.removeTags(event.getMessage());
|
String message = Text.removeTags(event.getMessage());
|
||||||
|
Matcher matcher;
|
||||||
|
|
||||||
if (config.raidsTimer() && message.startsWith(RAID_START_MESSAGE))
|
matcher = LEVEL_COMPLETE_REGEX.matcher(message);
|
||||||
|
if (matcher.find())
|
||||||
{
|
{
|
||||||
timer = new RaidsTimer(spriteManager.getSprite(TAB_QUESTS_BROWN_RAIDING_PARTY, 0), this, Instant.now());
|
String floor = matcher.group(1);
|
||||||
infoBoxManager.addInfoBox(timer);
|
int time = timeToSeconds(matcher.group(2));
|
||||||
}
|
if (floor.equals("Upper"))
|
||||||
|
|
||||||
if (timer != null && message.contains(LEVEL_COMPLETE_MESSAGE))
|
|
||||||
{
|
|
||||||
timer.timeFloor();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.startsWith(RAID_COMPLETE_MESSAGE))
|
|
||||||
{
|
|
||||||
if (timer != null)
|
|
||||||
{
|
{
|
||||||
timer.timeOlm();
|
upperTime = time;
|
||||||
timer.setStopped(true);
|
|
||||||
}
|
}
|
||||||
|
else if (floor.equals("Middle"))
|
||||||
|
{
|
||||||
|
middleTime = time;
|
||||||
|
}
|
||||||
|
else if (floor.equals("Lower"))
|
||||||
|
{
|
||||||
|
lowerTime = time;
|
||||||
|
}
|
||||||
|
updateTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
matcher = RAID_COMPLETE_REGEX.matcher(message);
|
||||||
|
if (matcher.find())
|
||||||
|
{
|
||||||
|
raidTime = timeToSeconds(matcher.group(1));
|
||||||
|
updateTooltip();
|
||||||
|
|
||||||
if (config.pointsMessage())
|
if (config.pointsMessage())
|
||||||
{
|
{
|
||||||
@@ -306,6 +321,23 @@ public class RaidsPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onClientTick(ClientTick event)
|
||||||
|
{
|
||||||
|
if (!config.raidsTimer()
|
||||||
|
|| !client.getGameState().equals(GameState.LOGGED_IN)
|
||||||
|
|| tooltip == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Point mousePosition = client.getMouseCanvasPosition();
|
||||||
|
if (widgetOverlay.getBounds().contains(mousePosition.getX(), mousePosition.getY()))
|
||||||
|
{
|
||||||
|
tooltipManager.add(new Tooltip(tooltip));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkRaidPresence(boolean force)
|
private void checkRaidPresence(boolean force)
|
||||||
{
|
{
|
||||||
if (client.getGameState() != GameState.LOGGED_IN)
|
if (client.getGameState() != GameState.LOGGED_IN)
|
||||||
@@ -318,7 +350,6 @@ public class RaidsPlugin extends Plugin
|
|||||||
if (force || inRaidChambers != setting)
|
if (force || inRaidChambers != setting)
|
||||||
{
|
{
|
||||||
inRaidChambers = setting;
|
inRaidChambers = setting;
|
||||||
updateInfoBoxState();
|
|
||||||
|
|
||||||
if (inRaidChambers)
|
if (inRaidChambers)
|
||||||
{
|
{
|
||||||
@@ -343,9 +374,14 @@ public class RaidsPlugin extends Plugin
|
|||||||
overlay.setScoutOverlayShown(true);
|
overlay.setScoutOverlayShown(true);
|
||||||
sendRaidLayoutMessage();
|
sendRaidLayoutMessage();
|
||||||
}
|
}
|
||||||
else if (!config.scoutOverlayAtBank())
|
else
|
||||||
{
|
{
|
||||||
overlay.setScoutOverlayShown(false);
|
if (!config.scoutOverlayAtBank())
|
||||||
|
{
|
||||||
|
overlay.setScoutOverlayShown(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,30 +414,6 @@ public class RaidsPlugin extends Plugin
|
|||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateInfoBoxState()
|
|
||||||
{
|
|
||||||
if (timer == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inRaidChambers && config.raidsTimer())
|
|
||||||
{
|
|
||||||
if (!infoBoxManager.getInfoBoxes().contains(timer))
|
|
||||||
{
|
|
||||||
infoBoxManager.addInfoBox(timer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
infoBoxManager.removeInfoBox(timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!inRaidChambers)
|
|
||||||
{
|
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateLists()
|
private void updateLists()
|
||||||
{
|
{
|
||||||
@@ -700,4 +712,94 @@ public class RaidsPlugin extends Plugin
|
|||||||
|
|
||||||
return room;
|
return room;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
raid = null;
|
||||||
|
upperTime = -1;
|
||||||
|
middleTime = -1;
|
||||||
|
lowerTime = -1;
|
||||||
|
raidTime = -1;
|
||||||
|
tooltip = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int timeToSeconds(String s)
|
||||||
|
{
|
||||||
|
int seconds = -1;
|
||||||
|
String[] split = s.split(":");
|
||||||
|
if (split.length == 2)
|
||||||
|
{
|
||||||
|
seconds = Integer.parseInt(split[0]) * 60 + Integer.parseInt(split[1]);
|
||||||
|
}
|
||||||
|
if (split.length == 3)
|
||||||
|
{
|
||||||
|
seconds = Integer.parseInt(split[0]) * 3600 + Integer.parseInt(split[1]) * 60 + Integer.parseInt(split[2]);
|
||||||
|
}
|
||||||
|
return seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String secondsToTime(int seconds)
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
if (seconds >= 3600)
|
||||||
|
{
|
||||||
|
builder.append((int)Math.floor(seconds / 3600) + ";");
|
||||||
|
}
|
||||||
|
seconds %= 3600;
|
||||||
|
if (builder.toString().equals(""))
|
||||||
|
{
|
||||||
|
builder.append((int)Math.floor(seconds / 60));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.append(StringUtils.leftPad(String.valueOf((int)Math.floor(seconds / 60)), 2, '0'));
|
||||||
|
}
|
||||||
|
builder.append(":");
|
||||||
|
seconds %= 60;
|
||||||
|
builder.append(StringUtils.leftPad(String.valueOf(seconds), 2, '0'));
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTooltip()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
if (upperTime == -1)
|
||||||
|
{
|
||||||
|
tooltip = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
builder.append("Upper level: " + secondsToTime(upperTime));
|
||||||
|
if (middleTime == -1)
|
||||||
|
{
|
||||||
|
if (lowerTime == -1)
|
||||||
|
{
|
||||||
|
tooltip = builder.toString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.append("</br>Lower level: " + secondsToTime(lowerTime - upperTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.append("</br>Middle level: " + secondsToTime(middleTime - upperTime));
|
||||||
|
if (lowerTime == -1)
|
||||||
|
{
|
||||||
|
tooltip = builder.toString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.append("</br>Lower level: " + secondsToTime(lowerTime - middleTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (raidTime == -1)
|
||||||
|
{
|
||||||
|
tooltip = builder.toString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
builder.append("</br>Olm: " + secondsToTime(raidTime - lowerTime));
|
||||||
|
tooltip = builder.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,150 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018, Kamiel
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package net.runelite.client.plugins.raids;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.LocalTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import net.runelite.client.plugins.Plugin;
|
|
||||||
import net.runelite.client.ui.overlay.infobox.InfoBox;
|
|
||||||
|
|
||||||
public class RaidsTimer extends InfoBox
|
|
||||||
{
|
|
||||||
private final Instant startTime;
|
|
||||||
private Instant floorTime;
|
|
||||||
private LocalTime time;
|
|
||||||
private LocalTime firstFloorTime;
|
|
||||||
private LocalTime secondFloorTime;
|
|
||||||
private LocalTime thirdFloorTime;
|
|
||||||
private LocalTime olmTime;
|
|
||||||
|
|
||||||
@Setter
|
|
||||||
private boolean stopped;
|
|
||||||
|
|
||||||
public RaidsTimer(BufferedImage image, Plugin plugin, Instant startTime)
|
|
||||||
{
|
|
||||||
super(image, plugin);
|
|
||||||
this.startTime = startTime;
|
|
||||||
floorTime = startTime;
|
|
||||||
stopped = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void timeFloor()
|
|
||||||
{
|
|
||||||
Duration elapsed = Duration.between(floorTime, Instant.now());
|
|
||||||
|
|
||||||
if (firstFloorTime == null)
|
|
||||||
{
|
|
||||||
firstFloorTime = LocalTime.ofSecondOfDay(elapsed.getSeconds());
|
|
||||||
}
|
|
||||||
else if (secondFloorTime == null)
|
|
||||||
{
|
|
||||||
secondFloorTime = LocalTime.ofSecondOfDay(elapsed.getSeconds());
|
|
||||||
}
|
|
||||||
else if (thirdFloorTime == null)
|
|
||||||
{
|
|
||||||
thirdFloorTime = LocalTime.ofSecondOfDay(elapsed.getSeconds());
|
|
||||||
}
|
|
||||||
|
|
||||||
floorTime = Instant.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void timeOlm()
|
|
||||||
{
|
|
||||||
Duration elapsed = Duration.between(floorTime, Instant.now());
|
|
||||||
olmTime = LocalTime.ofSecondOfDay(elapsed.getSeconds());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getText()
|
|
||||||
{
|
|
||||||
if (startTime == null)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stopped)
|
|
||||||
{
|
|
||||||
Duration elapsed = Duration.between(startTime, Instant.now());
|
|
||||||
time = LocalTime.ofSecondOfDay(elapsed.getSeconds());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (time.getHour() > 0)
|
|
||||||
{
|
|
||||||
return time.format(DateTimeFormatter.ofPattern("HH:mm"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return time.format(DateTimeFormatter.ofPattern("mm:ss"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Color getTextColor()
|
|
||||||
{
|
|
||||||
if (stopped)
|
|
||||||
{
|
|
||||||
return Color.GREEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Color.WHITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTooltip()
|
|
||||||
{
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("Elapsed raid time: ");
|
|
||||||
builder.append(time.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
|
||||||
|
|
||||||
if (firstFloorTime != null)
|
|
||||||
{
|
|
||||||
builder.append("</br>First floor: ");
|
|
||||||
builder.append(firstFloorTime.format(DateTimeFormatter.ofPattern("mm:ss")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (secondFloorTime != null)
|
|
||||||
{
|
|
||||||
builder.append("</br>Second floor: ");
|
|
||||||
builder.append(secondFloorTime.format(DateTimeFormatter.ofPattern("mm:ss")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thirdFloorTime != null)
|
|
||||||
{
|
|
||||||
builder.append("</br>Third floor: ");
|
|
||||||
builder.append(thirdFloorTime.format(DateTimeFormatter.ofPattern("mm:ss")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (olmTime != null)
|
|
||||||
{
|
|
||||||
builder.append("</br>Olm: ");
|
|
||||||
builder.append(olmTime.format(DateTimeFormatter.ofPattern("mm:ss")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -42,6 +42,7 @@ import lombok.Getter;
|
|||||||
import net.runelite.api.MenuAction;
|
import net.runelite.api.MenuAction;
|
||||||
import net.runelite.api.events.MenuOptionClicked;
|
import net.runelite.api.events.MenuOptionClicked;
|
||||||
import net.runelite.api.widgets.WidgetItem;
|
import net.runelite.api.widgets.WidgetItem;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
import net.runelite.client.config.ConfigGroup;
|
import net.runelite.client.config.ConfigGroup;
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.config.RuneLiteConfig;
|
import net.runelite.client.config.RuneLiteConfig;
|
||||||
@@ -364,4 +365,21 @@ public class OverlayManager
|
|||||||
final String locationKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
final String locationKey = overlay.getName() + OVERLAY_CONFIG_PREFERRED_POSITION;
|
||||||
return configManager.getConfiguration(RUNELITE_CONFIG_GROUP_NAME, locationKey, OverlayPosition.class);
|
return configManager.getConfiguration(RUNELITE_CONFIG_GROUP_NAME, locationKey, OverlayPosition.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WidgetOverlay getWidgetOverlay(final WidgetInfo info)
|
||||||
|
{
|
||||||
|
for (Overlay o : overlays)
|
||||||
|
{
|
||||||
|
if (o instanceof WidgetOverlay)
|
||||||
|
{
|
||||||
|
WidgetOverlay overlay = (WidgetOverlay) o;
|
||||||
|
if (overlay.getWidgetInfo().equals(info))
|
||||||
|
{
|
||||||
|
return overlay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -32,6 +32,7 @@ import java.util.Collection;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import lombok.Getter;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.widgets.Widget;
|
import net.runelite.api.widgets.Widget;
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
@@ -64,6 +65,7 @@ public class WidgetOverlay extends Overlay
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final Client client;
|
private final Client client;
|
||||||
|
@Getter
|
||||||
private final WidgetInfo widgetInfo;
|
private final WidgetInfo widgetInfo;
|
||||||
private final Rectangle parentBounds = new Rectangle();
|
private final Rectangle parentBounds = new Rectangle();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Hydrox6 <ikada@protonmail.ch>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.ui.overlay.arrow;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.GameObject;
|
||||||
|
import net.runelite.api.NPC;
|
||||||
|
import net.runelite.api.Perspective;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.coords.LocalPoint;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Slf4j
|
||||||
|
public class ArrowMinimapOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private static final int MINIMAP_VISIBLE_RANGE = 17 * 128;
|
||||||
|
|
||||||
|
private final ArrowPointManager arrowPointManager;
|
||||||
|
private final Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ArrowMinimapOverlay(Client client, ArrowPointManager arrowPointManager)
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
this.arrowPointManager = arrowPointManager;
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setPriority(OverlayPriority.HIGH);
|
||||||
|
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
|
||||||
|
final Collection<ArrowPoint> points = arrowPointManager.getArrowPoints().values();
|
||||||
|
|
||||||
|
if (points.isEmpty())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final LocalPoint localPlayerPos = client.getLocalPlayer().getLocalLocation();
|
||||||
|
final WorldPoint worldPlayerPos = WorldPoint.fromLocal(client, localPlayerPos);
|
||||||
|
|
||||||
|
for (ArrowPoint arrowPoint : points)
|
||||||
|
{
|
||||||
|
final WorldPoint worldPoint = arrowPoint.getWorldPoint();
|
||||||
|
|
||||||
|
if (worldPoint.distanceTo(worldPlayerPos) < arrowPoint.getVisibleRange())
|
||||||
|
{
|
||||||
|
LocalPoint fallBackPoint = LocalPoint.fromWorld(client, worldPoint);
|
||||||
|
if (arrowPoint.types.contains(ArrowType.NPC))
|
||||||
|
{
|
||||||
|
boolean found = false;
|
||||||
|
for (NPC npc : client.getCachedNPCs())
|
||||||
|
{
|
||||||
|
if (npc != null && arrowPoint.getNpcIDs().contains(npc.getId()))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
renderMinimapArrow(graphics, arrowPoint, npc.getLocalLocation(), localPlayerPos, worldPlayerPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found || fallBackPoint == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMinimapArrow(graphics, arrowPoint, null, localPlayerPos, worldPlayerPos);
|
||||||
|
}
|
||||||
|
else if (arrowPoint.types.contains(ArrowType.OBJECT))
|
||||||
|
{
|
||||||
|
|
||||||
|
ArrayList<GameObject> objects = ArrowUtil.getObjects(client, arrowPoint.getObjectIDs());
|
||||||
|
if (objects.isEmpty() && fallBackPoint != null)
|
||||||
|
{
|
||||||
|
renderMinimapArrow(graphics, arrowPoint, null, localPlayerPos, worldPlayerPos);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (GameObject object : objects)
|
||||||
|
{
|
||||||
|
renderMinimapArrow(graphics, arrowPoint, object.getLocalLocation(), localPlayerPos, worldPlayerPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (arrowPoint.types.contains(ArrowType.WORLD_POINT))
|
||||||
|
{
|
||||||
|
renderMinimapArrow(graphics, arrowPoint, null, localPlayerPos, worldPlayerPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderMinimapArrow(Graphics2D graphics, ArrowPoint arrowPoint, LocalPoint localPoint, LocalPoint localPlayerPos, WorldPoint worldPlayerPos)
|
||||||
|
{
|
||||||
|
final BufferedImage minimapImage = arrowPoint.getMinimapImage();
|
||||||
|
final WorldPoint worldPoint = arrowPoint.getWorldPoint();
|
||||||
|
final Point minimapImageOffset = arrowPoint.getMinimapImageOffset();
|
||||||
|
|
||||||
|
if (localPoint != null && localPlayerPos.distanceTo(localPoint) < MINIMAP_VISIBLE_RANGE)
|
||||||
|
{
|
||||||
|
final Point minimapLoc = Perspective.getMiniMapImageLocation(client, localPoint, minimapImage);
|
||||||
|
if (minimapLoc != null)
|
||||||
|
{
|
||||||
|
graphics.drawImage(minimapImage, minimapLoc.getX() + minimapImageOffset.getX(), minimapLoc.getY() + minimapImageOffset.getY(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!arrowPoint.isMinimapUseFallback())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Point minimapPlayerPos = Perspective.localToMinimap(client, localPlayerPos);
|
||||||
|
double cameraAngle = ((client.getCameraYaw()) / 2048.0) * 2 * Math.PI;
|
||||||
|
//Use localPoint if it's available for a smoother rotation
|
||||||
|
double theta;
|
||||||
|
if (localPoint != null)
|
||||||
|
{
|
||||||
|
theta = Math.atan2(localPoint.getX() - localPlayerPos.getX(), localPlayerPos.getY() - localPoint.getY());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
theta = Math.atan2(worldPoint.getX() - worldPlayerPos.getX(), worldPlayerPos.getY() - worldPoint.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
AffineTransform at = new AffineTransform();
|
||||||
|
if (arrowPoint.isMinimapImagePointToTarget())
|
||||||
|
{
|
||||||
|
at.translate(minimapPlayerPos.getX(), minimapPlayerPos.getY());
|
||||||
|
at.rotate(cameraAngle - theta);
|
||||||
|
at.translate(0, 66);
|
||||||
|
at.translate(minimapImageOffset.getX() - minimapImage.getWidth() / 2, minimapImageOffset.getY() - minimapImage.getHeight() / 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Get the correct position as if it were rotated
|
||||||
|
at.rotate(cameraAngle - theta);
|
||||||
|
at.translate(0, 66);
|
||||||
|
double dX = at.getTranslateX();
|
||||||
|
double dY = at.getTranslateY();
|
||||||
|
//Then apply that position to an un-rotated transform
|
||||||
|
at = new AffineTransform();
|
||||||
|
at.translate(minimapPlayerPos.getX(), minimapPlayerPos.getY());
|
||||||
|
at.translate(dX, dY);
|
||||||
|
at.translate(minimapImageOffset.getX() - minimapImage.getWidth() / 2, minimapImageOffset.getY() - minimapImage.getHeight() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.drawImage(minimapImage, at, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderMinimapArrowNPC(Graphics2D graphics, ArrowPoint arrowPoint, NPC npc, LocalPoint localPlayerPos, WorldPoint worldPlayerPos)
|
||||||
|
{
|
||||||
|
final BufferedImage minimapImage = arrowPoint.getMinimapImage();
|
||||||
|
final WorldPoint worldPoint = arrowPoint.getWorldPoint();
|
||||||
|
LocalPoint localPoint;
|
||||||
|
if (npc != null)
|
||||||
|
{
|
||||||
|
localPoint = LocalPoint.fromWorld(client, worldPoint);
|
||||||
|
if (localPoint != null)
|
||||||
|
{
|
||||||
|
//For whatever reason, LocalPoint.fromWorld returns a point (-1, -1) from the actual point
|
||||||
|
localPoint = new LocalPoint(localPoint.getX() + 1, localPoint.getY() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
localPoint = npc.getLocalLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMinimapArrow(graphics, arrowPoint, localPoint, localPlayerPos, worldPlayerPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Morgan Lewis <https://github.com/MESLewis>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.ui.overlay.arrow;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class ArrowPoint
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Can define a point to mark, or be used as a fallback when an object or an NPC is outside of the scene
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private WorldPoint worldPoint;
|
||||||
|
|
||||||
|
private HashSet<Integer> npcIDs;
|
||||||
|
|
||||||
|
private HashSet<Integer> objectIDs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The regions that an NPC or Object has to be in to be marked (eg. Exam Centre locked chest Hard Clue requires
|
||||||
|
* killing a Barbarian in Barbarian Village, or Konar Slayer requires killing monsters in a certain area)
|
||||||
|
*/
|
||||||
|
private HashSet<Integer> region;
|
||||||
|
|
||||||
|
private BufferedImage worldImage;
|
||||||
|
@Builder.Default
|
||||||
|
private Point worldImageOffset = new Point(0, 0);
|
||||||
|
@Builder.Default
|
||||||
|
private Color tileColor = Color.RED;
|
||||||
|
|
||||||
|
private BufferedImage minimapImage;
|
||||||
|
@Builder.Default
|
||||||
|
private Point minimapImageOffset = new Point(0, 0);
|
||||||
|
/**
|
||||||
|
* Whether the minimap arrow should rotate. Set to false if not using an arrow
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private boolean minimapImagePointToTarget = true;
|
||||||
|
@Builder.Default
|
||||||
|
private int visibleRange = 128;
|
||||||
|
/**
|
||||||
|
* Whether the minimap arrow should use the fallback point. Useful when there are multiple locations that could be
|
||||||
|
* used as a fallback (eg. Seers' Village locked draw Medium Clue, where you need to kill any chicken for a key)
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private boolean minimapUseFallback = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Set of what arrows should be rendered
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
EnumSet<ArrowType> types;
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Morgan Lewis <https://github.com/MESLewis>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.ui.overlay.arrow;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.runelite.api.events.NpcSpawned;
|
||||||
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class ArrowPointManager
|
||||||
|
{
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private final Multimap<Plugin, ArrowPoint> arrowPoints = HashMultimap.create();
|
||||||
|
|
||||||
|
public void add(Plugin plugin, ArrowPoint arrowPoint)
|
||||||
|
{
|
||||||
|
arrowPoints.put(plugin, arrowPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(Plugin plugin, ArrowPoint arrowPoint)
|
||||||
|
{
|
||||||
|
arrowPoints.remove(plugin, arrowPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear(Plugin plugin)
|
||||||
|
{
|
||||||
|
arrowPoints.removeAll(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
arrowPoints.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package net.runelite.client.ui.overlay.arrow;
|
||||||
|
|
||||||
|
public enum ArrowType
|
||||||
|
{
|
||||||
|
MINIMAP,
|
||||||
|
NPC,
|
||||||
|
OBJECT,
|
||||||
|
WORLD_MAP,
|
||||||
|
WORLD_POINT
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package net.runelite.client.ui.overlay.arrow;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.GameObject;
|
||||||
|
import net.runelite.api.ObjectComposition;
|
||||||
|
import net.runelite.api.Scene;
|
||||||
|
import net.runelite.api.Tile;
|
||||||
|
|
||||||
|
class ArrowUtil
|
||||||
|
{
|
||||||
|
static ArrayList<GameObject> getObjects(final Client client, HashSet<Integer> objectIDs)
|
||||||
|
{
|
||||||
|
final Scene scene = client.getScene();
|
||||||
|
final Tile[][] tiles = scene.getTiles()[client.getPlane()];
|
||||||
|
final ArrayList<GameObject> found = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Tile[] tiles2 : tiles)
|
||||||
|
{
|
||||||
|
for (Tile tile : tiles2)
|
||||||
|
{
|
||||||
|
for (GameObject object : tile.getGameObjects())
|
||||||
|
{
|
||||||
|
if (object == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objectIDs.contains(object.getId()))
|
||||||
|
{
|
||||||
|
found.add(object);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check impostors
|
||||||
|
final ObjectComposition comp = client.getObjectDefinition(object.getId());
|
||||||
|
final ObjectComposition impostor = comp.getImpostorIds() != null ? comp.getImpostor() : comp;
|
||||||
|
|
||||||
|
if (impostor != null && objectIDs.contains(impostor.getId()))
|
||||||
|
{
|
||||||
|
found.add(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Hydrox6 <ikada@protonmail.ch>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.ui.overlay.arrow;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Polygon;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.GameObject;
|
||||||
|
import net.runelite.api.NPC;
|
||||||
|
import net.runelite.api.Perspective;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.coords.LocalPoint;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Slf4j
|
||||||
|
public class ArrowWorldOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private static final int Z_OFFSET = 20;
|
||||||
|
|
||||||
|
private final ArrowPointManager arrowPointManager;
|
||||||
|
private final Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ArrowWorldOverlay(Client client, ArrowPointManager arrowPointManager)
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
this.arrowPointManager = arrowPointManager;
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setPriority(OverlayPriority.HIGHEST);
|
||||||
|
setLayer(OverlayLayer.UNDER_WIDGETS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D graphics)
|
||||||
|
{
|
||||||
|
final Collection<ArrowPoint> points = arrowPointManager.getArrowPoints().values();
|
||||||
|
|
||||||
|
if (points.isEmpty())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation();
|
||||||
|
|
||||||
|
for (ArrowPoint arrowPoint : points)
|
||||||
|
{
|
||||||
|
WorldPoint point = arrowPoint.getWorldPoint();
|
||||||
|
|
||||||
|
if (point.distanceTo(playerLocation) < client.getScene().getDrawDistance())
|
||||||
|
{
|
||||||
|
LocalPoint fallBackPoint = LocalPoint.fromWorld(client, point);
|
||||||
|
if (arrowPoint.types.contains(ArrowType.NPC))
|
||||||
|
{
|
||||||
|
boolean found = false;
|
||||||
|
for (NPC npc : client.getCachedNPCs())
|
||||||
|
{
|
||||||
|
if (npc != null && arrowPoint.getNpcIDs().contains(npc.getId()))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
renderWorldArrow(graphics, arrowPoint, npc.getLocalLocation(), npc.getLogicalHeight() + Z_OFFSET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found || fallBackPoint == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderWorldArrow(graphics, arrowPoint, fallBackPoint);
|
||||||
|
}
|
||||||
|
else if (arrowPoint.types.contains(ArrowType.OBJECT))
|
||||||
|
{
|
||||||
|
|
||||||
|
ArrayList<GameObject> objects = ArrowUtil.getObjects(client, arrowPoint.getObjectIDs());
|
||||||
|
if (objects.isEmpty() && fallBackPoint != null)
|
||||||
|
{
|
||||||
|
renderWorldArrow(graphics, arrowPoint, fallBackPoint);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (GameObject object : objects)
|
||||||
|
{
|
||||||
|
if (object.getRenderable().getModel() == null)
|
||||||
|
{
|
||||||
|
renderWorldArrow(graphics, arrowPoint, object.getLocalLocation(), 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
renderWorldArrow(graphics, arrowPoint, object.getLocalLocation(), object.getRenderable().getModel().getModelHeight() + Z_OFFSET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (arrowPoint.types.contains(ArrowType.WORLD_POINT))
|
||||||
|
{
|
||||||
|
renderWorldArrow(graphics, arrowPoint, fallBackPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderWorldArrow(Graphics2D graphics, ArrowPoint arrowPoint, LocalPoint localPoint)
|
||||||
|
{
|
||||||
|
renderWorldArrow(graphics, arrowPoint, localPoint, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderWorldArrow(Graphics2D graphics, ArrowPoint arrowPoint, LocalPoint localPoint, int zOffset)
|
||||||
|
{
|
||||||
|
final BufferedImage worldImage = arrowPoint.getWorldImage();
|
||||||
|
//Draw Tile
|
||||||
|
Polygon poly = Perspective.getCanvasTilePoly(client, localPoint);
|
||||||
|
if (poly != null)
|
||||||
|
{
|
||||||
|
OverlayUtil.renderPolygon(graphics, poly, arrowPoint.getTileColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
Point worldIconOffset = arrowPoint.getWorldImageOffset();
|
||||||
|
//Draw World Arrow
|
||||||
|
Point canvasPoint = Perspective.getCanvasImageLocation(client, localPoint, worldImage, zOffset);
|
||||||
|
if (canvasPoint != null)
|
||||||
|
{
|
||||||
|
graphics.drawImage(worldImage, canvasPoint.getX() + worldIconOffset.getX(), canvasPoint.getY() + worldIconOffset.getY(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ import com.google.inject.Guice;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.testing.fieldbinder.Bind;
|
import com.google.inject.testing.fieldbinder.Bind;
|
||||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||||
|
import java.util.EnumSet;
|
||||||
import net.runelite.api.AnimationID;
|
import net.runelite.api.AnimationID;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
@@ -36,6 +37,7 @@ import net.runelite.api.NPC;
|
|||||||
import net.runelite.api.NPCComposition;
|
import net.runelite.api.NPCComposition;
|
||||||
import net.runelite.api.Player;
|
import net.runelite.api.Player;
|
||||||
import net.runelite.api.VarPlayer;
|
import net.runelite.api.VarPlayer;
|
||||||
|
import net.runelite.api.WorldType;
|
||||||
import net.runelite.api.events.AnimationChanged;
|
import net.runelite.api.events.AnimationChanged;
|
||||||
import net.runelite.api.events.GameStateChanged;
|
import net.runelite.api.events.GameStateChanged;
|
||||||
import net.runelite.api.events.GameTick;
|
import net.runelite.api.events.GameTick;
|
||||||
@@ -118,6 +120,7 @@ public class IdleNotifierPluginTest
|
|||||||
when(client.getGameState()).thenReturn(GameState.LOGGED_IN);
|
when(client.getGameState()).thenReturn(GameState.LOGGED_IN);
|
||||||
when(client.getKeyboardIdleTicks()).thenReturn(42);
|
when(client.getKeyboardIdleTicks()).thenReturn(42);
|
||||||
when(client.getMouseLastPressedMillis()).thenReturn(System.currentTimeMillis() - 100_000L);
|
when(client.getMouseLastPressedMillis()).thenReturn(System.currentTimeMillis() - 100_000L);
|
||||||
|
when(client.getWorldType()).thenReturn(EnumSet.of(WorldType.DEADMAN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user