Fixed issue where eating/firemaking/decanting replaced item from incorrect inventory slot

Corrected potion decanting and bank pin interface sounds
This commit is contained in:
Woahscam
2023-08-28 13:08:45 +00:00
committed by Ryan
parent 1d775bd2d3
commit 93082bc94a
9 changed files with 307 additions and 317 deletions
@@ -2,12 +2,12 @@ package content.data.consumables;
import content.data.consumables.effects.*; import content.data.consumables.effects.*;
import core.game.consumable.*; import core.game.consumable.*;
import org.rs09.consts.Items;
import core.game.node.entity.player.link.diary.DiaryType; import core.game.node.entity.player.link.diary.DiaryType;
import core.game.world.update.flag.context.Animation;
import core.game.node.entity.skill.Skills; import core.game.node.entity.skill.Skills;
import content.data.consumables.effects.KegOfBeerEffect; import core.game.world.update.flag.context.Animation;
import org.rs09.consts.Items;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import static core.tools.TickUtilsKt.minutesToTicks; import static core.tools.TickUtilsKt.minutesToTicks;
@@ -377,6 +377,8 @@ public enum Consumables {
public static HashMap<Integer,Consumables> consumables = new HashMap<>(); public static HashMap<Integer,Consumables> consumables = new HashMap<>();
public static ArrayList<Integer> potions = new ArrayList<>();
private final Consumable consumable; private final Consumable consumable;
public boolean isIgnoreMainClock = false; public boolean isIgnoreMainClock = false;
@@ -405,6 +407,11 @@ public enum Consumables {
static { static {
for (Consumables consumable : Consumables.values()) { for (Consumables consumable : Consumables.values()) {
add(consumable); add(consumable);
if (consumable.consumable instanceof Potion) {
for (int pot : consumable.consumable.getIds()) {
potions.add(pot);
}
}
} }
} }
} }
@@ -1,18 +1,21 @@
package content.global.handlers.npc package content.global.handlers.npc
import core.api.*
import content.data.consumables.Consumables import content.data.consumables.Consumables
import core.api.*
import core.game.consumable.Potion import core.game.consumable.Potion
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.dialogue.DialogueFile import core.game.dialogue.DialogueFile
import core.game.interaction.InteractionListener
import core.game.interaction.IntType import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.node.item.Item
import core.tools.END_DIALOGUE import core.tools.END_DIALOGUE
import org.rs09.consts.NPCs import org.rs09.consts.Items
class DecantListener : InteractionListener { class DecantListener : InteractionListener {
companion object {
val potions = Consumables.potions.toIntArray()
}
override fun defineListeners() { override fun defineListeners() {
on(IntType.NPC,"decant"){ player, node -> on(IntType.NPC,"decant"){ player, node ->
val (toRemove, toAdd) = decantContainer(player.inventory) val (toRemove, toAdd) = decantContainer(player.inventory)
@@ -23,6 +26,63 @@ class DecantListener : InteractionListener {
player.dialogueInterpreter.open(DecantingDialogue(),node.asNpc()) player.dialogueInterpreter.open(DecantingDialogue(),node.asNpc())
return@on true return@on true
} }
onUseWith(IntType.ITEM, potions, *potions) { player, used, with ->
if (used !is Item) return@onUseWith false
if (with !is Item) return@onUseWith false
// Verify these are both the same potion types
val potionUsed = Consumables.getConsumableById(used.id)?.consumable as? Potion ?: return@onUseWith false
val potionWith = Consumables.getConsumableById(with.id)?.consumable as? Potion ?: return@onUseWith false
if (potionUsed != potionWith) {
return@onUseWith false
}
// Dosage math
val usedDose = potionUsed.getDose(used)
val withDose = potionWith.getDose(with)
// Shouldn't be able to combine a 4 dose potion
if (usedDose == 4 || withDose == 4) {
return@onUseWith false
}
val totalDosage = usedDose + withDose
val fullDoses = totalDosage / 4
val leftoverDose = totalDosage % 4
// Replace the targeted potion item with a (4) dose potion
if (fullDoses != 0) {
replaceSlot(player, with.slot, Item(potionWith.ids.first()), with, Container.INVENTORY)
}
// Replace the targeted potion item with the updated dosage amount
if (leftoverDose != 0 && fullDoses == 0) {
replaceSlot(player, with.slot, Item(potionUsed.ids[potionUsed.ids.size - totalDosage]), with, Container.INVENTORY)
// Replace the used with potion item with the updated dosage amount
} else if (leftoverDose != 0) {
replaceSlot(player, used.slot, Item(potionUsed.ids[potionUsed.ids.size - leftoverDose]), used, Container.INVENTORY)
}
// Replace the used with potion item with an empty vial
if (leftoverDose == 0 || fullDoses == 0) {
replaceSlot(player, used.slot, Item(Items.VIAL_229), used, Container.INVENTORY)
}
// Send message/Play sound
val amountString = when {
totalDosage >= 4 -> "four"
totalDosage == 3 -> "three"
else -> "two"
}
sendMessage(player, "You have combined the liquid into $amountString doses.")
playAudio(player, 2401)
return@onUseWith true
}
} }
internal class DecantingDialogue : DialogueFile(){ internal class DecantingDialogue : DialogueFile(){
@@ -33,5 +93,4 @@ class DecantListener : InteractionListener {
} }
} }
} }
} }
@@ -1,5 +1,6 @@
package content.global.skill.firemaking; package content.global.skill.firemaking;
import core.api.Container;
import core.game.event.LitFireEvent; import core.game.event.LitFireEvent;
import core.game.node.entity.skill.SkillPulse; import core.game.node.entity.skill.SkillPulse;
import core.game.node.entity.skill.Skills; import core.game.node.entity.skill.Skills;
@@ -13,6 +14,10 @@ import core.game.world.GameWorld;
import core.game.world.map.RegionManager; import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Animation;
import core.tools.RandomFunction; import core.tools.RandomFunction;
import org.rs09.consts.Items;
import static core.api.ContentAPIKt.inInventory;
import static core.api.ContentAPIKt.replaceSlot;
/** /**
* Represents the pulse used to light a log. * Represents the pulse used to light a log.
@@ -28,7 +33,8 @@ public final class FireMakingPulse extends SkillPulse<Item> {
/** /**
* Represents the tinderbox item. * Represents the tinderbox item.
*/ */
private static final Item TINDERBOX = new Item(590); private static final Item TINDERBOX = new Item(Items.TINDERBOX_590);
/** /**
* Represents the log being burned. * Represents the log being burned.
@@ -82,7 +88,8 @@ public final class FireMakingPulse extends SkillPulse<Item> {
} }
if (player.getAttribute("remove-log", false)) { if (player.getAttribute("remove-log", false)) {
player.removeAttribute("remove-log"); player.removeAttribute("remove-log");
if (player.getInventory().remove(node)) { if (inInventory(player, node.getId(), 1)) {
replaceSlot(player, node.getSlot(), new Item(node.getId(), (node.getAmount() - 1)), node, Container.INVENTORY);
GroundItemManager.create(groundItem); GroundItemManager.create(groundItem);
} }
} }
@@ -139,7 +146,7 @@ public final class FireMakingPulse extends SkillPulse<Item> {
@Override @Override
public void message(int type) { public void message(int type) {
String name = node.getId() == 3125 ? "bones" : "logs"; String name = node.getId() == Items.JOGRE_BONES_3125 ? "bones" : "logs";
switch (type) { switch (type) {
case 0: case 0:
player.getPacketDispatch().sendMessage("You attempt to light the " + name + ".."); player.getPacketDispatch().sendMessage("You attempt to light the " + name + "..");
@@ -171,7 +178,7 @@ public final class FireMakingPulse extends SkillPulse<Item> {
* @return {@code GroundItem} the itemm. * @return {@code GroundItem} the itemm.
*/ */
public static GroundItem getAsh(final Player player, Log fire, final Scenery object) { public static GroundItem getAsh(final Player player, Log fire, final Scenery object) {
final GroundItem ash = new GroundItem(new Item(592), object.getLocation(), player); final GroundItem ash = new GroundItem(new Item(Items.ASHES_592), object.getLocation(), player);
ash.setDecayTime(fire.getLife() + 200); ash.setDecayTime(fire.getLife() + 200);
return ash; return ash;
} }
@@ -1,259 +0,0 @@
package content.global.skill.herblore;
import core.cache.def.impl.ItemDefinition;
import core.game.interaction.NodeUsageEvent;
import core.game.interaction.UseWithHandler;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import core.plugin.Initializable;
import core.plugin.Plugin;
import java.util.HashMap;
import java.util.Map;
/**
* Represents the plugin used to handle the decanting of potions.
* @author 'Vexia
*/
@Initializable
public final class PotionDecantingPlugin extends UseWithHandler {
/**
* Represents the empty item vial.
*/
private static final Item EMPTY_VIAL = new Item(229, 1);
/**
* Represents the array of potions to utilitize.
*/
public static final int[] POTIONS = new int[] {
/* empty vial */229,
/* Strength potion(4) */113,
/* Strength potion(3) */115,
/* Strength potion(2) */117,
/* Strength potion(1) */119,
/* Attack potion(3) */121,
/* Attack potion(2) */123,
/* Attack potion(1) */125,
/* Restore potion(3) */127,
/* Restore potion(2) */129,
/* Restore potion(1) */131,
/* Defence potion(3) */133,
/* Defence potion(2) */135,
/* Defence potion(1) */137,
/* Prayer potion(3) */139,
/* Prayer potion(2) */141,
/* Prayer potion(1) */143,
/* Super attack(3) */145,
/* Super attack(2) */147,
/* Super attack(1) */149,
/* Fishing potion(3) */151,
/* Fishing potion(2) */153,
/* Fishing potion(1) */155,
/* Super strength(3) */157,
/* Super strength(2) */159,
/* Super strength(1) */161,
/* Super defence(3) */163,
/* Super defence(2) */165,
/* Super defence(1) */167,
/* Ranging potion(3) */169,
/* Ranging potion(2) */171,
/* Ranging potion(1) */173,
/* Antipoison(3) */175,
/* Antipoison(2) */177,
/* Antipoison(1) */179,
/* Super antipoison(3) */181,
/* Super antipoison(2) */183,
/* Super antipoison(1) */185,
/* Bravery potion */739,
/* Cadava potion */756,
/* Magic ogre potion */2395,
/* Attack potion(4) */2428,
/* Restore potion(4) */2430,
/* Defence potion(4) */2432,
/* Prayer potion(4) */2434,
/* Super attack(4) */2436,
/* Fishing potion(4) */2438,
/* Super strength(4) */2440,
/* Super defence(4) */2442,
/* Ranging potion(4) */2444,
/* Antipoison(4) */2446,
/* Super antipoison(4) */2448,
/* Antifire potion(4) */2452,
/* Antifire potion(3) */2454,
/* Antifire potion(2) */2456,
/* Antifire potion(1) */2458,
/* Energy potion(4) */3008,
/* Energy potion(3) */3010,
/* Energy potion(2) */3012,
/* Energy potion(1) */3014,
/* Super energy(4) */3016,
/* Super energy(3) */3018,
/* Super energy(2) */3020,
/* Super energy(1) */3022,
/* Super restore(4) */3024,
/* Super restore(3) */3026,
/* Super restore(2) */3028,
/* Super restore(1) */3030,
/* Agility potion(4) */3032,
/* Agility potion(3) */3034,
/* Agility potion(2) */3036,
/* Agility potion(1) */3038,
/* Magic potion(4) */3040,
/* Magic potion(3) */3042,
/* Magic potion(2) */3044,
/* Magic potion(1) */3046,
/* Troll potion */3265,
/* Explosive potion */4045,
/* Super kebab */4608,
/* Strange potion */4836,
/* Antipoison+(4) */5943,
/* Antipoison+(3) */5945,
/* Antipoison+(2) */5947,
/* Antipoison+(1) */5949,
/* Antipoison++(4) */5952,
/* Antipoison++(3) */5954,
/* Antipoison++(2) */5956,
/* Antipoison++(1) */5958,
/* Supercompost */6034,
/* Compost potion(4) */6470,
/* Compost potion(3) */6472,
/* Compost potion(2) */6474,
/* Compost potion(1) */6476,
/* Combat potion(4) */9739,
/* Combat potion(3) */9741,
/* Combat potion(2) */9743,
/* Combat potion(1) */9745,
/* Hunter potion(4) */9998,
/* Hunter potion(3) */10000,
/* Hunter potion(2) */10002,
/* Hunter potion(1) */10004,
/* Antipoison mix(2) */11433,
/* Antipoison mix(1) */11435,
/* Superattack mix(2) */11469,
/* Superattack mix(1) */11471,
/* Antifire mix(2) */11505,
/* Antifire mix(1) */11507,
/* Goblin potion (4) */11809,
/* Goblin potion (3) */11810,
/* Goblin potion (2) */11811,
/* Goblin potion (1) */11812,
/* Summoning potion(4) */12140,
/* Summoning potion(3) */12142,
/* Summoning potion(2) */12144,
/* Summoning potion(1) */12146,
/* Saradomin brews */ 6685, 6687, 6689, 6691,
/* Zamorak brews*/ 2450, 189, 191, 193,
/* Extended antifire potions*/ 14753, 14755, 14757, 14759,
/* Super ranging */ 14776, 14777, 14778, 14779,
/* Super magic */ 14780, 14781, 14782, 14783,
/* Overloads */ 14784, 14785, 14786, 14787,
/*Super Combat Pots */ 14871, 14869, 14867, 14865};
/**
* Constructs a new {@code PotionDecantingPlugin} {@code Object}.
*/
public PotionDecantingPlugin() {
super(POTIONS);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
for (int i : POTIONS) {
addHandler(i, ITEM_TYPE, this);
}
return this;
}
@Override
public boolean handle(NodeUsageEvent event) {
final Player player = event.getPlayer();
final Item item = event.getUsedItem();
final Item other = event.getBaseItem();
final String itemName = formatName(item);
final String otherName = formatName(other);
if (!itemName.equals(otherName) && (item.getId() != 229 && other.getId() != 229)) {
return false;
}
final int itemDose = getPotionDose(item);
final int otherDose = getPotionDose(other);
if (flagged(itemDose, otherDose)) {
return false;
}
if (item.getId() == item.getNoteChange() || other.getId() == item.getNoteChange()) {
return false;
}
final int[] newDoses = getDoses(itemDose, otherDose);
if (itemDose == 4 && otherDose == 0 || otherDose == 4 && itemDose == 0) {
player.getInventory().replace(getItem(item.getName().contains("Vial") ? otherName : itemName, newDoses[1]), item.getSlot());
player.getInventory().replace(getItem(item.getName().contains("Vial") ? otherName : itemName, newDoses[1]), other.getSlot());
player.getPacketDispatch().sendMessage("You decant the potion into two equal parts.");
} else {
player.getInventory().replace(getItem(item.getName().contains("Vial") ? otherName : itemName, newDoses[0]), other.getSlot());
player.getInventory().replace(getItem(item.getName().contains("Vial") ? otherName : itemName, newDoses[1]), item.getSlot());
player.getPacketDispatch().sendMessage("You have combined the liquid into " + (newDoses[0] == 0 ? newDoses[1] : newDoses[0]) + " doses.");
}
return true;
}
/**
* Method used to format a name of a potion.
* @param item the item.
* @return the name.
*/
public static String formatName(final Item item) {
return item.getName().replace("(1)", "").replace("(2)", "").replace("(3)", "").replace("(4)", "").trim();
}
/**
* Method used to get the potion does between two potions.
* @param item the item.
* @return the doses.
*/
public static int getPotionDose(final Item item) {
return item.getName().contains("(1)") ? 1 : item.getName().contains("(2)") ? 2 : item.getName().contains("(3)") ? 3 : item.getName().contains("(4)") ? 4 : 0;
}
/**
* Method used to check if a new potion ca be created based on the doses.
* @param itemDose the item dose.
* @param otherDose the other dose.
* @return <code>True</code> if flagged.
*/
public boolean flagged(final int itemDose, final int otherDose) {
return (itemDose == 4 && otherDose != 0 || itemDose != 4 && otherDose == 0 || itemDose == 4 && otherDose == 3 || itemDose == 0 && otherDose != 4) || (otherDose == 4 && itemDose != 0 || otherDose != 4 && itemDose == 0 || otherDose == 4 && itemDose == 3 || otherDose == 0 && itemDose != 4);
}
/**
* Method used to return the doses of the new items.
* @param itemDose the item dose.
* @param otherDose the other dose.
* @return the new doses.
*/
public int[] getDoses(final int itemDose, final int otherDose) {
return itemDose == 1 && otherDose == 1 ? new int[] { 2, 0 } : itemDose == 3 && otherDose == 3 ? new int[] { 4, 2 } : itemDose == 2 && otherDose == 2 ? new int[] { 4, 0 } : itemDose == 2 && otherDose == 3 ? new int[] { 4, 1 } : itemDose == 1 && otherDose == 2 ? new int[] { 0, 3 } : itemDose == 4 && otherDose == 0 ? new int[] { 2, 2 } : itemDose == 1 && otherDose == 3 ? new int[] { 0, 4 } : otherDose == 2 && itemDose == 3 ? new int[] { 1, 4 } : otherDose == 1 && itemDose == 2 ? new int[] { 0, 3 } : otherDose == 4 && itemDose == 0 ? new int[] { 2, 2 } : otherDose == 1 && itemDose == 3 ? new int[] { 0, 4 } : itemDose == 0 && otherDose == 4 ? new int[] { 2, 2 } : otherDose == 4 && itemDose == 0 ? new int[] { 2, 2 } : new int[] { 0, 0 };
}
/**
* Method used to get the new item.
* @param name the name.
* @param dose the dose of the new item.
* @return the new item.
*/
public static Item getItem(String name, int dose) {
ItemDefinition def = null;
name += "(" + dose + ")";
if (dose == 0) {
return EMPTY_VIAL;
}
for (int id : POTIONS) {
def = ItemDefinition.forId(id);
if (def.getName().equals(name)) {
return new Item(id);
}
}
return null;
}
}
+7 -1
View File
@@ -337,12 +337,18 @@ fun replaceSlot(player: Player, slot: Int, item: Item, currentItem: Item? = null
Container.BANK -> player.bank Container.BANK -> player.bank
} }
if (item.id == -1 || item.amount <= 0) {
return cont.replace(null, slot)
}
if (currentItem == null) { if (currentItem == null) {
return cont.replace(item, slot) return cont.replace(item, slot)
} }
if (cont.remove(currentItem)) if (cont.remove(currentItem, slot, true)) {
return cont.replace(item, slot) return cont.replace(item, slot)
}
PlayerMonitor.log(player, LogType.DUPE_ALERT, "Potential slot-replacement-based dupe attempt, slot: $slot, item: $item") PlayerMonitor.log(player, LogType.DUPE_ALERT, "Potential slot-replacement-based dupe attempt, slot: $slot, item: $item")
val other = when (container) { val other = when (container) {
Container.INVENTORY -> Container.EQUIPMENT Container.INVENTORY -> Container.EQUIPMENT
@@ -50,13 +50,14 @@ public abstract class Consumable {
executeConsumptionActions(player); executeConsumptionActions(player);
final int nextItemId = getNextItemId(item.getId()); final int nextItemId = getNextItemId(item.getId());
if(item.getAmount() > 1){ // STACKABLE + NON-RETURN
removeItem(player, item.getId(), Container.INVENTORY); if (ids.length == 1) {
} else removeItem(player, item, Container.INVENTORY); replaceSlot(player, item.getSlot(), new Item(item.getId(), (item.getAmount() - 1)), item, Container.INVENTORY);
} else {
if (nextItemId != -1) { // ITEM HAS RETURN
addItem(player, nextItemId, 1, Container.INVENTORY); replaceSlot(player, item.getSlot(), new Item(nextItemId, 1), item, Container.INVENTORY);
} }
final int initialLifePoints = player.getSkills().getLifepoints(); final int initialLifePoints = player.getSkills().getLifepoints();
Consumables.getConsumableById(item.getId()).getConsumable().effect.activate(player); Consumables.getConsumableById(item.getId()).getConsumable().effect.activate(player);
sendMessages(player, initialLifePoints, item, messages); sendMessages(player, initialLifePoints, item, messages);
@@ -1,7 +1,5 @@
package core.game.interaction package core.game.interaction
import core.api.forceWalk
import core.api.queueScript
import core.game.event.InteractionEvent import core.game.event.InteractionEvent
import core.game.event.UseWithEvent import core.game.event.UseWithEvent
import core.game.node.Node import core.game.node.Node
@@ -218,8 +216,8 @@ object InteractionListeners {
} else { } else {
if(flipped) player.dispatch(UseWithEvent(with.id, used.id)) if(flipped) player.dispatch(UseWithEvent(with.id, used.id))
else player.dispatch(UseWithEvent(used.id, with.id)) else player.dispatch(UseWithEvent(used.id, with.id))
if(flipped) method.invoke(player,with,used) if(flipped) return method.invoke(player,with,used)
else method.invoke(player,used,with) else return method.invoke(player,used,with)
} }
return true return true
} }
@@ -348,7 +348,7 @@ public class BankPinManager {
return; return;
} else { } else {
if (!tempPin.equals(pin)) { if (!tempPin.equals(pin)) {
playAudio(player, Sounds.PIN_CANCEL_1042); playAudio(player, Sounds.PILLORY_WRONG_2277);
player.getInterfaceManager().close(); player.getInterfaceManager().close();
player.sendMessage("The PIN you entered is incorrect."); player.sendMessage("The PIN you entered is incorrect.");
if (setTries(getTries() + 1) >= 2) { if (setTries(getTries() + 1) >= 2) {
@@ -368,6 +368,7 @@ public class BankPinManager {
return; return;
} }
unlock(); unlock();
playAudio(player, Sounds.PILLORY_SUCCESS_2274);
player.sendMessage("You have correctly entered your PIN."); player.sendMessage("You have correctly entered your PIN.");
} }
return; return;
+170
View File
@@ -1,12 +1,15 @@
import content.data.consumables.Consumables
import core.api.IfaceSettingsBuilder import core.api.IfaceSettingsBuilder
import core.api.splitLines import core.api.splitLines
import content.global.skill.slayer.Master import content.global.skill.slayer.Master
import content.global.skill.slayer.SlayerManager import content.global.skill.slayer.SlayerManager
import content.global.skill.slayer.Tasks import content.global.skill.slayer.Tasks
import core.game.node.item.Item
import org.json.simple.JSONObject import org.json.simple.JSONObject
import org.json.simple.parser.JSONParser import org.json.simple.parser.JSONParser
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.rs09.consts.Items
class APITests { class APITests {
var testPlayer: MockPlayer var testPlayer: MockPlayer
@@ -178,4 +181,171 @@ class APITests {
Assertions.assertEquals(expectedLine2, lines.getOrNull(1) ?: "") Assertions.assertEquals(expectedLine2, lines.getOrNull(1) ?: "")
Assertions.assertEquals(expectedLine3, lines.getOrNull(2) ?: "") Assertions.assertEquals(expectedLine3, lines.getOrNull(2) ?: "")
} }
@Test fun consumableStackableItemShouldNotRemoveStack() {
val stackableItem = Item(Items.PURPLE_SWEETS_10476, 999)
TestUtils.getMockPlayer("Inventory Consumable Stack Slot Tester").use { player ->
// Inventory setup
player.inventory.clear()
player.inventory.add(stackableItem, false, 0)
// Setup
val consumable = Consumables.getConsumableById(stackableItem.id)
consumable.consumable.consume(player.inventory.get(0), player)
TestUtils.advanceTicks(2, false)
// Get item in that slot,
val updatedConsumable = player.inventory.get(0)
// Maintains slot clicked + Amount is decremented
Assertions.assertEquals(0, updatedConsumable.slot)
Assertions.assertEquals(998, updatedConsumable.amount)
}
}
@Test fun consumableMultiPieceItemShouldBeRemovedFromCorrectSlot() {
val consumables: Array<Item?> = arrayOf(
Item(Items.CAKE_1891, 8),
Item(Items.TWO_THIRDS_CAKE_1893, 8),
Item(Items.SLICE_OF_CAKE_1895, 8)
)
TestUtils.getMockPlayer("Inventory Consumable Multi Piece Tester").use { player ->
// Inventory setup
player.inventory.clear()
player.inventory.add(*consumables)
val lastWholeCakeContainerIndex = 7
val lastWholeCake = player.inventory.get(lastWholeCakeContainerIndex)
val consumable = Consumables.getConsumableById(lastWholeCake.id)
consumable.consumable.consume(player.inventory.get(lastWholeCakeContainerIndex), player)
TestUtils.advanceTicks(2, false)
// Cake amounts are correct
val wholeCakeAmount = player.inventory.getAmount(Items.CAKE_1891)
val twoThirdsCakeAmount = player.inventory.getAmount(Items.TWO_THIRDS_CAKE_1893)
Assertions.assertEquals(7, wholeCakeAmount)
Assertions.assertEquals(9, twoThirdsCakeAmount)
// Cake was replaced in correct spot
val inventorySlot0 = player.inventory.get(0)
val inventorySlot7 = player.inventory.get(7)
Assertions.assertEquals(Items.CAKE_1891, inventorySlot0.id)
Assertions.assertEquals(Items.TWO_THIRDS_CAKE_1893, inventorySlot7.id)
}
}
@Test fun consumableMultiPieceItemShouldAddReturnItemToCorrectSlot() {
val PIE_DISH_NONCONSUMABLE_2313 = Items.PIE_DISH_2313
val consumables: Array<Item?> = arrayOf(
Item(Items.APPLE_PIE_2323, 8),
Item(Items.HALF_AN_APPLE_PIE_2335, 8),
Item(Items.REDBERRY_PIE_2325, 8)
)
TestUtils.getMockPlayer("Inventory Consumable Multi Piece With Return Tester").use { player ->
// Inventory setup
player.inventory.clear()
player.inventory.add(*consumables)
val lastWholePieContainerIndex = 7
val lastWholePie = player.inventory.get(lastWholePieContainerIndex)
val wholePieConsumable = Consumables.getConsumableById(lastWholePie.id)
wholePieConsumable.consumable.consume(player.inventory.get(lastWholePieContainerIndex), player)
TestUtils.advanceTicks(2, false)
// Pie amounts are correct
var wholePieAmount = player.inventory.getAmount(Items.APPLE_PIE_2323)
var halfPieAmount = player.inventory.getAmount(Items.HALF_AN_APPLE_PIE_2335)
Assertions.assertEquals(7, wholePieAmount)
Assertions.assertEquals(9, halfPieAmount)
// Pie was replaced in correct spot
val inventorySlot0 = player.inventory.get(0)
val inventorySlot7 = player.inventory.get(7)
Assertions.assertEquals(Items.APPLE_PIE_2323, inventorySlot0.id)
Assertions.assertEquals(Items.HALF_AN_APPLE_PIE_2335, inventorySlot7.id)
// Tests for pie halves + pie tins
val firstHalfPieContainerIndex = 7
val firstHalfPie = player.inventory.get(firstHalfPieContainerIndex)
val halfPieConsumable = Consumables.getConsumableById(firstHalfPie.id)
halfPieConsumable.consumable.consume(player.inventory.get(firstHalfPieContainerIndex), player)
TestUtils.advanceTicks(2, false)
// Pie amounts are correct
halfPieAmount = player.inventory.getAmount(Items.HALF_AN_APPLE_PIE_2335)
val pieDishAmount = player.inventory.getAmount(PIE_DISH_NONCONSUMABLE_2313)
Assertions.assertEquals(8, halfPieAmount)
Assertions.assertEquals(1, pieDishAmount)
val updatedSlot7 = player.inventory.get(7)
Assertions.assertEquals(PIE_DISH_NONCONSUMABLE_2313, updatedSlot7.id)
}
}
@Test fun consumableItemShouldNotHaveReturnItem() {
val consumables: Array<Item?> = arrayOf(
Item(Items.TROUT_333, 8),
Item(Items.SHARK_385, 8),
Item(Items.LOBSTER_379, 8)
)
TestUtils.getMockPlayer("Inventory Consumable No Return Item Tester").use { player ->
// Inventory setup
player.inventory.clear()
player.inventory.add(*consumables)
// Feed the player copious amounts of fish
val lastTroutContainerIndex = 7
val lastTrout = player.inventory.get(lastTroutContainerIndex)
val troutConsumable = Consumables.getConsumableById(lastTrout.id)
troutConsumable.consumable.consume(player.inventory.get(lastTroutContainerIndex), player)
TestUtils.advanceTicks(4, false)
val sharkConsumable = Consumables.getConsumableById(Items.SHARK_385)
for (n in 0..7) {
sharkConsumable.consumable.consume(player.inventory.get(n + 8), player)
TestUtils.advanceTicks(4, false)
}
val lobsterConsumable = Consumables.getConsumableById(Items.LOBSTER_379)
for (n in 16..23 step 2) {
lobsterConsumable.consumable.consume(player.inventory.get(n), player)
TestUtils.advanceTicks(4, false)
}
// Trout amounts are correct
val troutAmount = player.inventory.getAmount(Items.TROUT_333)
Assertions.assertEquals(7, troutAmount)
// Trout was removed from the correct spot
val inventorySlot0 = player.inventory.get(0)
val inventorySlot7: Item? = player.inventory.get(7)
Assertions.assertEquals(Items.TROUT_333, inventorySlot0.id)
Assertions.assertNull(inventorySlot7)
val sharkAmount = player.inventory.getAmount(Items.SHARK_385)
Assertions.assertEquals(0, sharkAmount)
for (n in 8..15) {
val inventoryItem: Item? = player.inventory.get(n)
Assertions.assertNull(inventoryItem)
}
val lobsterAmount = player.inventory.getAmount(Items.LOBSTER_379)
Assertions.assertEquals(4, lobsterAmount)
for (n in 16..23) {
if (n % 2 == 0) {
val inventoryItem: Item? = player.inventory.get(n)
Assertions.assertNull(inventoryItem)
} else {
val inventoryItem: Item = player.inventory.get(n)
Assertions.assertEquals(Items.LOBSTER_379, inventoryItem.id)
}
}
}
}
} }