Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Implement Move Multiple Items #4259

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

catapultam-habeo
Copy link
Contributor

@catapultam-habeo catapultam-habeo commented Apr 15, 2024

Description

This implements ctrl-click movement of bag contents for ROF+ clients.

Type of change

  • New feature (non-breaking change which adds functionality)

Testing

There are three behaviors that are introduced here;

  • CTRL + left click -> drops an item into a bag without opening it.
  • CTRL + left click -> adds the contents of a bag (on cursor) into another bag without opening it
  • CTRL + right click -> swaps the contents of two bags if a bag is on your cursor and you ctrl-right click on another bag.

I don't know how to attach images to demonstrate this.

I would furthermore like some assistance testing this.

Clients tested:

  • ROF2

Checklist

  • I have tested my changes
  • I have performed a self-review of my code. Ensuring variables, functions and methods are named in a human-readable way, comments are added only where naming of variables, functions and methods can't give enough context.
  • I have made corresponding changes to the documentation (if applicable, if not delete this line)
  • I own the changes of my code and take responsibility for the potential issues that occur

@catapultam-habeo
Copy link
Contributor Author

Do not merge this. Found some bugs.

@Akkadius Akkadius marked this pull request as draft April 16, 2024 04:13
@catapultam-habeo
Copy link
Contributor Author

catapultam-habeo commented Apr 17, 2024

This isn't working correctly because the cursor bag re-orders itself on SwapItem, causing the transfers subsequent to the first one to fail. I'm not certain how to fix that right now.

No, it is because the swap contains redundant two-way operations.

@catapultam-habeo
Copy link
Contributor Author

catapultam-habeo commented Apr 18, 2024

This works according to my testing. It implements all 3 ctrl-click modes exactly replicating client behavior.

  1. ctrl + left click single item into bag -> places item into bag without opening it. This will combine stacks as needed, including filling multiple stacks as needed.
  2. ctrl + left click bag into bag -> fills target bag with contents of source bag. client checks if there is enough room, etc. This will combine stacks as possible\needed.
  3. ctrl + right click bag into bag -> swaps contents of bags. This puts things into lowest ordinal bag slots, but does not combine stacks.

left and right click logic needs to be bifurcated because left click handles things a lot like proper slot swaps or autoinv in terms of stack combining, etc, so we want to leverage the existing logic of SwapItem. right click just bluntly exchanges contents, but we need to respect the new targets instead of just explicitly exchanging the bag contents slot for slot.

@catapultam-habeo catapultam-habeo marked this pull request as ready for review April 18, 2024 07:17
@catapultam-habeo catapultam-habeo marked this pull request as draft April 18, 2024 07:25
zone/client_packet.cpp Outdated Show resolved Hide resolved
zone/client_packet.cpp Outdated Show resolved Hide resolved
zone/client_packet.cpp Outdated Show resolved Hide resolved
zone/client_packet.cpp Outdated Show resolved Hide resolved
zone/client_packet.cpp Outdated Show resolved Hide resolved
zone/client_packet.cpp Outdated Show resolved Hide resolved
zone/client_packet.cpp Outdated Show resolved Hide resolved
@Kinglykrab Kinglykrab changed the title Implement Move Multiple Items [Feature] Implement Move Multiple Items Apr 21, 2024
@catapultam-habeo catapultam-habeo marked this pull request as ready for review April 23, 2024 06:05
@catapultam-habeo
Copy link
Contributor Author

This has been running on my servers for a while now without issues (~40 users total). I haven't been able to break it personally. I'm reasonably confident in this implementation.

@MazeEQ
Copy link

MazeEQ commented May 5, 2024

This has been running on my servers for a while now without issues (~40 users total). I haven't been able to break it personally. I'm reasonably confident in this implementation.

Can confirm this has been working as expected.

Have not ran into any issues while testing on Cata's servers.

