diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java index d987c0062c..d61416bb0c 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -215,6 +215,13 @@ public enum Varbits */ EXPERIENCE_DROP_COLOR(4695), + /** + * Tithe Farm + */ + TITHE_FARM_SACK_AMOUNT(4900), + TITHE_FARM_SACK_ICON(5370), + TITHE_FARM_POINTS(4893), + /** * Raids */ diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index 9083d91c47..395d37d1ba 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -76,6 +76,7 @@ public class WidgetID public static final int PYRAMID_PLUNDER_GROUP_ID = 428; public static final int RAIDS_REWARD_GROUP_ID = 539; public static final int EXPERIENCE_TRACKER_GROUP_ID = 122; + public static final int TITHE_FARM_GROUP_ID = 241; static class WorldMap { diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index 5275ed3733..c641d9bb91 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -226,7 +226,9 @@ public enum WidgetInfo PYRAMID_PLUNDER_DATA(WidgetID.PYRAMID_PLUNDER_GROUP_ID, 0), EXPERIENCE_TRACKER(WidgetID.EXPERIENCE_TRACKER_GROUP_ID, WidgetID.ExperienceTracker.WIDGET), - EXPERIENCE_TRACKER_BOTTOM_BAR(WidgetID.EXPERIENCE_TRACKER_GROUP_ID, WidgetID.ExperienceTracker.BOTTOM_BAR); + EXPERIENCE_TRACKER_BOTTOM_BAR(WidgetID.EXPERIENCE_TRACKER_GROUP_ID, WidgetID.ExperienceTracker.BOTTOM_BAR), + + TITHE_FARM(WidgetID.TITHE_FARM_GROUP_ID, 1); private final int groupId; private final int childId; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmInventoryOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmInventoryOverlay.java new file mode 100644 index 0000000000..2b3178d9d1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmInventoryOverlay.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.tithefarm; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import javax.inject.Inject; +import net.runelite.api.Query; +import net.runelite.api.queries.InventoryWidgetItemQuery; +import net.runelite.api.widgets.WidgetItem; +import net.runelite.client.ui.FontManager; +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.components.TextComponent; +import net.runelite.client.util.QueryRunner; + +class TitheFarmInventoryOverlay extends Overlay +{ + private final QueryRunner queryRunner; + private final TitheFarmPluginConfig config; + + private final TextComponent textComponent = new TextComponent(); + + @Inject + TitheFarmInventoryOverlay(QueryRunner queryRunner, TitheFarmPluginConfig config) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_WIDGETS); + this.queryRunner = queryRunner; + this.config = config; + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (!config.showWateringCanOverlay()) + { + return null; + } + graphics.setFont(FontManager.getRunescapeSmallFont()); + + Query inventoryQuery = new InventoryWidgetItemQuery(); + WidgetItem[] inventoryItems = queryRunner.runQuery(inventoryQuery); + + for (WidgetItem item : inventoryItems) + { + WateringCan wateringCan = WateringCan.getWateringCan(item.getId()); + if (wateringCan == null) + { + continue; + } + + final Rectangle bounds = item.getCanvasBounds(); + textComponent.setPosition(new Point(bounds.x, bounds.y + 16)); + textComponent.setColor(wateringCan.getColor()); + textComponent.setText(String.valueOf(wateringCan.getCharges())); + textComponent.render(graphics); + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlant.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlant.java new file mode 100644 index 0000000000..f7dce4fbfc --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlant.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.tithefarm; + +import java.time.Duration; +import java.time.Instant; +import lombok.Getter; +import lombok.Setter; +import net.runelite.api.GameObject; +import net.runelite.api.coords.WorldPoint; + +class TitheFarmPlant +{ + private static final Duration PLANT_TIME = Duration.ofMinutes(1); + + @Getter + @Setter + private Instant planted; + + @Getter + private final TitheFarmPlantState state; + + @Getter + private final TitheFarmPlantType type; + + @Getter + private final GameObject gameObject; + + @Getter + private final WorldPoint worldLocation; + + TitheFarmPlant(TitheFarmPlantState state, TitheFarmPlantType type, GameObject gameObject) + { + this.planted = Instant.now(); + this.state = state; + this.type = type; + this.gameObject = gameObject; + this.worldLocation = gameObject.getWorldLocation(); + } + + public double getPlantTimeRelative() + { + Duration duration = Duration.between(planted, Instant.now()); + return duration.compareTo(PLANT_TIME) < 0 ? (double) duration.toMillis() / PLANT_TIME.toMillis() : 1; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantOverlay.java new file mode 100644 index 0000000000..d9c113f715 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantOverlay.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.tithefarm; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.geom.Arc2D; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.widgets.Widget; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; + +public class TitheFarmPlantOverlay extends Overlay +{ + private static final int TIMER_SIZE = 25; + private static final int TIMER_BORDER_WIDTH = 1; + + private final Client client; + private final TitheFarmPlugin plugin; + private final TitheFarmPluginConfig config; + + @Inject + TitheFarmPlantOverlay(Client client, TitheFarmPlugin plugin, TitheFarmPluginConfig config) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + this.plugin = plugin; + this.config = config; + this.client = client; + } + + @Override + public Dimension render(Graphics2D graphics) + { + Widget viewport = client.getViewportWidget(); + for (TitheFarmPlant plant : plugin.getPlants()) + { + LocalPoint localLocation = LocalPoint.fromWorld(client, plant.getWorldLocation()); + net.runelite.api.Point canvasLocation = Perspective.worldToCanvas(client, localLocation.getX(), localLocation.getY(), client.getPlane()); + if (viewport != null && localLocation != null) + { + switch (plant.getState()) + { + case UNWATERED: + drawTimerOnPlant(graphics, plant, canvasLocation, config.getColorUnwatered()); + break; + case WATERED: + drawTimerOnPlant(graphics, plant, canvasLocation, config.getColorWatered()); + break; + case GROWN: + drawTimerOnPlant(graphics, plant, canvasLocation, config.getColorGrown()); + break; + } + } + } + + return null; + } + + private void drawTimerOnPlant(Graphics2D graphics, TitheFarmPlant plant, net.runelite.api.Point loc, Color color) + { + //Construct the arc + Arc2D.Float arc = new Arc2D.Float(Arc2D.PIE); + arc.setAngleStart(90); + double timeLeft = 1 - plant.getPlantTimeRelative(); + arc.setAngleExtent(timeLeft * 360); + arc.setFrame(loc.getX() - TIMER_SIZE / 2, loc.getY() - TIMER_SIZE / 2, TIMER_SIZE, TIMER_SIZE); + + //Draw the inside of the arc + graphics.setColor(color); + graphics.fill(arc); + + //Draw the outlines of the arc + graphics.setStroke(new BasicStroke(TIMER_BORDER_WIDTH)); + graphics.drawOval(loc.getX() - TIMER_SIZE / 2, loc.getY() - TIMER_SIZE / 2, TIMER_SIZE, TIMER_SIZE); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantState.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantState.java new file mode 100644 index 0000000000..a1331808ba --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantState.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.tithefarm; + +enum TitheFarmPlantState +{ + UNWATERED, + WATERED, + DEAD, + GROWN; + + public static TitheFarmPlantState getState(int objectId) + { + TitheFarmPlantType plantType = TitheFarmPlantType.getPlantType(objectId); + if (plantType == null) + { + return null; + } + + int baseId = plantType.getBaseId(); + if (objectId == baseId) + { + return GROWN; + } + + switch ((baseId - objectId) % 3) + { + case 0: + return UNWATERED; + case 2: + return WATERED; + default: + return DEAD; + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantType.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantType.java new file mode 100644 index 0000000000..413838c144 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantType.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.tithefarm; + +import java.util.HashMap; +import java.util.Map; +import lombok.Getter; +import net.runelite.api.ObjectID; + +public enum TitheFarmPlantType +{ + EMPTY("Empty", ObjectID.TITHE_PATCH, + ObjectID.TITHE_PATCH + ), + GOLOVANOVA("Golovanova", ObjectID.GOLOVANOVA_PLANT_27393, + ObjectID.GOLOVANOVA_SEEDLING, ObjectID.GOLOVANOVA_SEEDLING_27385, ObjectID.BLIGHTED_GOLOVANOVA_SEEDLING, + ObjectID.GOLOVANOVA_PLANT, ObjectID.GOLOVANOVA_PLANT_27388, ObjectID.BLIGHTED_GOLOVANOVA_PLANT, + ObjectID.GOLOVANOVA_PLANT_27390, ObjectID.GOLOVANOVA_PLANT_27391, ObjectID.BLIGHTED_GOLOVANOVA_PLANT_27392, + ObjectID.GOLOVANOVA_PLANT_27393, ObjectID.BLIGHTED_GOLOVANOVA_PLANT_27394 + ), + BOLOGANO("Bologano", ObjectID.BOLOGANO_PLANT_27404, + ObjectID.BOLOGANO_SEEDLING, ObjectID.BOLOGANO_SEEDLING_27396, ObjectID.BLIGHTED_BOLOGANO_SEEDLING, + ObjectID.BOLOGANO_PLANT, ObjectID.BOLOGANO_PLANT_27399, ObjectID.BLIGHTED_BOLOGANO_PLANT, + ObjectID.BOLOGANO_PLANT_27401, ObjectID.BOLOGANO_PLANT_27402, ObjectID.BLIGHTED_BOLOGANO_PLANT_27403, + ObjectID.BOLOGANO_PLANT_27404, ObjectID.BLIGHTED_BOLOGANO_PLANT_27405 + ), + LOGAVANO("Logavano", ObjectID.LOGAVANO_PLANT_27415, + ObjectID.LOGAVANO_SEEDLING, ObjectID.LOGAVANO_SEEDLING_27407, ObjectID.BLIGHTED_LOGAVANO_SEEDLING, + ObjectID.LOGAVANO_PLANT, ObjectID.LOGAVANO_PLANT_27410, ObjectID.BLIGHTED_LOGAVANO_PLANT, + ObjectID.LOGAVANO_PLANT_27412, ObjectID.LOGAVANO_PLANT_27413, ObjectID.BLIGHTED_LOGAVANO_PLANT_27414, + ObjectID.LOGAVANO_PLANT_27415, ObjectID.BLIGHTED_LOGAVANO_PLANT_27416 + ); + + @Getter + private final String name; + @Getter + private final int baseId; + @Getter + private final int[] objectIds; + + private static final Map plantTypes = new HashMap<>(); + + static + { + TitheFarmPlantType[] types = values(); + + for (TitheFarmPlantType type : types) + { + for (int spotId : type.getObjectIds()) + { + plantTypes.put(spotId, type); + } + } + } + + TitheFarmPlantType(String name, int baseId, int... objectIds) + { + this.name = name; + this.baseId = baseId; + this.objectIds = objectIds; + } + + public static TitheFarmPlantType getPlantType(int objectId) + { + return plantTypes.get(objectId); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlugin.java new file mode 100644 index 0000000000..3dd687a74b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlugin.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.tithefarm; + +import com.google.common.eventbus.Subscribe; +import com.google.inject.Provides; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import javax.inject.Inject; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.GameObject; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.GameObjectSpawned; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.task.Schedule; +import net.runelite.client.ui.overlay.Overlay; + +@Slf4j +@PluginDescriptor( + name = "Tithe Farm" +) +public class TitheFarmPlugin extends Plugin +{ + @Inject + private TitheFarmPluginConfig config; + + @Inject + private TitheFarmPlantOverlay titheFarmOverlay; + + @Inject + private TitheFarmSackOverlay titheFarmSackOverlay; + + @Inject + private TitheFarmInventoryOverlay titheFarmInventoryOverlay; + + @Getter + private final Set plants = new HashSet<>(); + + @Provides + TitheFarmPluginConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(TitheFarmPluginConfig.class); + } + + @Override + public Collection getOverlays() + { + return Arrays.asList(titheFarmOverlay, titheFarmSackOverlay, titheFarmInventoryOverlay); + } + + @Schedule(period = 600, unit = ChronoUnit.MILLIS) + public void checkPlants() + { + plants.removeIf(plant -> plant.getPlantTimeRelative() == 1); + } + + @Subscribe + public void onGameObjectSpawned(GameObjectSpawned event) + { + GameObject gameObject = event.getGameObject(); + + TitheFarmPlantType type = TitheFarmPlantType.getPlantType(gameObject.getId()); + if (type == null) + { + return; + } + + TitheFarmPlantState state = TitheFarmPlantState.getState(gameObject.getId()); + + TitheFarmPlant newPlant = new TitheFarmPlant(state, type, gameObject); + TitheFarmPlant oldPlant = getPlantFromCollection(gameObject); + + if (oldPlant == null && newPlant.getType() != TitheFarmPlantType.EMPTY) + { + log.debug("Added plant {}", newPlant); + plants.add(newPlant); + } + else if (oldPlant == null) + { + return; + } + else if (newPlant.getType() == TitheFarmPlantType.EMPTY) + { + log.debug("Removed plant {}", oldPlant); + plants.remove(oldPlant); + } + else if (oldPlant.getGameObject().getId() != newPlant.getGameObject().getId()) + { + if (oldPlant.getState() != TitheFarmPlantState.WATERED && newPlant.getState() == TitheFarmPlantState.WATERED) + { + log.debug("Updated plant (watered)"); + newPlant.setPlanted(oldPlant.getPlanted()); + plants.remove(oldPlant); + plants.add(newPlant); + } + else + { + log.debug("Updated plant"); + plants.remove(oldPlant); + plants.add(newPlant); + } + } + } + + private TitheFarmPlant getPlantFromCollection(GameObject gameObject) + { + WorldPoint gameObjectLocation = gameObject.getWorldLocation(); + for (TitheFarmPlant plant : plants) + { + if (gameObjectLocation.equals(plant.getWorldLocation())) + { + return plant; + } + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPluginConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPluginConfig.java new file mode 100644 index 0000000000..84ce84af0c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPluginConfig.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.tithefarm; + +import java.awt.Color; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup( + keyName = "tithefarmplugin", + name = "Tithe Farm", + description = "Configuration for the Tithe Farm plugin" +) +public interface TitheFarmPluginConfig extends Config +{ + @ConfigItem( + position = 0, + keyName = "showWateringCanOverlay", + name = "Show watering can doses", + description = "Configures whether or not the watering can doses are displayed" + ) + default boolean showWateringCanOverlay() + { + return true; + } + + @ConfigItem( + position = 1, + keyName = "showSack", + name = "Show fruit sack", + description = "Configures whether or not the fruit sack is displayed" + ) + default boolean showSack() + { + return true; + } + + @ConfigItem( + position = 2, + keyName = "hexColorUnwatered", + name = "Unwatered plant", + description = "Color of unwatered plant timer" + ) + default Color getColorUnwatered() + { + return new Color(255, 187, 0); + } + + @ConfigItem( + position = 3, + keyName = "hexColorWatered", + name = "Watered plant", + description = "Color of watered plant timer" + ) + default Color getColorWatered() + { + return new Color(0, 153, 255); + } + + @ConfigItem( + position = 4, + keyName = "hexColorGrown", + name = "Grown plant", + description = "Color of grown plant timer" + ) + default Color getColorGrown() + { + return new Color(0, 217, 0); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmSackOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmSackOverlay.java new file mode 100644 index 0000000000..b324de730f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmSackOverlay.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.tithefarm; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Varbits; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.PanelComponent; + +class TitheFarmSackOverlay extends Overlay +{ + private final Client client; + private final TitheFarmPluginConfig config; + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + TitheFarmSackOverlay(Client client, TitheFarmPluginConfig config) + { + setPosition(OverlayPosition.TOP_LEFT); + this.client = client; + this.config = config; + } + + @Override + public Dimension render(Graphics2D graphics) + { + Widget sack = client.getWidget(WidgetInfo.TITHE_FARM); + if (sack == null) + { + return null; + } + + panelComponent.getLines().clear(); + + sack.setHidden(true); + if (config.showSack()) + { + panelComponent.getLines().add(new PanelComponent.Line( + "Fruits in sack:", + String.valueOf(client.getSetting(Varbits.TITHE_FARM_SACK_AMOUNT)) + )); + panelComponent.getLines().add(new PanelComponent.Line( + "Points:", + String.valueOf(client.getSetting(Varbits.TITHE_FARM_POINTS)) + )); + } + + return panelComponent.render(graphics); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/WateringCan.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/WateringCan.java new file mode 100644 index 0000000000..aa18b546e9 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/WateringCan.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018, Unmoon + * 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.tithefarm; + +import java.awt.Color; +import java.util.HashMap; +import java.util.Map; +import lombok.Getter; +import net.runelite.api.ItemID; + +enum WateringCan +{ + WATERING_CAN0(ItemID.WATERING_CAN, 0, Color.RED), + WATERING_CAN1(ItemID.WATERING_CAN1, 1, Color.ORANGE), + WATERING_CAN2(ItemID.WATERING_CAN2, 2, Color.YELLOW), + WATERING_CAN3(ItemID.WATERING_CAN3, 3, Color.WHITE), + WATERING_CAN4(ItemID.WATERING_CAN4, 4, Color.WHITE), + WATERING_CAN5(ItemID.WATERING_CAN5, 5, Color.WHITE), + WATERING_CAN6(ItemID.WATERING_CAN6, 6, Color.WHITE), + WATERING_CAN7(ItemID.WATERING_CAN7, 7, Color.WHITE), + WATERING_CAN8(ItemID.WATERING_CAN8, 8, Color.WHITE); + + @Getter + private final int id; + @Getter + private final int charges; + @Getter + private final Color color; + + private static final Map wateringCans = new HashMap<>(); + + static + { + for (WateringCan can : values()) + { + wateringCans.put(can.getId(), can); + } + } + + WateringCan(int id, int charges, Color color) + { + this.id = id; + this.charges = charges; + this.color = color; + } + + public static WateringCan getWateringCan(int itemId) + { + return wateringCans.get(itemId); + } +}