Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Basil Beard

Pages: 1 ... 14 15 [16]
226
Items / Item Transfers.
« on: April 26, 2006, 09:13:38 am »
I was board again. And so using my newfound knowledge of what $context does.... 3 easy steps to get item transfers working on your forum  :)

1) Open shop.php and insert:

Code: [Select]
elseif($_GET['do'] == "senditems") {
        $context['linktree'][] = array(
            'url' => "$scripturl?action=shop;do=senditems",
            'name' => $txt['shop_send_money'],
        );
       
        $result = db_query("SELECT it.name, inv.id AS ivid, inv.trading
                            FROM {$db_prefix}shop_inventory AS inv, {$db_prefix}shop_items AS it
                            WHERE inv.ownerid = {$ID_MEMBER} AND inv.itemid = it.id AND inv.trading = 0
                            GROUP BY it.id
                            ORDER BY it.name ASC ", __FILE__, __LINE__);
        while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
        $context['shop_trade_items'] .= "
        <option value ={$row['ivid']}>{$row['name']}</option>";
        }
        $context['sub_template'] = "sendItems";
loadTemplate('Shop');

    } elseif($_GET['do'] == "senditems2") {
        $context['linktree'][] = array(
            'url' => "$scripturl?action=shop;do=senditems2",
            'name' => $txt['shop_send_money'],
        );
$result = db_query("SELECT ID_MEMBER
FROM {$db_prefix}members
WHERE memberName = '{$_POST['membername']}'", __FILE__, __LINE__);
        $row = mysql_fetch_array($result, MYSQL_ASSOC);
        $newowner = $row['ID_MEMBER'];
$result = db_query("SELECT ownerid, itemid
FROM {$db_prefix}shop_inventory
WHERE id = '{$_POST['giftid']}'", __FILE__, __LINE__);
        $row = mysql_fetch_array($result, MYSQL_ASSOC);
        $itemid = $row['itemid'];
        if ($row['ownerid'] !== $ID_MEMBER) {
       die($txt['shop_use_others_item']);
       }
       else {
        $result = db_query("UPDATE {$db_prefix}shop_inventory
SET ownerid = $newowner
WHERE id = '{$_POST['giftid']}'", __FILE__, __LINE__);
$context['shop_buy_message'] = "Item succesfully transfered!";
$result = db_query("SELECT name
FROM {$db_prefix}shop_items
WHERE id = {$itemid}", __FILE__, __LINE__);
      $row = mysql_fetch_array($result, MYSQL_ASSOC);
      $name = $row['name'];
$result = db_query("SELECT memberName
FROM {$db_prefix}members
WHERE ID_MEMBER = {$ID_MEMBER}", __FILE__, __LINE__);
        $row = mysql_fetch_array($result, MYSQL_ASSOC);
        $target = $row['memberName'];
$pmfrom = array(
'id' => '1',
'name' => 'Clucky',
'username' => 'Clucky'
);
$pmto = array(
'to' => array($newowner),
'bcc' => array()
);
sendpm($pmto, 'You have been sent an item!', "{$target} has sent you an {$name}. Isn't that nice of them? [i]You do not need to reply to this automated message[/i]", 0, $pmfrom);
}
        $context['sub_template'] = "message";
loadTemplate('Shop');

    }

this should go right before the
Code: [Select]
     else {
        die("What do I do with {$_GET['do']}? HUH????");
    }
}


function formatMoney($money) {
    global $modSettings;

    $money = (int) $money;
    return $modSettings['shopCurrencyPrefix'].$money.$modSettings['shopCurrencySuffix'];
}
?>
Which ends the file.

Next, open shop.tempelate.php and insert
Code: [Select]
function template_sendItems() {
global $txt, $context, $modSettings, $scripturl, $settings;

shop_header();
echo <<<EOT
<table width="100%" cellpadding="5" cellspacing="0" border="0" class="tborder" style="margin-top: 1.5ex;">
<tr valign='top' class='windowbg2'>
<td style='padding-bottom: 2ex;' width='20%'>
<center><b>{$txt['shop_send_items']}</b></center><br />{$txt['shop_send_items_message']}
<form action="$scripturl?action=shop;do=senditems2" method="POST">
{$txt['shop_member_name']}: <input type="text" name="membername" size="25">
<a href="{$scripturl}?action=findmember;input=membername;quote=1;sesc={$context['session_id']}" onclick="return reqWin(this.href, 350, 400);"><img src="{$settings['images_url']}/icons/assist.gif" border="0" alt="{$txt['find_members']}" /> Find Members</a><br />
{$txt['shop_item_to_send']}:
<select name="giftid">
{$context['shop_trade_items']}
</select>
{$txt['shop_send_message_to_give']}: <textarea name="message" cols="50" rows="5"></textarea><br />
<input type="submit" value="{$txt['shop_send_items']}">
</form>
</td>
</tr>
</table>
EOT;
shop_footer();
}
Right before the ?> that ends the file.

You also need to find this line of code:
Code: [Select]
<a href='$scripturl?action=shop;do=invother'>{$txt['shop_invother']}</a><br />
and insert
Code: [Select]
<a href='$scripturl?action=shop;do=senditems'>{$txt['shop_senditems']}</a><br />

After it.

Lastly, open shop.english.php and insert these four lines pretty much anywhere in the file.
Code: [Select]
$txt['shop_send_items'] = "Send a item to someone";
$txt['shop_send_items_message'] = "You can use this to give an item to someone. This can also be used for item - item trades. If you wish to sell an item, please use the trade center. You cannot sell an item that you are currently trading";
$txt['shop_item_to_send'] = "Item to send:";
$txt['shop_senditems'] = "Items transfer center";

Save/upload everything, and you should be able to transfer items from account to account without using the trade center.

 

227
General SMFShop Discussion / Re: Question about shop.php
« on: April 26, 2006, 01:39:13 am »
AH! I see now.  :D. The shop.template.php file does the general formatting and the $context variable tells it what to stick in the unkown spots. Very nice.  O0.

228
I always make little coding errors like that. Not really sure why. I posted this with out having time to test it, because I was pressed for time.

229
General SMFShop Discussion / Question about shop.php
« on: April 25, 2006, 12:48:52 am »
All through out shop.php there are these $context lines.

Code: [Select]
$context['shop_bank_link']

I have determined that the $context lines provoide certain amounts of text formatting and all that, but I can't figgure out where they are defined? Is in one of the subs files in the sources folder? Or is it someplace else?

Thanks  :D

230
General SMFShop Discussion / Re: Item Ideas
« on: April 24, 2006, 05:12:59 am »
Its on my profile. Anyone whos really interested in it can look there. =)

231
General SMFShop Discussion / Re: Item Ideas
« on: April 24, 2006, 04:41:17 am »
Stealing items would be codeable. I'm not a big fan on it, but I could probably do it if I had the time. However, right now I am rather busy and thus don't want to spend a whole lot of time coding items that arn't for my site. Maybe after the first week of May(when AP exams and my college course are done) I could do so item coding for other people as well =).

232
Part 2:

Last time we looked at how to code a simple item. But often people get board of these basic items, and what to expand their horizons. The best way to code fun interesting items is to add more database fields. To do this, you need to either use a program such as phpMyAdmin, or simply run an install query. When you do this, you need to be very sure not to mess up any of the existing database or serious problems could occur. Most likely you will only be modifying the smf_members and smf_shop_inventory tables. Smf_members controls all the stats for a given member. If you wanted to say, make an item which added something below each members post like the Flag Item thingy, youd modify this table. Smf_shop_iventory controls the actual items, and this is what we will be looking at today.

Say we want to make an item that isn’t single use but also isn’t multiple use. We will call this item a “Wizard’s Wand”. The Wizard’s Wand will be a type of gambling item. Each time you use it, it gives you 10 points. The more its used, however, the more likely it will break.

The first thing to do is add a “counter” row to the smf_shop_inventory table. This will count how many times the Wizard’s Wand has been used. We can them use the mt_rand function to see if the wand breaks or not. To add this, either use some sort of program or upload and run the following query

Code: [Select]
db_query("ALTER TABLE `{$db_prefix}shop_inventory` ADD `counter` INT(10) UNSIGNED DEFAULT '0' NOT NULL", __FILE__, __LINE__);
Then make sure you remove this file from your server as it posses a security risk.

If you use a program to add it, just make sure the row is named “counter” and is an unsigned int(10) with a default value of zero.

This item contains no input from the user, so the first part of our code looks like this.

Code: [Select]
class item_WizardsWand extends itemTemplate {
   
    //when this function is called, you should set all the item's
    //variables (see inside this example)
    function getItemDetails() {

        //VALUES CHANGABLE FROM WITHIN ADMIN PANEL:
          //the name of the item
          $this->name = "Wizard's Wand";
          //the item's description
          $this->desc = "Wave the wand and get some points. Make sure it doesn't explode though!";
          //the item's price
          $this->price = 30;
         
        //UNCHANGABLE VALUES:
          //whether the item requires input or not. In this case, we don't need
          //any input
          $this->require_input = false;
          //set this to 'false' if the item is unusable. This is good for display
          //items.
          $this->can_use_item = true;
    }
   
        function getAddInput() {
        return "Amount to give per use: <input type='text' name='info1' value='10'>
        "Max number of uses: <input type='text' name='info2' value='6'>";
    }

Now for the fun part. We first start by selecting the value of counter from the proper table. We want the column where the id value is the same as the item we are using(individual items have their own unique id values in the smf_shop_inventory table). To do this, we use the following section of code:
Code: [Select]
function onUse() {
global $db_prefix, $ID_MEMBER, $memberName, $item_info;
$result = db_query(" SELECT counter
FROM {$db_prefix}shop_inventory
WHERE id = {$_GET['id']}", __FILE__, __LINE__);
$row = mysql_fetch_array($result, MYSQL_ASSOC);
This is similar to the code we used in the first section of this tutorial.

Next we need to see if this item breaks or not. $item_info[2] holds the max number of uses. After zero uses, this item is sure to work, and after $item_info[2] uses it is sure to fail. After 2 uses, it should break 2/$item_info[2] of the time. So to see if it works, we first select the numerator of our fraction. This should be a number between 1 and $item_info[2]. So we use

Code: [Select]
$value = mt_rand(1, $item_info[2]);

Now we want to compare $value/$item_info[2] to $row[‘counter’]/$item_info[2]. This, of course, is the same as comparing $value to $row[‘counter’]. If they are equal, or $row[‘counter’] is greater than value, then the item should break. Else wise is should work. So we use a if statement.

Code: [Select]
(if $value <= $row[‘counter’]) {
$result = db_query("UPDATE {$db_prefix}members
  SET money = money - $item_info[1]
WHERE ID_MEMBER = {$ID_MEMBER}", __FILE__, __LINE__);
return “You try to use the Wizard’s wand, but it backfires and destroys {$item_info[1]} of your points!”;
}

If the if statement is false, the item should work, give the user $item_info[1] points, increase the counter by one, not delete itself, and return a successful message.

Code: [Select]
Else {
$result = db_query("UPDATE {$db_prefix}members
  SET money = money + $item_info[1]
WHERE ID_MEMBER = {$ID_MEMBER}", __FILE__, __LINE__);
$result = db_query("UPDATE {$db_prefix}shop_inventory
  SET counter = counter + 1
WHERE id = {$_GET[‘id’]}", __FILE__, __LINE__);
die();
return “You wave your Wizard’s wand an cause {$item_info[1]} points to appear!”;
}
}
}
?>

So this time the final code looks like:    

Code: [Select]
<?php
class item_WizardsWand extends itemTemplate {
    
    
//when this function is called, you should set all the item's
    //variables (see inside this example)
    
function getItemDetails() {

        
//VALUES CHANGABLE FROM WITHIN ADMIN PANEL:
          //the name of the item
          
$this->name "Wizard's Wand";
          
//the item's description
          
$this->desc "Wave the wand and get some points. Make sure it doesn't explode though!";
          
//the item's price
          
$this->price 30;
          
        
//UNCHANGABLE VALUES:
          //whether the item requires input or not. In this case, we don't need
          //any input
          
$this->require_input false;
          
//set this to 'false' if the item is unusable. This is good for display
          //items.
          
$this->can_use_item true;
    }
    
        function 
getAddInput() {
 
       return "Amount to give per use: <input type='text' name='info1' value='10'>
         "
Max number of uses: <input type='text' name='info2' value='10'>";
    }
    
function onUse() {
global 
$db_prefix$ID_MEMBER$memberName$item_info;
$result = db_query(" SELECT counter
FROM {$db_prefix}shop_inventory
WHERE id = {$_GET['id']}", __FILE__, __LINE__);
$row = mysql_fetch_array($result, MYSQL_ASSOC);
$value = mt_rand(1, $item_info[2]);
if (
$value <= $row['counter']) {
$result = db_query("UPDATE {$db_prefix}members
 
SET money money $item_info[1]
     WHERE ID_MEMBER = {$ID_MEMBER}", __FILE__, __LINE__);
return "
You try to use the Wizard's wand, but it backfires and destroys {$item_info[1]} of your points!";
}
else {
$result = db_query("UPDATE {$db_prefix}members
SET money = money + $item_info[1]
WHERE ID_MEMBER = {$ID_MEMBER}", __FILE__, __LINE__);
$result = db_query("UPDATE {$db_prefix}shop_inventory
    SET counter = counter + 1
WHERE id = {$_GET['
id']}", __FILE__, __LINE__);
die();
return "You wave your Wizard'
s Wand and cause {$item_info[1]} points to appear!";
}
}
}
?>



A few words of note:

1)   This code hasn’t been tested yet and thus might contain some bugs. Sorry about that.
2)   Be sure to reuse database rows. If you can make “counter” serve for 4-5 items, then that’s great! You’ve saved space. No one cares if the row name actually makes sense!
3)   Play around with the price as well to make sure this doesn’t give your members too many points. :-P.

233
General SMFShop Discussion / Re: Shop Ideas
« on: April 23, 2006, 12:27:47 pm »
Looks very nice. But when I went to download it, download link didn't work and gave me gibberish. Any idea why?

234
First off, INDENT INDENT INDENT! Seriously, code is much easier to follow when it is properly indented. (general rule of thumb is one tab for each bracket)

Secondly, you need to return a message to the user. I am not sure what happens if you dont. It might work fine, but its nice to give the user a message as well.

Lastly, Im not sure what those quotes are doing after "karma" but they shouldn't be there and will mess up your code. =).

Other than that, seems like you've done a pretty good job =D

So the fixed code would look like

Code: [Select]
<?php
/**********************************************\
| SMFSHOP (Shop MOD for Simple Machines Forum) |
|         (c) 2005 DanSoft Australia           |
|      http://www.dansoftaustralia.com/        |
\**********************************************/

//File: KarmaBash.php
//      Item

//VERSION: 1.1 (Build 4)
//DATE: 10th April 2005

class item_KarmaBash extends itemTemplate {
    function 
getItemDetails() {
        
$this->name "Karma Bash";
        
$this->desc "Bash 10 points of another members karma";
        
$this->price 50;

        
$this->require_input true;
        
$this->can_use_item true;
    }

    function 
getUseInput() {
global $context$scripturl$settings$txt;
        return 
"Karma Bash: <input type='text' name='bashwho' size='50'>
         <a href='
{$scripturl}?action=findmember;input=bashwho;quote=0;sesc={$context['session_id']}' onclick='return reqWin(this.href, 350, 400);'><img src='{$settings['images_url']}/icons/assist.gif' border='0' alt='{$txt['find_members']}' /> Find Member</a>";
    }

function onUse() {
        global 
$db_prefix$ID_MEMBER$item_info;

$result db_query("UPDATE {$db_prefix}members
                           SET karmaBad = karmaBad + 10
                           WHERE membername = 
{$_POST['bashwho']}",
                           
__FILE____LINE__);
    return "Successfully bashed 10 karma points from {$_POST['bashwho']}!";
$result db_query("SELECT ID_MEMBER
         FROM 
{$db_prefix}members
               WHERE memberName = '
{$_POST[‘bashwho’]}'"__FILE____LINE__);
$row mysql_fetch_array($resultMYSQL_ASSOC);
$pmfrom = array(
'id' => 1,
'name' => 'Tazpot',
'username' => 'Tazpot'
);
$pmto = array(
'to' => array($row['ID_MEMBER']),
'bcc' => array()
);
sendpm($pmto'You have been bashed'"{$user} bashed 10 points off your karma! [i] You do not need to reply to this automated message[/i]"0$pmfrom);
return "You have bashed {$_POST['bashwho']} for 10 points off their karma!";
}
}
?>


235
Oh cool  :D.

Actually, while in a normal situation that would be best; we still need to do the select memberName query in order to tell the target who used magic die them. So we would have to make the same two querys in the end. Your way would be slightly more efficant because the faster query would be used to run the if statment. Thus if you are targeting yourself, only the faster query would be done.

236
After reading tazpot's post Here I decided to take him up on it.  :P. After all, item creation is pretty easy(I have coded several fine items with only a begginers knowlege of php and my_sql when I started) and there isn't any reason why Daniel needs to code all the items you have ideas for.  :D. So cause I had some free time, I was like "Lets write a guide"  O0. And so, without futhur ado...   :)

Item Creation 101
By Basilbeard

So we want to create an item for SMF shop. To do this, first figure what item you want to create. For this lesson, we will be creating a “Magic Die”. Upon using the die, it will target another player, and then either give them a random amount of points or destroy a random amount of points.

Note: This guide assumes a basic knowledge of php. Thought not much is required.

Start by opening the testitem.php file.

Code: [Select]
<?php

/**********************************************\
| SMFSHOP (Shop MOD for Simple Machines Forum) |
|         (c) 2005 DanSoft Australia           |
|      http://www.dansoftaustralia.com/        |
\**********************************************/

//File: testitem.php
//      Test Item (gets some inputs, most likely you will base your items on this)

//VERSION: 1.1 (Build 4)
//DATE: 10th April 2005

//your class should always be called item_filename, eg. if your file is 
//myCoolItem.php then the class should be called 'item_myCoolItem'. This 
//class should always extend itemTemplate.

class item_testitem2 extends itemTemplate {
    
    
//when this function is called, you should set all the item's
    //variables (see inside this example)
    
function getItemDetails() {

        
//VALUES CHANGABLE FROM WITHIN ADMIN PANEL:
          //the name of the item
          
$this->name "A Test Item 2";
          
//the item's description
          
$this->desc "Just a test item! The second time!";
          
//the item's price
          
$this->price 5;

        
//UNCHANGABLE VALUES:
          //whether inputs are required by this item. In this case, we get some inputs,
          //so set this to 'true'.
          
$this->require_input true;
          
//set this to 'false' if the item is unusable. This is good for display
          //items.
          
$this->can_use_item true;
    }

    
//this function is called when the user tries to use the item.
    //if your item needs any further user input then you can get that 
    //input here (eg. if it's a "Change username" item then you have
    //to ask the user what they'd like to change their username to).
    //Any text you return will get shown to the user (DON'T ECHO STUFF).
    
function getUseInput() {
        return 
"A Test: <input type='text' name='test123'>";
    }

    
//the is where all the fun begins. This function is called when 
    //the user actually uses the item. Return stuff, DON'T ECHO!
    
function onUse() {
        return 
"Hello, I am a test!<br>In the text box, you entered '{$_POST['test123']}'";
    }
}

?>

Anything after a // is a comment and doesn’t actually appear in the code, so the real file looks like

Code: [Select]
<?php
class item_testitem2 extends itemTemplate {
    function 
getItemDetails() {
          
$this->name "A Test Item 2";
          
$this->desc "Just a test item! The second time!";
          
$this->price 5;

          
$this->require_input true;
          
$this->can_use_item true;
    }

    function 
getUseInput() {
        return 
"A Test: <input type='text' name='test123'>";
    }

    function 
onUse() {
        return 
"Hello, I am a test!<br>In the text box, you entered '{$_POST['test123']}'";
    }
}

?>
First lets try and see what this item does. The function getUseInput() prompts the user for input upon using the item. This is where they will often type in the member name of the target. The type=’text’ tells them to be a text box while the name=’test123’ defines its value for the onUse() function. In this case, name=’test123’ and so whatever the user inputs here can be called up using ($_POST[‘test123’]} in the onUse() function.

Note that if you wanted two inputs, say, an item that lets you pick a target and also an amount to steal, you would not have.
Code: [Select]
    function getUseInput() {
        return "Target: <input type='text' name='target'>";
        return "Amount to steal: <input type='text' name='steal'>";
    }

Because the return line causes that part of the function to end. Instead, you would need to have.

Code: [Select]
    function getUseInput() {
        return "Target: <input type='text' name='target'> <br>
                Amount to steal: <input type='text' name='steal'>";
    }

Here, the target name could later be called up using {$_POST[‘target’]} and the amount to steal could later be called up using {$_POST[‘steal’]}.

Now lets examine the second half of the code.

Code: [Select]
    function onUse() {
        return "Hello, I am a test!<br>In the text box, you entered '{$_POST['test123']}'";
    }

This is very simple. ‘return’ tells it print the follow text in the quotes. Thus, upon using the item it will display

Hello, I am a test!
In the text box, you entered ‘Arrrrrrrr!’

(this assumes that I did infact enter Arrrrrrr! In the textbox.

So now that we understand the basics behind how this item works, lets start coding out item.

We start by copying this to a new file, which we call MagicDie.php

Code: [Select]
  <?php
class item_testitem2 extends itemTemplate {
    function 
getItemDetails() {
          
$this->name "A Test Item 2";
          
$this->desc "Just a test item! The second time!";
          
$this->price 5;

          
$this->require_input true;
          
$this->can_use_item true;
    }

    function 
getUseInput() {
        return 
"A Test: <input type='text' name='test123'>";
    }

    function 
onUse() {
        return 
"Hello, I am a test!<br>In the text box, you entered '{$_POST['test123']}'";
    }
}

?>


The most important change is in the second line. We need to change class item_testitem2 extends itemTemplate { to class item_MagicDie extends itemTemplate {
We then need to change the name and desc and price. This item requires input and it can be used, so the other two values stay as true. Lets make this item cost 20 points.

Code: [Select]
  <?php
class item_MagicDie extends itemTemplate {
    function 
getItemDetails() {
          
$this->name "Magic Die";
          
$this->desc "Why risk your own points when you can gamble with someone elses?";
          
$this->price 20;

          
$this->require_input true;
          
$this->can_use_item true;
    }

For this item, we also need to include the getAddInput() function. This will allow us, upon the creation of the item, to send bounds on how rewarding or damaging this item can be.
Code: [Select]
    function getAddInput() {
        return "Max amount to give: <input type='text' name='info1' value='100'><br>
               Max amount to take: <input type='text' name='info2' value='-100'>";
    }

Unlike with the getUseInput() function, you cannot change the value of the ‘name’ in these two lines. If you were to add a third, it would have to be called ‘info3’ and a fourth would be ‘info4’. You can’t add anymore after that due to database constraints.

Now that we have that part coded, lets again code our getUseInput() function. This is best served by copying the same function from another item, say the steal item we already have.

Code: [Select]
    function getUseInput() {
global $context, $scripturl, $settings, $txt;
        return "Steal From: <input type='text' name='stealfrom' size='50'>
         <a href='{$scripturl}?action=findmember;input=stealfrom;quote=0;sesc={$context['session_id']}' onclick='return reqWin(this.href, 350, 400);'><img src='{$settings['images_url']}/icons/assist.gif' border='0' alt='{$txt['find_members']}' /> Find Member</a>";
    }

We of course need to make some changes. Namely, the “Steal From” line needs to be changed and the name should be more like ‘dicetarget’ rather than ‘stealfrom’. So we make out changes.

Code: [Select]
    function getUseInput() {
global $context, $scripturl, $settings, $txt;
        return “Choose a target for your die: <input type='text' name='dicetarget' size='50'>
         <a href='{$scripturl}?action=findmember;input=dicetarget;quote=0;sesc={$context['session_id']}' onclick='return reqWin(this.href, 350, 400);'><img src='{$settings['images_url']}/icons/assist.gif' border='0' alt='{$txt['find_members']}' /> Find Member</a>";
    }

Don’t worry about all that funky code. That adds the button that lets you search for member’s names. Now we just need to code the fun part. The onUse() function. The part that actually tells the item what to do.
Code: [Select]
    function onUse() {
        global $db_prefix, $ID_MEMBER, $item_info;

The first task is to make sure they are not targeting themselves with the item. They should use random money if they want to do that. So we do a database query.
Code: [Select]
$result = db_query("SELECT memberName
                                FROM {$db_prefix}members
                                WHERE ID_MEMBER = {$ID_MEMBER}", __FILE__, __LINE__);

I personally hate these queries. The syntax needs to be perfect or else the item will not work, and I often find I need keep fixing the syntax on my items several times after I add them before they actually work. But they are needed for any good item. They are what you use for almost everything, from changing someone’s money count to modifying their title or post count.

We then need to add a few more lines of code. I am not a PHP know-it-all, so can’t really explain why it works I just know it does.

Code: [Select]
$row = mysql_fetch_array($result, MYSQL_ASSOC);
$user = $row[‘memberName’]

This creates an array called row(I think) which contains the previously selected memberName. We can now call that value using $row[‘memberName’]; our next part needs to be an if statement which gets to see if $row[‘memberName’] is the same name as the name the user inputted. If this is true, we need to return an error message instead of executing the random part.

Code: [Select]
if ($user == $_POST[‘dicetarget’]) {
return “Use some random money instead. Use the die on someone else”;
die();
}

According to Daniel, the die() function should stop the item from deleting itself. I have worked around this differently and thus cannot test this, but if it gives you any errors, just remove it from the code.

Now we need to code the other part of the code, what happens when the target is someone different. To do this, we just use an else.
Code: [Select]
else {
$amount = mt_rand($item_info[2], $item_info[1]);

The mt_rand function creates a random integer(inclusive) between the two given bounds. Exactly what we want. We now need to update the other guys point count. Guess what? We need another database query to do this.
Code: [Select]
$result = db_query("UPDATE {$db_prefix}members
                                SET money = money + {$ammount}
                                WHERE memberName = '{$_POST[‘dicetarget’]}'", __FILE__, __LINE__);

So we have updated the database with the random amount. There are two things left to do. The first is to send a friendly PM to the unlucky or lucky target. They should know their points have been changed. To do this, we actually need to add a couple of lines into the top of the code. There again might be a better way to do this, but this is how I’ve figured out how to do it. So until Daniel tells me a better way to do it, add

Code: [Select]
global $sourcedir;
require_once($sourcedir . '/Subs-Post.php');

below the <?php line that starts your code.

Now let’s send the PM. We first need to select the targets ID_MEMBER number so that the PM can be sent.

Code: [Select]
$result = db_query("SELECT ID_MEMBER
       FROM {$db_prefix}members
                           WHERE memberName = '{$_POST[‘dicetarget’]}'", __FILE__, __LINE__);
$row = mysql_fetch_array($result, MYSQL_ASSOC);
$pmfrom = array(
'id' => 1,
'name' => 'Basilbeard',
'username' => 'Basilbeard'
);
$pmto = array(
to' => array($row['ID_MEMBER']),
'bcc' => array()
);
sendpm($pmto, 'Care for a game of chance?', “{$user} uses a Magic Die on you. You check your inventory, and find that your point total has been changed by ".formatMoney($amount).”! [i] You do not need to reply to this automated message”, 0, $pmfrom);                                           

Lastly, we need to return a statement to the user of the item and then make sure we end all our brackets and such.

Code: [Select]
Return “You use your Magic Die on {$_POST[‘dicetarget’}. It spins around for a few minutes, before landing on {$amount} and thus changing their point count by “.formatMoney{$amount}.”!”;
} // This ends the else bracket.
} // This ends the onUse function
} // This items the item function itself.
?> // this ends the PHP code, and thus out file.

So in the end, our whole file looks like:

Code: [Select]
<?php
/**********************************************\
| SMFSHOP (Shop MOD for Simple Machines Forum) |
|         (c) 2005 DanSoft Australia           |
|      http://www.dansoftaustralia.com/        |
\**********************************************/

//File: MagicDie.php
//      Magic Die

//VERSION: 1.0
//DATE: 16th April 2006
//AUTHOR: Basilbeard
global $sourcedir;
require_once(
$sourcedir '/Subs-Post.php');
class 
item_MagicDie extends itemTemplate {
    function 
getItemDetails() {
          
$this->name "Magic Die";
          
$this->desc "Why risk your own points when you can gamble with someone elses?";
          
$this->price 20;

          
$this->require_input true;
          
$this->can_use_item true;
    }

    function 
getAddInput() {
 
   return "Max amount to give: <input type='text' name='info1' value='100'><br>
               Max amount to take: <input type='text' name='info2' value='-100'>"
;
    }

    function 
getUseInput() {
global $context$scripturl$settings$txt;
        return 
"Choose a target for your die: <input type='text' name='dicetarget' size='50'>
         <a href='
{$scripturl}?action=findmember;input=dicetarget;quote=0;sesc={$context['session_id']}' onclick='return reqWin(this.href, 350, 400);'><img src='{$settings['images_url']}/icons/assist.gif' border='0' alt='{$txt['find_members']}' /> Find Member</a>";
    }

    function 
onUse() {
    global $db_prefix$ID_MEMBER$item_info;
$result db_query("SELECT memberName
                                FROM 
{$db_prefix}members
                                WHERE ID_MEMBER = 
{$ID_MEMBER}"__FILE____LINE__);
$row mysql_fetch_array($resultMYSQL_ASSOC);
$user $row['memberName'];
if ($user == $_POST['dicetarget']) {
return "Use some random money instead. Use the die on someone else"
die();
}
else {
$amount mt_rand($item_info[2], $item_info[1]);
$result db_query("UPDATE {$db_prefix}members
                                SET money = money + 
{$ammount}
                                WHERE memberName = '
{$_POST['dicetarget']}'"__FILE____LINE__);
$result db_query("SELECT ID_MEMBER
        FROM 
{$db_prefix}members
                         WHERE memberName = '
{$_POST['dicetarget']}'"__FILE____LINE__);
$row mysql_fetch_array($resultMYSQL_ASSOC);
$pmfrom = array(
'id' => 1,
'name' => 'Basilbeard',
'username' => 'Basilbeard'
);
$pmto = array(
to' => array($row['ID_MEMBER']),
'
bcc' => array()
);
sendpm($pmto, '
Care for a game of chance?', "{$user} uses a Magic Die on you. You check your inventory, and find that your point total has been changed by ".formatMoney($amount)."! [i] You do not need to reply to this automated message[/i]", 0, $pmfrom);                                           
return "You use your Magic Die on {$_POST['
dicetarget']}. It spins around for a few minutes, before landing on {$amount} and thus changing their point count by {$amount} points!";;
}
}
}
?>


Now of course, if I am coding my own items I don’t worry too much about commenting. But if I am doing some coding for others and that, its nice to add some recognition both to myself and to Daniel. So that’s why I put that block of code up at the very top.

The only thing remaining is to upload the item, install it and test it out. For me this never seems to work the first time, or the second time, or even the nth time. I personally prefer to just code the item in something like Crimson Editor, which shows any really dumb mistakes, and then to just upload and let it tell me what I did wrong instead of spending time looking for it myself. For example, the first time I coded this item I forgot the ; on the $user = $row['memberName']; line, causing the whole function not to work.

Once all the errors in the code are sorted out. We need to see if the item works. I start by using it on myself.

Quote
Use some random money instead. Use the die on someone else

Yay! It worked!.

I then try on someone else. And get a mysql error. As I said, I hate those errors. Luckily, this one wasn’t bad. I had {$ammount} instead of {$amount}.

I use it again and get
Quote
You use your Magic Die on Bunny. It spins around for a few minutes, before landing on 52 and thus changing their point count by 52 points!

Yay! The last thing to do is log into Bunny and see the PM. It works! So I assume the item is working just fine and release it on my forum. Or, in this place, remove it from my forum and post this guide.



I'm open to any questions you might have about the guide. Questions about SMF_SHOP itself would probably be better suited for Daniel cause he was the one that acutally wrote it  :P

Update: 4/23: Scroll down for part 2! Learn how to code items which use custom database fields!

237
General SMFShop Discussion / Re: Shop idea: staff gets paid
« on: April 09, 2006, 09:54:56 am »
That would be pretty cool. =).

As I said above, you can simply use the date() function after each use, saving it into dateused part of the smf_shop_inventory database. If you wanted to make it an offical feature, you could also have a "time period" which the user enters at the creation of the item(to allow for once per day, or once per hour, or items like that). It wouldn't be that hard to store the date() after each use, and then run an if date() - (dateused) > (time period) before the use of then item. That way it would be build into the smf_shop code itself instead of adding extra junky lines to the item codes.

238
General SMFShop Discussion / Re: Shop idea: staff gets paid
« on: April 08, 2006, 11:11:52 am »
We aren't supposed to change the smf_shop_inventory table around? Oops... I've added like three columns onto it already. Hopefully it wont cause any problems. =). Putting it in the smf_members table sounds like a good idea, but doesn't allow you to code other types of once per day items.

Also thanks for the information about the die() function. Seems alot better considering that most of my items are one use anyways.

239
General SMFShop Discussion / Re: Shop idea: staff gets paid
« on: April 08, 2006, 01:01:22 am »
The way I have seen this done on other forums is to give each staff an item which can only be used once per day/once per week/however long want them to get their money. When they use the item, it gives them their salary but doesn't disappear.(You have to make a few changes to the shop.php code, namly removing the code that deletes the items after each use in order to do this. Of couse, when you do that you need to reinsert that same code at the end of all your other items that are supposed to be one. You also need another database column on the smf_shop_inventory to count when the item was last used.).

A cron job would be the other way, but im not experienced there. Plus making it item based encourages mods to be active. The mod can't go away for a month and add up loads of credits during their absence.

240
General SMFShop Discussion / Re: shop questions
« on: April 08, 2006, 12:51:53 am »
Go to your admin panel. From there you should see Shop Administration as one of the blocks on the left toolbar.
Shop Administration - General Settings to edit amount of credits per post.
Shop Administration - Add new Item to add new items.

Note that if you code yourself a new item, you need to add it to simplemachinesroot/sources/shop/items/ in order to add it from the Add New Item Page.
---

If you don't  see the Shop Administration section of the sidebar, then my guess is SMFshop didn't install properly. Try installing it again, and if that doesn't work, the only thing left to do is bug Daniel.

Pages: 1 ... 14 15 [16]