Skip to content

Commit

Permalink
Fix inventory
Browse files Browse the repository at this point in the history
I don't know why but some inventory stuff broke
with the addition of the ticking to other segments of this

While I was at it, I sped up the specs too
  • Loading branch information
grepsedawk committed Jul 29, 2023
1 parent 9fa4669 commit a84cd64
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 37 deletions.
65 changes: 34 additions & 31 deletions spec/integration/inventory_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

expect(bot.inventory.count("bucket")).to eq 0
end
Expand All @@ -20,7 +20,7 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

bot.chat "/give #{bot.username} minecraft:bucket 16"
bot.chat "/give #{bot.username} minecraft:bucket 1"
Expand All @@ -38,10 +38,11 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

bot.chat "/give #{bot.username} minecraft:bucket 513"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot
bot.wait_tick

expect(bot.inventory.count("bucket")).to eq 513
end
Expand All @@ -56,8 +57,7 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"

sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

expect(bot.inventory.pick("diamond_pickaxe")).to eq false
expect(bot.inventory.pick("stone")).to eq false
Expand All @@ -72,9 +72,11 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:stone 42"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:grass_block 43"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

expect(bot.inventory.pick("stone")).to eq true
expect(bot.inventory.main_hand.item_id).to eq "stone"
Expand All @@ -90,9 +92,11 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:stone #{64*9}"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:grass_block 1"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

expect(bot.inventory.pick("grass_block")).to eq true
expect(bot.inventory.main_hand.item_id).to eq "grass_block"
Expand All @@ -108,7 +112,7 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot
expect { bot.inventory.pick!("diamond_pickaxe") }.to raise_error(Rosegold::Inventory::ItemNotFoundError)
end
end
Expand All @@ -120,7 +124,9 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:diamond_pickaxe{Damage:1550,Enchantments:[{id:efficiency,lvl:1}]} 1"
bot.wait_for Rosegold::Clientbound::SetSlot
expect { bot.inventory.pick!("diamond_pickaxe") }.to raise_error(Rosegold::Inventory::ItemNotFoundError)
end
end
Expand All @@ -133,17 +139,17 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/fill ~ ~ ~ ~ ~ ~ minecraft:air"
sleep 1
bot.wait_tick
bot.chat "/setblock ~ ~ ~ minecraft:chest{Items:[{Slot:7b, id: \"minecraft:diamond_sword\",Count:1b}]}"
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot
bot.wait_tick

bot.pitch = 90
bot.use_hand
sleep 1
expect(bot.inventory.withdraw_at_least(1, "diamond_sword")).to eq 1
bot.wait_for Rosegold::Clientbound::WindowItems

sleep 1
expect(bot.inventory.withdraw_at_least(1, "diamond_sword")).to eq 1

local_inventory = bot.inventory.inventory.map &.dup
local_hotbar = bot.inventory.hotbar.map &.dup
Expand All @@ -152,9 +158,9 @@ Spectator.describe Rosegold::Bot do
expect((local_inventory + local_hotbar).map(&.item_id)).to contain "diamond_sword"
expect(local_content.map(&.item_id)).not_to contain "diamond_sword"

sleep 1
bot.use_hand
sleep 1
bot.wait_for Rosegold::Clientbound::WindowItems
bot.wait_tick

expect(local_inventory.map(&.item_id)).to match_array bot.inventory.inventory.map(&.item_id)
expect(local_hotbar.map(&.item_id)).to match_array bot.inventory.hotbar.map(&.item_id)
Expand All @@ -172,16 +178,16 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/fill ~ ~ ~ ~ ~ ~ minecraft:air"
sleep 1
bot.wait_tick
bot.chat "/setblock ~ ~ ~ minecraft:chest{Items:[]}"
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:diamond_sword 1"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

bot.pitch = 90
bot.use_hand
sleep 1
bot.wait_for Rosegold::Clientbound::WindowItems

expect(bot.inventory.deposit_at_least(1, "diamond_sword")).to eq 1

Expand All @@ -192,9 +198,8 @@ Spectator.describe Rosegold::Bot do
expect((local_inventory + local_hotbar).map(&.item_id)).not_to contain "diamond_sword"
expect(local_content.map(&.item_id)).to contain "diamond_sword"

sleep 1
bot.use_hand
sleep 1
bot.wait_for Rosegold::Clientbound::WindowItems

