Fixed regression causing GE to eat noted items

This commit is contained in:
Ceikry 2023-08-12 00:21:25 +00:00 committed by Ryan
parent 418f239261
commit 2e70a9714a
2 changed files with 115 additions and 12 deletions

View file

@ -19,6 +19,7 @@ import core.game.ge.PriceIndex
import core.game.interaction.InterfaceListener
import core.tools.Log
import core.tools.SystemLogger
import kotlin.math.min
/**
* Handles the grand exchange interface (Stock Market)
@ -216,19 +217,28 @@ class StockMarket : InterfaceListener {
offer.visualize(player)
}
fun confirmOffer(player: Player, offer: GrandExchangeOffer, index: Int)
enum class OfferConfirmResult {
Success,
ZeroCoins,
TooManyCoins,
NotEnoughItemsOrCoins,
ItemRemovalFailure,
OfferPlacementError
}
fun confirmOffer(player: Player, offer: GrandExchangeOffer, index: Int) : OfferConfirmResult
{
if(offer.offeredValue < 1)
{
playAudio(player, Audio(4039, 1, 1))
sendMessage(player, "You can't make an offer for 0 coins.")
return
return OfferConfirmResult.ZeroCoins
}
if(offer.amount > Int.MAX_VALUE / offer.offeredValue)
{
playAudio(player, Audio(4039, 1, 1))
sendMessage(player, "You can't ${if(offer.sell) "sell" else "buy"} this much!")
return
return OfferConfirmResult.TooManyCoins
}
offer.index = index
if(offer.sell)
@ -239,21 +249,25 @@ class StockMarket : InterfaceListener {
playAudio(player, Audio(4039, 1, 1))
sendMessage(player, "You do not have enough of this item in your inventory to cover the")
sendMessage(player, "offer.")
return
return OfferConfirmResult.NotEnoughItemsOrCoins
}
var item: Item
val amountUnnoted = amountInInventory(player, offer.itemID)
val amountUnnoted = min(amountInInventory(player, offer.itemID), offer.amount)
val amountLeft = offer.amount - amountUnnoted
val removedUnnoted = removeItem(player, Item(offer.itemID, amountUnnoted).also { item = it })
val removedUnnoted = if (amountUnnoted > 0) removeItem(player, Item(offer.itemID, amountUnnoted)) else true
val removeNoted = if (amountLeft > 0) removeItem(player, Item(itemDefinition(offer.itemID).noteId, amountLeft)) else true
if (!removedUnnoted || !removeNoted) return
if (!removedUnnoted || !removeNoted) return OfferConfirmResult.ItemRemovalFailure
if(GrandExchange.dispatch(player, offer))
{
player.removeAttribute("ge-temp")
}
else
{
addItem(player, item.id, item.amount)
if (amountUnnoted > 0)
addItem(player, offer.itemID, offer.amount - amountLeft)
if (amountLeft > 0)
addItem(player, itemDefinition(offer.itemID).noteId, amountLeft)
sendMessage(player, "Unable to place GE offer. Please try again.")
return OfferConfirmResult.OfferPlacementError
}
}
else
@ -263,7 +277,7 @@ class StockMarket : InterfaceListener {
{
playAudio(player, Audio(4039, 1, 1))
sendMessage(player, "You do not have enough coins to cover the offer.")
return
return OfferConfirmResult.NotEnoughItemsOrCoins
}
if(GrandExchange.dispatch(player, offer) && removeItem(player, Item(995, total)))
{
@ -273,6 +287,7 @@ class StockMarket : InterfaceListener {
playAudio(player, Audio(4043, 1, 1))
offer.visualize(player)
toMainInterface(player)
return OfferConfirmResult.Success
}
fun getInventoryAmount(player: Player, itemId: Int): Int {

View file

@ -1,3 +1,4 @@
import content.global.handlers.iface.ge.StockMarket
import core.game.ge.OfferState
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
@ -11,6 +12,8 @@ import core.game.ge.GEDB
import core.game.ge.GrandExchange
import core.game.ge.GrandExchangeOffer
import core.game.ge.PriceIndex
import core.game.node.item.Item
import org.rs09.consts.Items
import java.io.File
@TestInstance(TestInstance.Lifecycle.PER_CLASS) class ExchangeTests {
@ -21,10 +24,10 @@ import java.io.File
GEDB.init(TEST_DB_PATH)
}
fun generateOffer(itemId: Int, amount: Int, price: Int, sale: Boolean, username: String = "test ${System.currentTimeMillis()}") : GrandExchangeOffer {
fun generateOffer(itemId: Int, amount: Int, price: Int, sale: Boolean, username: String = "test ${System.currentTimeMillis()}", offerState: OfferState = OfferState.REGISTERED) : GrandExchangeOffer {
val offer = GrandExchangeOffer()
val uid = username.hashCode() // normally this would be the account's uid but in the test we don't have an account
offer.offerState = OfferState.REGISTERED
offer.offerState = offerState
offer.itemID = itemId
offer.offeredValue = price
offer.amount = amount
@ -37,6 +40,22 @@ import java.io.File
return offer
}
fun generateUnsentOffer (itemId: Int, amount: Int, price: Int, sale: Boolean, username: String, offerState: OfferState = OfferState.PENDING) : GrandExchangeOffer {
val offer = GrandExchangeOffer()
val uid = username.hashCode() // normally this would be the account's uid but in the test we don't have an account
offer.offerState = offerState
offer.itemID = itemId
offer.offeredValue = price
offer.amount = amount
offer.timeStamp = System.currentTimeMillis()
offer.index = 0
offer.isBot = false
offer.playerUID = uid
offer.sell = sale
offer.uid = 0L
return offer
}
@AfterAll @JvmStatic fun cleanup() {
File(TEST_DB_PATH).delete()
}
@ -115,4 +134,73 @@ import java.io.File
Assertions.assertEquals(false, b.isCancelled)
}
}
@Test fun offerWithCombinedNotedAndUnnotedAmountShouldSuceed() {
TestUtils.getMockPlayer("combinedNotendAndUnnotedExcTest").use { p ->
val offer = generateUnsentOffer(4151, 1000, 1500, true, p.name, OfferState.PENDING)
val mkt = StockMarket()
p.inventory.add(Item(Items.ABYSSAL_WHIP_4151, 10))
p.inventory.add(Item(Items.ABYSSAL_WHIP_4152, 990))
Assertions.assertEquals(StockMarket.OfferConfirmResult.Success, mkt.confirmOffer(p, offer, 0))
Assertions.assertEquals(0, p.inventory.getAmount(4151))
Assertions.assertEquals(0, p.inventory.getAmount(4152))
}
}
@Test fun offerWithOnlyNotedAmountShouldSucceed() {
TestUtils.getMockPlayer("onlyNotedOfferSucceed").use { p ->
val offer = generateUnsentOffer(4151, 1000, 1500, true, p.name, OfferState.PENDING)
val mkt = StockMarket()
p.inventory.add(Item(Items.ABYSSAL_WHIP_4152, 1000))
Assertions.assertEquals(StockMarket.OfferConfirmResult.Success, mkt.confirmOffer(p, offer, 0))
Assertions.assertEquals(0, p.inventory.getAmount(4151))
Assertions.assertEquals(0, p.inventory.getAmount(4152))
}
}
@Test fun offerWithMoreUnnotedItemsThanOfferAmountShouldSucceed() {
TestUtils.getMockPlayer("onlyUnnotedOfferWithExtraItemsSucceed").use { p ->
val offer = generateUnsentOffer(4151, 10, 1500, true, p.name, OfferState.PENDING)
val mkt = StockMarket()
p.inventory.add(Item(Items.ABYSSAL_WHIP_4151, 20))
Assertions.assertEquals(StockMarket.OfferConfirmResult.Success, mkt.confirmOffer(p, offer, 0))
Assertions.assertEquals(10, p.inventory.getAmount(4151))
Assertions.assertEquals(0, p.inventory.getAmount(4152))
}
}
@Test fun offerWithOnlyUnnotedAmountShouldSucceed() {
TestUtils.getMockPlayer("onlyUnnotedOfferSucceed").use { p ->
val offer = generateUnsentOffer(4151, 10, 1500, true, p.name, OfferState.PENDING)
val mkt = StockMarket()
p.inventory.add(Item(Items.ABYSSAL_WHIP_4151, 10))
Assertions.assertEquals(StockMarket.OfferConfirmResult.Success, mkt.confirmOffer(p, offer, 0))
Assertions.assertEquals(0, p.inventory.getAmount(4151))
Assertions.assertEquals(0, p.inventory.getAmount(4152))
}
}
@Test fun offerWithNotEnoughNotedItemsShouldFail() {
TestUtils.getMockPlayer("combinedNotedAndUnnotedFailure").use { p ->
val offer = generateUnsentOffer(4151, 1000, 1500, true, p.name, OfferState.PENDING)
val mkt = StockMarket()
p.inventory.add(Item(Items.ABYSSAL_WHIP_4151, 10))
p.inventory.add(Item(Items.ABYSSAL_WHIP_4152, 15))
Assertions.assertEquals(StockMarket.OfferConfirmResult.NotEnoughItemsOrCoins, mkt.confirmOffer(p, offer, 0))
Assertions.assertEquals(10, p.inventory.getAmount(4151))
Assertions.assertEquals(15, p.inventory.getAmount(4152))
}
}
@Test fun offerWithNotEnoughUnnotedItemsShouldFail() {
TestUtils.getMockPlayer("combinedNotedAndUnnotedFailure2").use { p ->
val offer = generateUnsentOffer(4151, 1000, 1500, true, p.name, OfferState.PENDING)
val mkt = StockMarket()
p.inventory.add(Item(Items.ABYSSAL_WHIP_4151, 10))
p.inventory.add(Item(Items.ABYSSAL_WHIP_4152, 900))
Assertions.assertEquals(StockMarket.OfferConfirmResult.NotEnoughItemsOrCoins, mkt.confirmOffer(p, offer, 0))
Assertions.assertEquals(10, p.inventory.getAmount(4151))
Assertions.assertEquals(900, p.inventory.getAmount(4152))
}
}
}