Every time a player issues a specific command, a virtual inventory is being generated from the contents of a MySQL table and then shown to the player. That's working fine.
Now, when the player is moving items from this virtual inventory to his own Inventory, it should check if the items are still in the database. If not, the event should be cancelled. And when the player moves items from his inventory to the virtual inventory, they should be added to the database table.
I have no problem with the MySQL queries, but I don't know which EventHandler I should use for the events (Player Inv -> Virtual Inv, Virtual Inv -> Player Inv).
Bukkit Inventory Events
InventoryMoveItemEvent would be perfect, but it's only called when blocks (hoppers, dispensers, etc.) move items, not players.
InventoryClickEvent is no solution, because there are many different possibilities to move the items to another inventory:
Shift-clicking would call the event only once
Picking the item up and using the cursor for moving it to the other inventory would call the event twice.
Picking up an itemstack and spreading its items across the other inventory would call InventoryClickEvent and InventoryDragEvent.
and so on...
Anyone got an idea how I could solve this problem?
I have a simple solution to this, Use the InventoryCloseEvent and then check on close if the inventory contents are the same as what was in the database, if not then update the database with the new inventory and vice versa.
Related
I'm using QStandardItemModel with table view.
My table allows moving rows and for user to edit a cell.
I want to catch the cell changes from user edits.
Problem is, if a user drags a row, and/or edits cells the same signals are fired. How can I grab the cell changes and ignore the row changes?
Solution is to Subclass the QStandarItemModel. Don't waste time trying to track from the GUI by item selected, clicked, pressed. Once you subclass, you're now in control of how the model (which is your data) is going to work, we can do anything.
In particular, look at ::itemData, the ::dropMimeData and ::setData functions. Between those items you know which are from internal dnd or not. You can store to var's, emit by Qt's sig/slot mechanism to GUI, or whatever your class needs.
Another useful tool is to hook into the deleget closeEditor func:
#include <QAbstractItemDelegate>
QAbstractItemDelegate * d = tv->itemDelegate();
connect(d, &QAbstractItemDelegate::closeEditor, this, &MainWindow::endEditHint);
Hope this helps anyone who might have this arise.
I've created simple game using SFML(player can run, jump etc pressing arrows), how can i make the same for two players(second player will use WASD to move) at the same time on one computer?
You can access the keys pressed with the sf::Keyboard class. sf::Keyboard is a static class so you don't need to create a unique instance, here is a quick example:
if(sf::Keyboard::isKeypressed(sf::Keyboard::Key::W))
{
Player1.Move(1, 1);
}
if(sf::Keyboard::isKeypressed(sf::Keyboard::Key::Left))
{
Player2.Move(1, 1);
}
I'm assuming you currently are using window.PollEvent(event), the problem with that approach is that you only poll one event per loop cycle since events are added into a queue. With the above code you should be able to press multiple keys at the same time and have two actions processed.
I am attempting to create a framework where I can have multiple events all use the same room.
For example, the player triggers an event and the event builds the room with the passed in variables.
I am having trouble making the room dynamic. I want the room and the objects in the room be reusable for every event. This includes the buttons as well.
Is this possible to do?; OR
Do I have to create separate rooms for each unique event I wish to create?
The game is mostly menu based (like the game "Long Live The Queen") if that helps.
To answer simply, yes it is possible.
There are a lot of cases where I have been able to fit a lot of stuff into a single room in Game Maker. Here are a few ways to achieve this "dynamic" game creation:
Files and Scripts. You can use a single room to hold a variable number of levels by storing walls, floors, player positions, events, etc inside of a file. You can make a script that takes the filename (your "passed in" variable) and then let it simply create all of the instances inside the level for you in that room. You can also have a function that cleans up the room to prepare for another level to load. The side effect though is that your uniqueness is limited to what information can be stored in those files. You can store menu options and text dialog too if you wish.
"Unique" Objects. Game Maker is an IDE. There is nothing stopping you from making new objects in the editor for a unique case and then adding a handler in another object to create it on demand. You have to manage switching between them though.
Make a "manager" object. It can handle all of the events of something happening in-game (and in that room, for that matter). Plus also it can be used by objects to store non-global variables before being destroyed. For instance, if a character dies, it can set a variable in a manager object to "true", which would trigger a boss to appear.
In terms of manipulating object events dynamically though, unless you are running something like Game Maker 8, that is no longer possible. I say this because prior to GameMaker:Studio, object, sprites and others can be created dynamically in game via functions like "object_add()". Of course, these are obsolete and can no longer be used. Nevertheless, there are always ways around it.
I have a really big tree structure and I cant load the complete tree into Ram on client side. I am using Qt's QTreeView.
I want to load the sub elements of an item dynamically when the user expands the element.
Is there some signal that triggers when the user opens an item in the tree?
I am using the tutorial Simple Tree Model Example. When I do changes to the model the view has also to be updated. And I dont want to loose the focus to avoid user confusion!
and after some time (request to the server)...
You need to implement a subclass of QAbstractItemModel that can process needed amount of data. When an item is expanded in the view, it calls QAbstractItemModel::rowCount to determine children count and then QAbstractItemModel::flags and QAbstractItemModel::data to get children data. If requested data is not available at the moment, you should return placeholder data (i.e. 1 row containing "Loading"), and start a request. When the data is received, emit rowsAboutToBeInserted and rowsInserted signals to notify the view about new data (you should also notify it about removing "Loading" row). The view will then call rowCount, data, and flags methods again, and your model should now provide loaded data. Use QCache to keep last accessed data in memory.
I use CListBox::SetItemData to store a pointer to some data in my ownerdrawn CListBox-derived class, and I'd like the listbox itself to keep track of it and free the memory when its no longer needed.
For that I'd need to be notified each time an item is deleted (including LB_RESETCONTENT and every possible other case where an item is deleted). Is there an event or events that I can handle to achieve that?
As its owner drawn with one of the LBS_OWNERDRAW* styles you can look out for WM_DELETEITEM;
Sent to the owner of a list box or combo box when the list box or
combo box is destroyed or when items are removed by the
LB_DELETESTRING, LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT
message. The system sends a WM_DELETEITEM message for each deleted
item
No. A ListBox only generates notifications for things that the user does. The user cannot remove or add or empty a list box, that can only be done by your own code. So the philosophy here is that the control doesn't have to tell you about something you already know. You can arbitrarily generate your own message in the code that modifies the content. But of course inheriting your own class from CListBox and adding your own virtual methods would be better.
Since you're subclassing the listbox already anyway, the 'proper' design would (IMO) be to add data management functionality to the listbox, which would then know when items are removed and can delete the data as required. What I mean is, let's say your list keeps track of people, you'd add AddPerson(Person p) and RemovePerson(Person p) methods to your class. The implementation of RemovePerson would remove the respective entry from the list, and delete all data related to it. So don't use CListBox::DeleteString to remove things, use the higher-level API that you implement yourself.
It's easy - just subclass the list box and add message handlers for LB_DELETESTRING and LB_RESETCONTENT
See here for details:
http://www.codeguru.com/cpp/controls/listbox/article.php/c4759/CListBox-with-the-Horizontal-Scroll-Bar-that-Works.htm