expect(local_inventory.map(&.item_id)).to match_array bot.inventory.inventory.map(&.item_id)
expect(local_hotbar.map(&.item_id)).to match_array bot.inventory.hotbar.map(&.item_id)
Expand All @@ -213,22 +218,17 @@ Spectator.describe Rosegold::Bot do
Rosegold::Bot.new(client).try do |bot|
bot.chat "/tp #{bot.username} -10 -60 -10"
bot.chat "/fill ~ ~ ~ ~ ~ ~ minecraft:air"
sleep 1
bot.wait_tick
bot.chat "/setblock ~ ~ ~ minecraft:chest{Items:[{Slot:7b, id: \"minecraft:diamond_sword\",Count:1b}]}"
bot.chat "/clear"
sleep 1

bot.pitch = 90
bot.use_hand
sleep 1
bot.wait_for Rosegold::Clientbound::WindowItems
bot.inventory.withdraw_at_least(1, "diamond_sword")

sleep 1

bot.inventory.close

sleep 1

slots_before_reload = bot.inventory.slots

expect((bot.inventory.inventory + bot.inventory.hotbar).map(&.item_id)).to contain "diamond_sword"
Expand All @@ -251,14 +251,17 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:diamond_sword 4"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:stone 200"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

bot.look = Rosegold::Look.new 0, 0
expect(bot.inventory.throw_all_of "diamond_sword").to eq 4
expect(bot.inventory.throw_all_of "stone").to eq 200

sleep 1
bot.wait_tick

expect(bot.inventory.inventory.map(&.item_id)).not_to contain "diamond_sword"
expect(bot.inventory.hotbar.map(&.item_id)).not_to contain "diamond_sword"
Expand Down
17 changes: 13 additions & 4 deletions src/rosegold/bot.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@ class Rosegold::Bot < Rosegold::EventEmitter

def initialize(@client)
@inventory = Inventory.new client
client.on(Rosegold::Clientbound::ChatMessage) do |packet|

subscribe Rosegold::Clientbound::ChatMessage
subscribe Event::Tick
subscribe Rosegold::Clientbound::WindowItems
subscribe Rosegold::Clientbound::SetSlot
end

def subscribe(event_class : Class)
client.on event_class do |packet|
emit_event packet
end
end
Expand Down Expand Up @@ -55,13 +63,14 @@ class Rosegold::Bot < Rosegold::EventEmitter
client.queue_packet Serverbound::ChatMessage.new message
end

# Is adjusted to server TPS.
def wait_ticks(ticks : Int32)
sleep ticks / 20 # TODO adjust to server TPS, changing over time
ticks.times do
wait_tick
end
end

def wait_tick
wait_ticks 1
wait_for Event::Tick, timeout: 1.second
end

# Direction the player is looking.
Expand Down
4 changes: 3 additions & 1 deletion src/rosegold/control/interactions.cr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Rosegold::Interactions
end

@using_hand = nil
@queue_using_hand = nil
@using_hand_delay = 0_i8
@digging_block : ReachedBlock?
@dig_hand_swing_countdown = 0_i8
Expand All @@ -27,6 +28,7 @@ class Rosegold::Interactions
# Activates the "use" button.
def start_using_hand(hand : Hand = :main_hand) # TODO: Auto select hand each tick
@using_hand = hand
@queue_using_hand = hand
end

# Deactivates the "use" button.
Expand Down Expand Up @@ -121,7 +123,7 @@ class Rosegold::Interactions
@using_hand_delay -= 1 if @using_hand_delay > 0
return if @using_hand_delay > 0

if using_hand = @using_hand
if using_hand = @using_hand || @queue_using_hand
@using_hand_delay = 4
case reached = reach_block_or_entity
when Entity
Expand Down
7 changes: 6 additions & 1 deletion src/rosegold/control/inventory.cr
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,15 @@ class Rosegold::Inventory
deposit_at_least(count, spec)
end

# Finds an empty slot in the source
# In order to match vanilla:
# When source is the container, prioritize first empty #container slot
# When source is the player inventory, prioritize rightmost empty #hotbar slot
# then rightmost empty #inventory slot
private def find_empty_slot(source)
empty_slot = nil

source.each do |slot|
source.sort { |a, b| b.slot_number <=> a.slot_number }.each do |slot|
if slot.empty?
empty_slot = slot
break
Expand Down

0 comments on commit a84cd64

Please sign in to comment.