newttster Posted September 2, 2012 Share Posted September 2, 2012 I am trying to write a mod that will take 1 of each inventory item that is over a quantity of 5. That part I have gotten to work so that it displays to the screen. It lists every item that is over a quantity of 5. No problem. I can get it to take 1 from just 1 item. No problem. The problem comes in when trying to go through the list of items that have been displayed. I'm pretty sure that it obviously has to be a loop of some sort with a counter ... but I can't figure out what kind of loop and how to get it to stop after it has gone through theitem list once. I have been reading up on loops and from what I have come to understand ... (granted that isn't much) it has to also include an array. Once I hit arrays ... I am lost. gumballs = 6 candy sticks = 7 chocolate bar = 9 ... then once the loop is finished you are left with gumballs = 5 candy sticks = 6 chocolate bar = 8. Anyone have any idea how I can accomplish this? Or if it can be done. Quote Link to comment Share on other sites More sharing options...
HauntedDawg Posted September 2, 2012 Share Posted September 2, 2012 Post up the code you currently are working on. Quote Link to comment Share on other sites More sharing options...
newttster Posted September 2, 2012 Author Share Posted September 2, 2012 First part of the code that displays the table. echo"<h3><font color=steelblue><u>Users Inventory Items Are Listed Below</u></h3>"; $inv=$db->query("SELECT iv.inv_id,iv.inv_qty,iv.inv_applied,iv.inv_itemid,iv.inv_userid, i.itmid,i.itmname,i.itmtype, i.effect1_on,i.effect2_on,i.effect3_on,i.itmuseable,i.itmsendable, i.itmtransferable, i.itmapplied,i.weapon,i.head,i.neck,i.arms,i.torso,i.legs,i.feet,i.special1,i.special2,i.special3, i.itmsellprice,it.itmtypename FROM inventory iv LEFT JOIN items i ON iv.inv_itemid=i.itmid LEFT JOIN itemtypes it ON i.itmtype=it.itmtypeid WHERE iv.inv_userid={$_GET['oneall']} AND i.itmtype!=1 AND i.itmtype!=45 AND iv.inv_qty >5 ORDER BY i.itmtype ASC, i.itmsellprice ASC, i.itmname ASC"); if ($db->num_rows($inv) == 0) { echo "<b>This user has no items!</b>"; } else { echo "Click on the Take button at the bottom of the table to take one of each item.<br /> <table border='1' bordercolor='red' cellspacing='0'> <tr style='background: gray'> <td class='tableleft'><font color=black>Item</td> <td class='tableleft' ><font color=black>Quantity</td> </tr>"; } while($i=$db->fetch_row($inv)) { echo "<tr><td>{$i['itmname']}</td> <td>".number_format($i['inv_qty'])."</td> </tr>"; } echo "</table><br />"; echo" <form action='casting5a.php?id={$i['inv_userid']}' method='post'> <input type='hidden' name='taking'/> <input type='submit' value='Take one of Each' /> </form>"; Then the code that has me stuck is the taking part $inv=$db->query("SELECT iv.inv_id,iv.inv_qty,iv.inv_applied,iv.inv_itemid,iv.inv_userid,i.itmid,i.itmname,i.itmtype, i.effect1_on,i.effect2_on,i.effect3_on,i.itmuseable,i.itmsendable, i.itmtransferable, i.itmapplied,i.weapon,i.head,i.neck,i.arms,i.torso,i.legs,i.feet,i.special1,i.special2,i.special3, i.itmsellprice,it.itmtypename FROM inventory iv LEFT JOIN items i ON iv.inv_itemid=i.itmid LEFT JOIN itemtypes it ON i.itmtype=it.itmtypeid WHERE iv.inv_qty>5 and iv.inv_userid={$_GET['id']}"); $i=$db->fetch_row($inv); From there ... I have no idea how to proceed. Quote Link to comment Share on other sites More sharing options...
HauntedDawg Posted September 2, 2012 Share Posted September 2, 2012 Well, instead of selecting them and looping through. Why not.. UPDATE `inventory` SET `inv_qty` = (`inv_qty` - 1) WHERE `inv_qty` > 6 AND `inv_userd` = '.intval($_GET['id']) ?? Quote Link to comment Share on other sites More sharing options...
newttster Posted September 2, 2012 Author Share Posted September 2, 2012 (edited) *facepalms* That works wonderfully. Thanks HD. Any idea how I would get it to add the items that were removed to another players inventory. I've tried item_add ... doesn't work. Tried ... $db->query("UPDATE `inventory` SET `inv_qty` = (`inv_qty` + 1) WHERE `inv_itemid` = `{$i['inv_itemid']}` AND `inv_userid` = '{$ir['userid']}'"); and it doesn't work either. Forgot to mention that is saying that the {$i['inv_itemid']} is what is throwing an error. Edited September 2, 2012 by newttster Quote Link to comment Share on other sites More sharing options...
Octarine Posted September 2, 2012 Share Posted September 2, 2012 Something like this perhaps ? Quote Link to comment Share on other sites More sharing options...
newttster Posted September 2, 2012 Author Share Posted September 2, 2012 Thank you for your input, Octarine. I will be testing that shortly. Can you explain this though. There is some sense in pre-locking the inventory table, but given the ""engine"" the code is running on, that appears overkill as so many other things are liable to fail. Specifically ... locking the table and what things are liable to fail. I know very few people care for McCodes as an engine ... as this is what I am currently learning on I would like to know all that I can in order to improve what I have. Quote Link to comment Share on other sites More sharing options...
HauntedDawg Posted September 2, 2012 Share Posted September 2, 2012 (edited) @ Octarine, instead of bashing on mccodes each time you help someone, why not rather step back from helping to step back from bashing all together? Or perhaps keep your remarks to yourself? also, why loop the rows? function transferToUser($fromUser, $toUser) { # Get the list of items in a concat string to transfer; $itemsList = mysql_query('SELECT GROUP_CONCAT(`inv_itemid`) as `items` FROM `inventory` WHERE `inv_qty` > 5 AND `inv_userid` = '.$fromUser); $itemsList = mysql_fetch_assoc($itemsList); $items = explode(',', $items['items']); foreach($items as $item) { # Transfer Begins mysql_query('UPDATE `inventory` SET `inv_qty` = (`inv_qty` - 1) WHERE `inv_userid` = '.$fromUser.' AND `inv_itemid` = '.$item); mysql_query('UPDATE `inventory` SET `inv_qty` = (`inv_qty` + 1) WHERE `inv_userid` = '.$toUser.' AND `inv_itemid` = '.$item); if(!mysql_affected_rows()) { # MCCodes does not have indexing, or we could of INSERT ... DUPLICATE KEY UPDATE # ... thus making us need to have the affected rows check to see if the last query has any affected rows # ... if it does not, it means that the user does not have one of those items, and we need to insert it. mysql_query('INSERT INTO `inventory` (`inv_qty`,`inv_userid`,`inv_itemid`)VALUES(1, '.$toUser.', '.$item.')'); } } } Seems overkill to loop the rows... Edited September 2, 2012 by HauntedDawg Quote Link to comment Share on other sites More sharing options...
Octarine Posted September 2, 2012 Share Posted September 2, 2012 Simply put, the inventory table structure is poorly designed; the primary key should ideally be inv_userid + inv_itemid; which means you can drop the inv_id field all together. Now; having simplified the table structure to user, item and quantity; things become a lost easier. As it stands, there is a possibility of the user donating the items having their inventory altered by either themselves or somebody else during the function I posted up, which is why the check is made upon delete. ie: function call is made SELECT statement issued to read the donating user's inventory $rows fully populated donating user buys 1000 of item X function loops over $rows making the adjustments as required ... end of function You could question the validity of this, after all the function call has been issued, but this is a simple example; there are far more complex examples - one in particular being the item/crystal market which is (or at least was) abusable with careful timing. Careful design of the table structure itself would prevent this problem from ever arising and certainly do away with the utter madness that is SELECT+UPDATE+INSERT(sometimes) in the current item_add() function. With your problem, I think a single query would be sufficient with the simplified inventory table structure - and thus no chance of misplacing items or having multiple rows containing the same item in your inventory. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.