Comment on lines +75 to +80
enum MoveMultiType: int16 {
inventoryPersonal = 0,
inventoryBank = 1,
inventorySharedBank = 2
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are unused?

Comment on lines +1625 to +1630
/*000*/ int16 Type; // Worn and Normal inventory = 0, Bank = 1, Shared Bank = 2, Delete Item = -1
/*002*/ int16 Unknown02;
/*004*/ int16 Slot;
/*006*/ int16 SubIndex;
/*008*/ int16 AugIndex; // Guessing - Seen 0xffff
/*010*/ int16 Unknown01; // Normally 0 - Seen 13262 when deleting an item, but didn't match item ID
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

snake_case please.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exists already in rof_structs.h, I just copied it. Would it be more correct to adjust this in rof_structs.h and reference it from there?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, whatever works.

Kick("Unimplemented move multiple items"); // TODO: lets not desync though
// This packet is only sent from the client if we ctrl click items in inventory
if (m_ClientVersionBit & EQ::versions::maskRoF2AndLater) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary newline.

bool error = false;
SwapItemResync(mi);
InterrogateInventory(this, false, true, false, error, false);
if (error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (error) {
}

from_slot = m_inv.CalcSlotId(multi_move->moves[i].from_slot.Slot + EQ::invslot::SHARED_BANK_BEGIN, multi_move->moves[i].from_slot.SubIndex);
}

auto to_slot = m_inv.CalcSlotId(multi_move->moves[i].to_slot.Slot, multi_move->moves[i].to_slot.SubIndex);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use actual type here since it's a simple type.


for (int i = 0; i < multi_move->count; i++) {
// These are always bags, so we don't need to worry about raw items in slotCursor
auto from_slot = m_inv.CalcSlotId(multi_move->moves[i].from_slot.Slot, multi_move->moves[i].from_slot.SubIndex);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use actual type here since it's a simple type.

Comment on lines +10900 to +10901
const auto from_parent = multi_move->moves[0].from_slot.Slot;
const auto to_parent = multi_move->moves[0].to_slot.Slot;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use actual types here since they're simple types.

return; // Not enough data to be a valid packet
}

const MultiMoveItem_Struct* multi_move = reinterpret_cast<const MultiMoveItem_Struct*>(app->pBuffer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use const auto if you'd prefer since it's a complex type.

// This is a left click which is purely additive. This should always be cursor object or cursor bag contents into general\bank\whatever bag
if (left_click) {
for (int i = 0; i < multi_move->count; i++) {
MoveItem_Struct* mi = new MoveItem_Struct();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use auto if you'd prefer since it's a complex type.

}
}

for (const MoveInfo& move : items) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use const auto& if you'd prefer since it's a complex type.

PutItemInInventory(move.to_slot, *move.item); // This saves inventory too
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary newline.

Comment on lines +10972 to +10974
MoveInfo move;
move.item = m_inv.PopItem(from_slot); // Don't delete the instance here
move.to_slot = to_slot;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do this.

MoveInfo move{
    .item = m_inv.PopItem(from_slot), // Don't delete the instance here
    .to_slot = to_slot
};

if (move.item) {

@Akkadius
Copy link
Member

@catapultam-habeo can you attach some demo videos?

Do you have any concerns of item dupes or item loss?

@catapultam-habeo
Copy link
Contributor Author

catapultam-habeo commented May 25, 2024

@catapultam-habeo can you attach some demo videos?

Do you have any concerns of item dupes or item loss?

Sorry for the delay in having KK's comments addressesed.

I'll get some demo videos when I make those adjustments and have a new build.

As for concerns about item dupes or loss; I don't see how either could happen unless there is a flaw with the existing inventory manipulation methods. That said, I think that there is a flaw in existing inventory manipulation somewhere, but I haven't been able to locate it. Unrelated to this PR (I have observed this behavior prior to working on this, on a totally stock release server), items can dup into ostensibly unaddressable inventory Slot IDs. There doesn't seem to be any real consequence other than extraneous inventory table rows, as these items do appear to be inaccessible. I also haven't been able to duplicate this error on demand, simply noting impossible rows in the table while parsing it for other needs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants