PDA

View Full Version : Mys 1.3.4 Item Shop Mod(s): NPC + Item Display + Tooltips


Kyttias
12-23-2014, 01:37 AM
Item Shop Mod(s): NPC + Item Display + Tooltips
Today we're going to modifying classes/class_itemshop.php, specifically the display() function. This guide comes in two parts. The first part will be a total modification of your item shops to display an NPC, with random text, and an overhaul of how items are displayed, complete with tooltips. The second part is just the item display overhaul, for those uninterested in having an NPC run your shops.

Let's start by showing you what you'll be making (if you change nothing), on the default Main theme Mysidia comes with, to prove it should work with any thee. After this, I'll give you the code as-is. Then I'll make an attempt at explaining in the code in greater detail. The code already comes commented, but if you're looking to build things to your exact specifications, it is my hope that the further reading will give you the details you need.

http://fc05.deviantart.net/fs71/f/2014/356/4/e/sc1_by_kyttias-d8avedp.png
Section 1 - Default InstructionsWe'll be replacing the display function in classes/class_itemshop.php:
public function display(){
$mysidia = Registry::get("mysidia");
$document = $mysidia->frame->getDocument();
$document->addLangvar($mysidia->lang->select_item);

if($this->gettotal() == 0){
$document->addLangvar($mysidia->lang->empty);
return FALSE;
}

# Choose the NPC image based on the name of the shop
switch ($this->shopname) {
case "Crossed Roads":
$npc_img = "http://fc00.deviantart.net/fs71/f/2014/262/a/2/base_npc_60_by_kyttias-d7zqrnf.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Time is money."; break;
case 2: $npc_text = "Isn't icecream super?"; break;
case 3: $npc_text = "Welcome to {$this->shopname}!"; break;
case 4: $npc_text = "Off to see the wizard?"; break;
case 5: $npc_text = "Tomorrow is another day..."; break;
case 6: $npc_text = "PHP is cool!"; }
break;
case "Spectrum":
$npc_img = "http://fc00.deviantart.net/fs70/f/2014/313/a/c/base_npc_2_60_by_kyttias-d85ww5k.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Time is money."; break;
case 2: $npc_text = "Isn't icecream super?"; break;
case 3: $npc_text = "Welcome to {$this->shopname}!"; break;
case 4: $npc_text = "Off to see the wizard?"; break;
case 5: $npc_text = "Tomorrow is another day..."; break;
case 6: $npc_text = "PHP is cool!"; }
break;
default;
$npc_img = "http://placekitten.com/g/200/500";
$npc_text = "Welcome to {$this->shopname}!";
break;
}

# let's begin rendering the page
$document->add(new Comment("
<style>
.s_top {
overflow:hidden;
display: block;
}
.sc_npc_text{
width: 300px;
float: left;
position: relative;
height: 70px;
padding: 15px;
margin: 10px;
margin-top: 180px;
font-family: 'Trebuchet MS', Helvetica, sans-serif;
overflow: auto;
}
.sc_npc_img{
width: 40%;
float: left;
}

.sc_item {
display: inline-table;
padding: 5px;
text-align: center;
font-family: 'Trebuchet MS', Helvetica, sans-serif;
font-size: 14px;
margin-bottom: 3px;
}
.s_panel {
border-radius: 2px;
border: 1px solid #CCC;
background-color: #FBFDF2;
}
</style>
<!-- START Container for Text and NPC -->
<div class='s_top s_container'>
<div class='s_panel sc_npc_text'>{$npc_text}</div>
<div class='sc_npc_img'><img src='{$npc_img}' height='300'></div>
</div>
<!-- END Container for Text and NPC -->
<!-- START Container for Items -->
<div class='s_container'>
", FALSE));

# Now render each item the store has
foreach($this->items as $stockitem){
$item = $this->getitem($stockitem);

#descriptions of the item functions
switch ($item->function) {
case "Click1": $usage = "<br/><b>use:</b> Feed a pet to give them {$item->value} EXP."; break;
case "Click2": $usage = "<br/><b>use:</b> Feed a pet to set their EXP to {$item->value}."; break;
case "Click3": $usage = "<br/><b>use:</b> Resets EXP earned today to 0."; break;
case "Level1": $usage = "<br/><b>use:</b> Raises the Level of your pet by {$item->value}."; break;
case "Level2": $usage = "<br/><b>use:</b> Sets the Level of your pet to {$item->value}."; break;
case "Level3": $usage = "<br/><b>use:</b> Makes your pet Level 0 again!"; break;
case "Gender": $usage = "<br/><b>use:</b> Swaps the gender of your pet to its opposite!"; break;
default;
$usage = "";
break;
}

# Now let's render each item icon, name, price and tooltip
$document->add(new Comment("
<div class=\"s_panel sc_item\">
<img rel=\"tooltip\" title=\"{$item->description} <em>{$usage}</em>\" src=\"{$item->imageurl}\"/><br/>
<b>{$item->itemname}</b>
<br/>
{$item->price} {$mysidia->settings->cost}<br/>
", FALSE));


# Building the Buy form
$buyForm = new FormBuilder("buyform", "../purchase/{$mysidia->input->get("shop")}", "post");
$buyForm->setLineBreak(FALSE);
$buyForm->buildPasswordField("hidden", "action", "purchase")
->buildPasswordField("hidden", "itemname", $item->itemname)
->buildPasswordField("hidden", "shopname", $shop->shopname)
->buildPasswordField("hidden", "shoptype", "itemshop")
->buildPasswordField("hidden", "salestax", $shop->salestax);
$quantity = new TextField("quantity", "1");
$quantity->setSize(3);
$quantity->setMaxLength(3);
$quantity->setLineBreak(FALSE);
$buy = new Button("Buy", "buy", "buy");
$buy->setLineBreak(FALSE);
$buyForm->add($quantity);
$buyForm->add($buy);

# Actually adding in the Quantity field Buy button now
$document->add($buyForm);

# Now we finish off the item by closing its div
$document->add(new Comment("</div>", FALSE));
}

# And that's a wrap
$document->add(new Comment("</div><!-- END Container for Items -->", FALSE));

} #END display function

You'll notice in the screenshot above that the items don't appear to have a description with them. This is because I'm also going to help you install nifty tooltips!

Section 2 - TooltipsIn your directory where Mysidia is installed there is a css folder (not talking about anything theme-related in the template folder, this css folder is the one at the root). We're going to add this as tooltip.css -

#tooltip
{
text-align: center;
color: #fff;
background: #111;
position: absolute;
z-index: 100;
padding: 15px;
}

#tooltip:after /* triangle decoration */
{
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #111;
content: '';
position: absolute;
left: 50%;
bottom: -10px;
margin-left: -10px;
}

#tooltip.top:after
{
border-top-color: transparent;
border-bottom: 10px solid #111;
top: -20px;
bottom: auto;
}

#tooltip.left:after
{
left: 10px;
margin: 0;
}

#tooltip.right:after
{
right: 10px;
left: auto;
margin: 0;
}

A nearby folder, also in the heart of things, is called js. Open up this folder and add this as tooltip.js:
/*
TOOLTIP
*/

$( function()
{
var targets = $( '[rel~=tooltip]' ),
target = false,
tooltip = false,
title = false;

targets.bind( 'mouseenter', function()
{
target = $( this );
tip = target.attr( 'title' );
tooltip = $( '<div id="tooltip"></div>' );

if( !tip || tip == '' )
return false;

target.removeAttr( 'title' );
tooltip.css( 'opacity', 0 )
.html( tip )
.appendTo( 'body' );

var init_tooltip = function()
{
if( $( window ).width() < tooltip.outerWidth() * 1.5 )
tooltip.css( 'max-width', $( window ).width() / 2 );
else
tooltip.css( 'max-width', 340 );

var pos_left = target.offset().left + ( target.outerWidth() / 2 ) - ( tooltip.outerWidth() / 2 ),
pos_top = target.offset().top - tooltip.outerHeight() - 20;

if( pos_left < 0 )
{
pos_left = target.offset().left + target.outerWidth() / 2 - 20;
tooltip.addClass( 'left' );
}
else
tooltip.removeClass( 'left' );

if( pos_left + tooltip.outerWidth() > $( window ).width() )
{
pos_left = target.offset().left - tooltip.outerWidth() + target.outerWidth() / 2 + 20;
tooltip.addClass( 'right' );
}
else
tooltip.removeClass( 'right' );

if( pos_top < 0 )
{
var pos_top = target.offset().top + target.outerHeight();
tooltip.addClass( 'top' );
}
else
tooltip.removeClass( 'top' );

tooltip.css( { left: pos_left, top: pos_top } )
.animate( { top: '+=10', opacity: 1 }, 50 );
};

init_tooltip();
$( window ).resize( init_tooltip );

var remove_tooltip = function()
{
tooltip.animate( { top: '-=10', opacity: 0 }, 50, function()
{
$( this ).remove();
});

target.attr( 'title', tip );
};

target.bind( 'mouseleave', remove_tooltip );
tooltip.bind( 'click', remove_tooltip );
});
});

Now, in your theme's header.tpl, add in these lines (before the end of the </head>, of course):

{$header->loadStyle("{$home}{$css}/tooltip.css")}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="{$home}{$js}/tooltip.js"></script>
<script src="{$home}{$js}/tabs.js"></script>
<script>
$(function() { $("#profile").organicTabs(); });
</script>


You now have all the necessary components for tooltips. You now also have jQuery, for future reference. If you already had jQuery, say, at the end of your </body> in your template.tpl (and if you have Bootstrap, you do), move the scripts there instead (but go ahead and leave the css in the header). These scripts must always come after your jQuery installation.

You'll notice I also have tab-related things in the above. This is because your profile tabs will have broken, and this will fix it. So now, to finish fixing up the tabs, open up inc/tabs.php and delete the contents (but not the file).

Using Tooltips:
To make tooltips elsewhere on your site, from now on, all you need to do is add title="Contents of the tooltip here!" rel="tooltip" to any element you want to have a tooltip. Could be links, divs, spans, images, etc. You can also use some basic html inside them, such as italicies, bold, and linebreaks.

For more reference on the tooltip system I just had you install, visit this link (http://osvaldas.info/elegant-css-and-jquery-tooltip-responsive-mobile-friendly).

http://fc01.deviantart.net/fs71/f/2014/356/1/1/sc1_by_kyttias-d8avivr.gif
Section 3 - Detailed UnderstandingNow, please take the time to check out the first bit of code I gave you, that new display function!

In place are two example shopkeeper NPCs. Please do not use these images and be ready to replace them with your own. My shop names are "Crossed Roads" and "Spectrum" - observe the code going on, it does have commentary! Replace these shop names with your own and don't be afraid to copy and paste to make room for more shops.

Each shopkeeper can say it's own set of random things. Can you see how there are six phrases, and a random number is being chosen between 1 and 6? Change as necessary.

Also, anywhere in a case, but before the break, you could also redefine the $npc_img. In this way, you could give your NPCs a variety of emotions, depending on their randomly selected phrase.

By default, if the script cannot find your shop's name on the list, it will display a cute kitten as a placeholder and a basic "Welcome to {$this->shopname}!". Feel free to keep on using this placeholder during your development. :3

Moving along, the page rendering will start to take place. $document->add(new Comment(" ... ")); will allow you to insert text to the current page. By default, there is a linebreak after comments inserted this way, so after each of my comments, you'll see I write FALSE to prevent this behavior, as it would produce undesired results while placing divs.

You'll see that I've inserted the css right there. Leave it, or move it to your own css file if it will be more convenient to you - the choice is yours. Adding width: 100px; to .sc_item will take longer titles down to multiple lines, but may increase the height of those item boxes. This may or may not be desired.

We're still inside the "new Comment" we're adding to the document, and you'll see that I'm adding divs just as easily as I would basic HTML. Take notice that we're inside double quotes, so the HTML must use single quotes when defining things like classes and inline styles. If double quotes are absolutely necessary, you can throw a backslash in front of them and they'll render as normal. Like this: \"This would be in double quotes.\"

Observe how the final page is rendered by visiting your shop and viewing the source (a right-click, Inspect Element anywhere in the shop area will get you in the approximate location). Because it's as easy as HTML inside these "new Comment" areas, go forth and be creative!

Our first "new Comment" ends with the start of a new div, which we'll close only after we've run a statement that will render the items, and we'll do that now.

This next bit opens up with a switch statement which will make the item function (as stored in the database) appear in a nice, plain text form that can be easily appended to the item description. It'll save you the trouble of including what an item does while writing the item's description! Not all item functions are included, so you'll want to append them with your own.

Now we're making the item. You'll see that I'm backslashes double quotes - this is so item descriptions that contain apostrophes will display without breaking anything! We wouldn't want that. <em> tags are just another way of doing italics. And, yes, some basic HTML does work inside the tooltips. {$mysidia->settings->cost} will automatically pull up the name of your site's currency, which can always be changed in the AdminCP or database.

Next the buy form is being built, added, and then the individual item's container is being closed.

Breaking out of this statement now, we'll close the div for the container that holds all the items.

If you wanted to, say, move your NPC to sit to the right of your items, you may want do your div work here, after the item containers have closed.

Section 4 - Just Items & Tooltips
The switch statement where the NPC is chosen for the shop isn't necessary, the first three css properties aren't necessary, and you can delete everything from the START Container for Text and NPC to END Container for Text and NPC. Isn't commented code nice?

Alternatively, all you need is this:
public function display(){
$mysidia = Registry::get("mysidia");
$document = $mysidia->frame->getDocument();
$document->addLangvar($mysidia->lang->select_item);

if($this->gettotal() == 0){
$document->addLangvar($mysidia->lang->empty);
return FALSE;
}

# let's begin rendering the page
$document->add(new Comment("
<style>
.sc_item {
display: inline-table;
padding: 5px;
text-align: center;
font-family: 'Trebuchet MS', Helvetica, sans-serif;
font-size: 14px;
margin-bottom: 3px;
}
.s_panel {
border-radius: 2px;
border: 1px solid #CCC;
background-color: #FBFDF2;
}
</style>
<!-- START Container for Items -->
<div class='s_container'>
", FALSE));

# Now render each item the store has
foreach($this->items as $stockitem){
$item = $this->getitem($stockitem);

#descriptions of the item functions
switch ($item->function) {
case "Click1": $usage = "<br/><b>use:</b> Feed a pet to give them {$item->value} EXP.";
break;
case "Click2": $usage = "<br/><b>use:</b> Feed a pet to set their EXP to {$item->value}.";
break;
case "Click3": $usage = "<br/><b>use:</b> Resets EXP earned today to 0.";
break;
case "Level1": $usage = "<br/><b>use:</b> Raises the Level of your pet by {$item->value}.";
break;
case "Level2": $usage = "<br/><b>use:</b> Sets the Level of your pet to {$item->value}.";
break;
case "Level3": $usage = "<br/><b>use:</b> Makes your pet Level 0 again!";
break;
case "Gender": $usage = "<br/><b>use:</b> Swaps the gender of your pet to its opposite!";
break;
default;
$usage = "";
break;
}

# Now let's render each item icon, name, price and tooltip
$document->add(new Comment("
<div class=\"s_panel sc_item\">
<img rel=\"tooltip\" title=\"{$item->description} <em>{$usage}</em>\" src=\"{$item->imageurl}\"/><br/>
<b>{$item->itemname}</b>
<br/>
{$item->price} {$mysidia->settings->cost}<br/>
", FALSE));


# Building the Buy form
$buyForm = new FormBuilder("buyform", "../purchase/{$mysidia->input->get("shop")}", "post");
$buyForm->setLineBreak(FALSE);
$buyForm->buildPasswordField("hidden", "action", "purchase")
->buildPasswordField("hidden", "itemname", $item->itemname)
->buildPasswordField("hidden", "shopname", $shop->shopname)
->buildPasswordField("hidden", "shoptype", "itemshop")
->buildPasswordField("hidden", "salestax", $shop->salestax);
$quantity = new TextField("quantity", "1");
$quantity->setSize(3);
$quantity->setMaxLength(3);
$quantity->setLineBreak(FALSE);
$buy = new Button("Buy", "buy", "buy");
$buy->setLineBreak(FALSE);
$buyForm->add($quantity);
$buyForm->add($buy);

# Actually adding in the Quantity field Buy button now
$document->add($buyForm);

# Now we finish off the item by closing its div
$document->add(new Comment("</div>", FALSE));
}

# And that's a wrap
$document->add(new Comment("</div><!-- END Container for Items -->", FALSE));

}

You'll definitely need to read up on all the details in Section 2 regarding tooltips and installation of them.

Kyttias
12-23-2014, 02:48 AM
InventoryI'm also pleased to present a semi-matching Inventory view. The embedded stylesheet is identical to the shop mod above, therefore, if you already moved it to your actual css stylesheet, you won't need it here (my example here has .sc_item set with a width, the one in the shop mod above does not, but I did mention it's potential usage). ^^
http://fc04.deviantart.net/fs70/f/2014/357/3/3/sc1_by_kyttias-d8avu35.png
Replace the index function in view/inventoryview.php:
public function index(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
$document->setTitle($mysidia->lang->inventory);

$inventory = $this->getField("inventory");

$document->add(new Comment(" <style>
.sc_item {
display: inline-table;
padding: 5px;
text-align: center;
font-family: 'Trebuchet MS', Helvetica, sans-serif;
font-size: 14px;
margin-bottom: 3px;
width: 120px;
}
.s_panel {
border-radius: 2px;
border: 1px solid #CCC;
background-color: #FBFDF2;
}
</style> ", FALSE));
$iids = $inventory->getiids();
for($i = 0; $i < $iids->length(); $i++){
$item = $inventory->getitem($iids[$i]);

# Descriptions of the item functions
switch ($item->function) {
case "Click1": $usage = "<br/><b>use:</b> Feed a pet to give them {$item->value} EXP."; break;
case "Click2": $usage = "<br/><b>use:</b> Feed a pet to set their EXP to {$item->value}."; break;
case "Click3": $usage = "<br/><b>use:</b> Resets EXP earned today to 0."; break;
case "Level1": $usage = "<br/><b>use:</b> Raises the Level of your pet by {$item->value}."; break;
case "Level2": $usage = "<br/><b>use:</b> Sets the Level of your pet to {$item->value}."; break;
case "Level3": $usage = "<br/><b>use:</b> Makes your pet Level 0 again!"; break;
case "Gender": $usage = "<br/><b>use:</b> Swaps the gender of your pet to its opposite!"; break;
default;
$usage = ""; break;
} # End item function descriptions


# Rendering items now
$document->add(new Comment("
<div class=\"s_panel sc_item\">
<img rel=\"tooltip\" title=\"{$item->description} <em>{$usage}</em>\" src=\"{$item->imageurl}\"/><br/>
<b>{$item->itemname}</b><br> Own &times;{$item->quantity}<br/>", FALSE));

# If item is consumable, add use button
if($item->consumable == "yes") {
$useForm = new FormBuilder("useform", "inventory/uses", "post");
$useForm->setLineBreak(FALSE);
$useForm->buildPasswordField("hidden", "action", "uses")
->buildPasswordField("hidden", "itemname", $item->itemname)
->buildButton("Use", "use", "use");
$document->add($useForm);
}

# Add sellback button so long as the item is not a key item
$sellback = $item->price / 2;
$document->add(new Comment("<hr>{$sellback} {$mysidia->settings->cost} Each ", FALSE));
if($item->category != "Key Items") {
$sellForm = new FormBuilder("sellform", "inventory/sell", "post");
$sellForm->setLineBreak(FALSE);
$sellForm->buildPasswordField("hidden", "action", "sell")
->buildPasswordField("hidden", "itemname", $item->itemname);

$quantity = new TextField("quantity");
$quantity->setSize(3);
$quantity->setMaxLength(3);
$quantity->setLineBreak(FALSE);

$sell = new Button("Sell", "sell", "sell");
$sell->setLineBreak(FALSE);

$sellForm->add($quantity);
$sellForm->add($sell);
$document->add($sellForm);
}

$document->add(new Comment("</div>", FALSE));

} # END item for loop

} # END index function

Emphasis: Please replace the index function, not the entire file.

parayna
12-23-2014, 06:19 AM
Thank you Kyttias! :)

Abronsyth
12-23-2014, 07:14 AM
This is absolutely fantastic! Thank you very, very much for sharing this with us!

I'll install as soon as I get my theme set up, haha.

Edit:
Just installed it and it works beautifully!

Many thanks! Just looks so awesome now! And I love the tooltips! Very cool!

Pear
12-30-2014, 02:46 PM
Ooh, I might use this in the future. :3 < 3 Thanks, Kyt!

Kyttias
12-30-2014, 03:39 PM
I'm glad to hear it! :happyc:

MikiHeart
01-19-2015, 06:34 AM
Awesome mods. I've installed them both. I love the tooltips and plan to use them to display information about pets and things, to clean up the pet pages a bit more ^^

MikiHeart
01-19-2015, 07:59 AM
Hey Kyttias, I'm using the bootstrap theme you created. The input fields are 200px long, and not short like yours. I'm unsure to how change it. I found out it's 200px by using the inspect tool in firefox, however, I've searched the bootstrap style high and low and couldn't find it. I'm using my own generated colors for the theme, but even if I switch back to the default one you have in the header, it displays the same.

From looking at your code, this should be setting the size, I think, but it's not.
$quantity->setSize(3);

Kyttias
01-19-2015, 11:37 AM
The preview image was done with the main/original theme, not Bootstrap. Because of the way Bootstrap works (and not by my design), form elements are always 100% the width of their container, which was uncomfortably long for any area where all I needed/wanted was 200px - so I set the default length to 200px using css, mostly because I was loading the original copy of Bootstrap from a CDN, for speed reasons, and had no access to change it.

However, did you also see that the quantity field had an id associated with it? Fix it with css:
#quantity {width: 50px;}

By the way? It was original set with just css, anyway, in style-kyt.css, around line 56:
@media (min-width: 767px){
input.form-control, select.form-control { width: 200px; display: inline-block;}
}

That's a media query and it says if the browser window/device is at least 767px wide, all text input fields are 200px. Just above this in the file, I have this same field set to 100% width (which is default behavior) because on small screens, that's generally ok.

So, again, just make a line specifically for the quantity field.

MikiHeart
01-19-2015, 10:46 PM
ohh okay. Makes sense why I couldn't find it. Thank you *.*

Do you plan to make a recode to suit the adoptable shop as well? Unless you don't plan to use that feature for your site?

Kyttias
01-19-2015, 11:11 PM
I've never even made an adopt shop, but I'm sure I'll give it a shot eventually. ^^;

MikiHeart
01-19-2015, 11:59 PM
I might try and give it a shot myself. Not sure how well it'll go XD

kristhasirah
01-24-2015, 07:13 AM
Thanks for the mod!!!! Works like a charm, also i manage to make it works for the adoptshop ^^ well it works, but dont know how to remove the items function, because if i remove them the mod gives me a blank page. But so far if i leave that part of the code the mod works well for the adoptshop

MikiHeart
01-24-2015, 10:32 PM
kristhasirah: That doesn't sound right. have you tried buying an adopt and everything?
Because when I looked at the code, it was different. Display and functionality are different.

kristhasirah
01-25-2015, 12:01 AM
You are right... Manage to make the adopshop look like the itemshop only, still need to figure out how to actually adopt a pet >_>
I was kind of happy and forgot to test the adopt part =\ now to wait until monday to keep working on the code>_<

Edit:
is working now :D
i can adopt fine ,just had to remove the $quantity and change every "item" for "adopt" and afew other things.
and manage to remove the items description.

Kyttias
01-25-2015, 02:09 AM
If I have time, I'll give the adopt shop a look over this week? ^^;

AndromedaKerova
04-25-2015, 09:43 PM
I'm wondering how to implement this because I have the shop listing mod and obviously, that modifies the display section already.

kristhasirah
04-25-2015, 11:26 PM
I have both mods installed and i dont have problems, also i think that the shop listing mod only affects how you see the shops but not how you see the items in the shop... Not sure about that as i installed first this mod and after that the shop listing mod.

Kyttias
04-26-2015, 12:22 AM
I'm wondering how to implement this because I have the shop listing mod and obviously, that modifies the display section already.

The foreach loop you're supposed to put inside the if statement from the other mod still exists. Just wrap it and, once again, be sure to close it. It's probably very confusing to a beginner how to find where something ends, and how to keep track of that... If you don't already have a text editor meant for code, one that has syntax highlighting and auto-indentation, you should probably get one. Notepad++ is free. (http://notepad-plus-plus.org/)

Ittermat
02-05-2016, 02:40 PM
I know this is probably a noob question- but exactly from where to where does the code go in Itemshop.php?

I keep getting syntax errors because I think im putting it in the wrong area...x.x

tahbikat
02-05-2016, 03:58 PM
@Ittermat In class_itemshop.php, you basically replace the whole public function display section. Clicking the first opening bracket next to 'public function display' should also highlight the closing bracket. So you take everything inside that, erase it, and replace with new code. Make sure to save your original code first.

Ittermat
02-05-2016, 03:59 PM
Okay so...Can we make this a bit easier?

We start at public display- and end at? where? XD

Kyttias
02-05-2016, 05:53 PM
End at the end of the display function. Brackets always line up. You'll have to see where that function ends. In a text editor meant for code, such as Sublime Text 2 or Notepad++, syntax highlighting will help you recognize where code ends and begins, and as Tahbikat said, if you click on a bracket, the closing bracket will highlight itself, showing where it ends.

Anyway, obviously one function must end before the next begins. Just look for the start of the next one?

Ittermat
02-05-2016, 06:08 PM
ohhh!! OKAY! See I didnt know that small bit of info... actually that will help alot and puts a main puzzle piece in place! thank you!

Corsair
02-14-2016, 11:35 AM
For some reason tool tips will not work (in shop or inventory) even after following all the steps. I'm not sure if it's because I'm using the bookstore theme. I double checked the tootip.css, tooltip.js and the header file.

Kyttias
02-14-2016, 12:04 PM
Does that theme have jQuery? If not, include a link to the jQuery library. For the tooltips to work, its .js file must come after jQuery, as it is dependant on it. Keep in mind that this may break your profile pages since they come with their own link to jQuery and having two links to different versions will cause errors on that page!

This should have been covered in section 2, in the third code block.

Corsair
02-14-2016, 03:24 PM
I did follow that part as well but no luck. So I thought i'd ask just in case. I'm going to go over it a third time to see if I missed something.

Corsair
02-15-2016, 12:31 AM
Unrelated to my last post but I'm having a issue with key items being able to be sold in the inventory.

I saw:
if($item->category !== "Key Items") {

So I assumed if the category was "Key Items" that would fix it but I got a error.
Catchable fatal error: Argument 1 passed to GUIContainer::add() must be an instance of GUIComponent, null given, called in /home/monstari/public_html/view/inventoryview.php on line 72 and defined in /home/monstari/public_html/classes/class_guicontainer.php on line 361

I tried to I tried to figure it out but I am stumped. I am not to far along my php studies so maybe the fix is right in front of my face but I can't see it.

Kyttias
02-15-2016, 04:31 AM
About the Inventory - you're absolutely right, although... I was going off of existing code in class_itemtablehelper.php, which used if($item->category == "Key Items") return "N/A"; . . . . obviously, yeah, that'd only take effect if the item's category was "Key Items".

It'd probably be better to check for $item->function.

I updated the chunk of code above, but also here - public function index(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
$document->setTitle($mysidia->lang->inventory);

$inventory = $this->getField("inventory");

$document->add(new Comment(" <style>
.sc_item {
display: inline-table;
padding: 5px;
text-align: center;
font-family: 'Trebuchet MS', Helvetica, sans-serif;
font-size: 14px;
margin-bottom: 3px;
width: 120px;
}
.s_panel {
border-radius: 2px;
border: 1px solid #CCC;
background-color: #FBFDF2;
}
</style> ", FALSE));
$iids = $inventory->getiids();
for($i = 0; $i < $iids->length(); $i++){
$item = $inventory->getitem($iids[$i]);

# Descriptions of the item functions
switch ($item->function) {
case "Click1": $usage = "<br/><b>use:</b> Feed a pet to give them {$item->value} EXP."; break;
case "Click2": $usage = "<br/><b>use:</b> Feed a pet to set their EXP to {$item->value}."; break;
case "Click3": $usage = "<br/><b>use:</b> Resets EXP earned today to 0."; break;
case "Level1": $usage = "<br/><b>use:</b> Raises the Level of your pet by {$item->value}."; break;
case "Level2": $usage = "<br/><b>use:</b> Sets the Level of your pet to {$item->value}."; break;
case "Level3": $usage = "<br/><b>use:</b> Makes your pet Level 0 again!"; break;
case "Gender": $usage = "<br/><b>use:</b> Swaps the gender of your pet to its opposite!"; break;
default;
$usage = ""; break;
} # End item function descriptions


# Rendering items now
$document->add(new Comment("
<div class=\"s_panel sc_item\">
<img rel=\"tooltip\" title=\"{$item->description} <em>{$usage}</em>\" src=\"{$item->imageurl}\"/><br/>
<b>{$item->itemname}</b><br> Own &times;{$item->quantity}<br/>", FALSE));

# If item is consumable, add use button
if($item->consumable == "yes") {
$useForm = new FormBuilder("useform", "inventory/uses", "post");
$useForm->setLineBreak(FALSE);
$useForm->buildPasswordField("hidden", "action", "uses")
->buildPasswordField("hidden", "itemname", $item->itemname)
->buildButton("Use", "use", "use");
$document->add($useForm);
}

# Add sellback button so long as the item is not a key item
$sellback = $item->price / 2;
$document->add(new Comment("<hr>{$sellback} {$mysidia->settings->cost} Each ", FALSE));
if($item->function !== "Key") {
$sellForm = new FormBuilder("sellform", "inventory/sell", "post");
$sellForm->setLineBreak(FALSE);
$sellForm->buildPasswordField("hidden", "action", "sell")
->buildPasswordField("hidden", "itemname", $item->itemname);

$quantity = new TextField("quantity");
$quantity->setSize(3);
$quantity->setMaxLength(3);
$quantity->setLineBreak(FALSE);

$sell = new Button("Sell", "sell", "sell");
$sell->setLineBreak(FALSE);

$sellForm->add($quantity);
$sellForm->add($sell);
}
$document->add($sellForm);
$document->add(new Comment("</div>", FALSE));

} # END item for loop

} # END index function

If the problem persists, perhaps try changing it to "!=" instead of "!==".

Anyway, do the tooltips work on the Inventory, but not elsewhere? Do any of your item names or descriptions happen to have apostrophes or quotations in them (this might be relevant and would be good to know, I thought I'd caught all of this).

Corsair
02-15-2016, 10:11 AM
I seem to be getting the same error even after changing the !== to !=

Catchable fatal error: Argument 1 passed to GUIContainer::add() must be an instance of GUIComponent, null given, called in /home/monstari/public_html/view/inventoryview.php on line 72 and defined in /home/monstari/public_html/classes/class_guicontainer.php on line 361

As for tooltips they do show up in both shops and the inventory but as plan boxes. I did move the CSS to the main theme but I don't think that's it either.

http://orig05.deviantart.net/c6e0/f/2016/046/a/4/02334_by_grand_corsair-d9ruuyf.png

I'm not sure if it's related but I've been noticing errors with drop downs and radio buttons related to this GUIContainer even in the admin panel where I have your bootstrap theme installed.

Kyttias
02-15-2016, 11:46 AM
Themes don't even modify core files, so I don't see how the two are related.

Please paste your entire inventoryview.php file. And, if you can, please link me to the site so I can see the problem first hand and confirm you have jQuery installed once and only once and in the correct location. I hope we get this figured out. ^^;

Corsair
02-15-2016, 12:01 PM
Thanks for being so penitent. I am still trying to get a handle on this php thing.

http://monstari.mysidiahost.com/index
<?php

use Resource\Collection\LinkedList;

class InventoryView extends View{

public function index(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
$document->setTitle($mysidia->lang->inventory);
$document->addLangvar("You may manage these items as you like, or go to the alchemy page to make your own items: <br>");
$document->add(new Link("inventory/alchemy", "Go to Alchemy Laboratory!"));
$document->add(new Comment("<br><br>"));

$inventory = $this->getField("inventory");


$iids = $inventory->getiids();
for($i = 0; $i < $iids->length(); $i++){
$item = $inventory->getitem($iids[$i]);

# Descriptions of the item functions
switch ($item->function) {
case "Click1": $usage = "<br/><b>use:</b> Feed a pet to give them {$item->value} EXP."; break;
case "Click2": $usage = "<br/><b>use:</b> Feed a pet to set their EXP to {$item->value}."; break;
case "Click3": $usage = "<br/><b>use:</b> Resets EXP earned today to 0."; break;
case "Level1": $usage = "<br/><b>use:</b> Raises the Level of your pet by {$item->value}."; break;
case "Level2": $usage = "<br/><b>use:</b> Sets the Level of your pet to {$item->value}."; break;
case "Level3": $usage = "<br/><b>use:</b> Makes your pet Level 0 again!"; break;
case "Gender": $usage = "<br/><b>use:</b> Swaps the gender of your pet to its opposite!"; break;
default;
$usage = ""; break;
} # End item function descriptions


# Rendering items now
$document->add(new Comment("
<div class=\"s_panel sc_item\">
<img rel=\"tooltip\" title=\"{$item->description} <em>{$usage}</em>\" src=\"{$item->imageurl}\"/><br/>
<b>{$item->itemname}</b><br> Own &times;{$item->quantity}<br/>", FALSE));

# If item is consumable, add use button
if($item->consumable == "yes") {
$useForm = new FormBuilder("useform", "inventory/uses", "post");
$useForm->setLineBreak(FALSE);
$useForm->buildPasswordField("hidden", "action", "uses")
->buildPasswordField("hidden", "itemname", $item->itemname)
->buildButton("Use", "use", "use");
$document->add($useForm);
}

# Add sellback button so long as the item is not a key item
$sellback = $item->price / 2;
$document->add(new Comment("<hr>{$sellback} {$mysidia->settings->cost} Each ", FALSE));
if($item->function != "Key") {
$sellForm = new FormBuilder("sellform", "inventory/sell", "post");
$sellForm->setLineBreak(FALSE);
$sellForm->buildPasswordField("hidden", "action", "sell")
->buildPasswordField("hidden", "itemname", $item->itemname);

$quantity = new TextField("quantity");
$quantity->setSize(3);
$quantity->setMaxLength(3);
$quantity->setLineBreak(FALSE);

$sell = new Button("Sell", "sell", "sell");
$sell->setLineBreak(FALSE);

$sellForm->add($quantity);
$sellForm->add($sell);
}
$document->add($sellForm);
$document->add(new Comment("</div>", FALSE));

} # END item for loop

} # END index function

public function uses(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
if($mysidia->input->post("aid")){
$message = (string)$this->getField("message");
$document->setTitle($mysidia->lang->global_action_complete);
$document->addLangvar($message);
return;
}

$petMap = $this->getField("petMap");
$document->setTitle($mysidia->lang->select_title);
$document->addLangvar($mysidia->lang->select);
$chooseFrom = new Form("chooseform", "uses", "post");

$adoptable = new DropdownList("aid");
$adoptable->add(new Option("None Selected", "none"));
if($petMap->size() > 0){
$iterator = $petMap->iterator();
while($iterator->hasNext()){
$adopt = $iterator->nextEntry();
$adoptable->add(new Option($adopt->getValue(), $adopt->getKey()));
}
}
$chooseFrom->add($adoptable);

$chooseFrom->add(new PasswordField("hidden", "itemname", $mysidia->input->post("itemname")));
$chooseFrom->add(new PasswordField("hidden", "validation", "valid"));
$chooseFrom->add(new Button("Choose this Adopt", "submit", "submit"));
$document->add($chooseFrom);
}

public function sell(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
$document->setTitle($this->lang->global_transaction_complete);
$document->addLangvar("{$this->lang->sell}{$mysidia->input->post("quantity")} {$mysidia->input->post("itemname")} {$this->lang->sell2}");
}

public function toss(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
if($mysidia->input->get("confirm")){
$document->setTitle($this->lang->global_action_complete);
$document->addLangvar("{$this->lang->toss}{$mysidia->input->post("itemname")}{$this->lang->toss2}");
return;
}

$document->setTitle($this->lang->toss_confirm);
$document->addLangvar($this->lang->toss_warning);

$confirmForm = new FormBuilder("confirmform", "toss/confirm", "post");
$confirmForm->buildPasswordField("hidden", "action", "toss")
->buildPasswordField("hidden", "itemname", $mysidia->input->post("itemname"))
->buildButton("Please Toss", "confirm", "confirm");
$document->add($confirmForm);
}
public function alchemy(){
$mysidia = Registry::get("mysidia");
$document = $this->document;

if($mysidia->input->post("iid") and $mysidia->input->post("iid2")){
$alchemy = $this->getField("alchemy");
$newitem = $alchemy->getNewItem()->itemname;
$document->setTitle($this->lang->alchemy_success);
$document->addLangvar($this->lang->alchemy_newitem.$newitem.$this->lang->alchemy_newitem2);
return;
}

$document->setTitle($this->lang->alchemy_title);
$document->addLangvar($this->lang->alchemy);
$itemMap = $this->getField("itemMap");
$settings = $this->getField("settings");
$alchemyFrom = new Form("alchemyform", "alchemy", "post");
$alchemyFrom->add(new Comment("<b>Cost of performing Alchemy: {$settings->cost} {$mysidia->settings->cost}</b><br>"));

$alchemyFrom->add(new Comment($mysidia->lang->alchemy_choose));
$items = new DropdownList("iid");
$items->add(new Option("None Selected", "none"));
if($itemMap->size() > 0){
$iterator = $itemMap->iterator();
while($iterator->hasNext()){
$item = $iterator->nextEntry();
$items->add(new Option($item->getValue(), $item->getKey()));
}
}
$alchemyFrom->add($items);

$alchemyFrom->add(new Comment($mysidia->lang->alchemy_choose2));
$items2 = new DropdownList("iid2");
$items2->add(new Option("None Selected", "none"));
if($itemMap->size() > 0){
$iterator = $itemMap->iterator();
while($iterator->hasNext()){
$item2 = $iterator->nextEntry();
$items2->add(new Option($item2->getValue(), $item2->getKey()));
}
}
$alchemyFrom->add($items2);
$alchemyFrom->add(new Button("Let's mix the items now!", "submit", "submit"));
$document->add($alchemyFrom);
}
}
?>

Kyttias
02-15-2016, 12:17 PM
Mkay, I copy-pasted in your exact file and I have no errors at all? There is no reason you should be having an error on line 72 and not much sooner. Do you have the error without the Alchemy mod installed (I've never used it)? I doubt it would interfere, but it's worth checking...

Can you try moving

<!-- Scripts -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="/js/tooltip.js"></script>
<script src="/js/tabs.js"></script>
<script>
$(function() { $("#profile").organicTabs(); });
</script>
<!-- Script end -->
into your header instead of your footer for me? Have you tried this yet? Does it make a difference for the tooltips?

Corsair
02-15-2016, 01:10 PM
Ok so weird thing. I removed everything and can still sell key items so even if I removed your mod I still can sell key items. whelp

Edit:

Ok so I did a fresh install and followed the installation. Installed this mod and got the same error.

Kyttias
02-15-2016, 07:18 PM
It's quite bizarre that two other people have this mod installed on their site, other than myself, just fine and never experienced fatal errors. Yet, no matter how much I search, I can't find any helpful reference to a similar error that they would have fixed elsewhere. My classes/class_guicontainer.php and classes/class_guicomponent.php files identical to the default install!

EDIT: I can actually recreate your error... if you followed the instructions wrong, you replaced your entire view/inventoryview.php file instead of replacing only the index() function as instructed. Try replacing your entire file with this (or go back and follow the instructions more carefully):
<?php

use Resource\Collection\LinkedList;

class InventoryView extends View{

public function index(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
$document->setTitle($mysidia->lang->inventory);

$inventory = $this->getField("inventory");

$document->add(new Comment(" <style>
.sc_item {
display: inline-table;
padding: 5px;
text-align: center;
font-family: 'Trebuchet MS', Helvetica, sans-serif;
font-size: 14px;
margin-bottom: 3px;
width: 120px;
}
.s_panel {
border-radius: 2px;
border: 1px solid #CCC;
background-color: #FBFDF2;
}
</style> ", FALSE));
$iids = $inventory->getiids();
for($i = 0; $i < $iids->length(); $i++){
$item = $inventory->getitem($iids[$i]);

# Descriptions of the item functions
switch ($item->function) {
case "Click1": $usage = "<br/><b>use:</b> Feed a pet to give them {$item->value} EXP."; break;
case "Click2": $usage = "<br/><b>use:</b> Feed a pet to set their EXP to {$item->value}."; break;
case "Click3": $usage = "<br/><b>use:</b> Resets EXP earned today to 0."; break;
case "Level1": $usage = "<br/><b>use:</b> Raises the Level of your pet by {$item->value}."; break;
case "Level2": $usage = "<br/><b>use:</b> Sets the Level of your pet to {$item->value}."; break;
case "Level3": $usage = "<br/><b>use:</b> Makes your pet Level 0 again!"; break;
case "Gender": $usage = "<br/><b>use:</b> Swaps the gender of your pet to its opposite!"; break;
default;
$usage = ""; break;
} # End item function descriptions


# Rendering items now
$document->add(new Comment("
<div class=\"s_panel sc_item\">
<img rel=\"tooltip\" title=\"{$item->description} <em>{$usage}</em>\" src=\"{$item->imageurl}\"/><br/>
<b>{$item->itemname}</b><br> Own &times;{$item->quantity}<br/>", FALSE));

# If item is consumable, add use button
if($item->consumable == "yes") {
$useForm = new FormBuilder("useform", "inventory/uses", "post");
$useForm->setLineBreak(FALSE);
$useForm->buildPasswordField("hidden", "action", "uses")
->buildPasswordField("hidden", "itemname", $item->itemname)
->buildButton("Use", "use", "use");
$document->add($useForm);
}

# Add sellback button so long as the item is not a key item
$sellback = $item->price / 2;
$document->add(new Comment("<hr>{$sellback} {$mysidia->settings->cost} Each ", FALSE));
if($item->category != "Key Items") {
$sellForm = new FormBuilder("sellform", "inventory/sell", "post");
$sellForm->setLineBreak(FALSE);
$sellForm->buildPasswordField("hidden", "action", "sell")
->buildPasswordField("hidden", "itemname", $item->itemname);

$quantity = new TextField("quantity");
$quantity->setSize(3);
$quantity->setMaxLength(3);
$quantity->setLineBreak(FALSE);

$sell = new Button("Sell", "sell", "sell");
$sell->setLineBreak(FALSE);

$sellForm->add($quantity);
$sellForm->add($sell);
$document->add($sellForm);
}

$document->add(new Comment("</div>", FALSE));

} # END item for loop

} # END index function

public function sell(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
$document->setTitle($this->lang->global_transaction_complete);
$document->addLangvar("{$this->lang->sell}{$mysidia->input->post("quantity")} {$mysidia->input->post("itemname")} {$this->lang->sell2}");
}

public function toss(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
if($mysidia->input->get("confirm")){
$document->setTitle($this->lang->global_action_complete);
$document->addLangvar("{$this->lang->toss}{$mysidia->input->post("itemname")}{$this->lang->toss2}");
return;
}

$document->setTitle($this->lang->toss_confirm);
$document->addLangvar($this->lang->toss_warning);

$confirmForm = new FormBuilder("confirmform", "toss/confirm", "post");
$confirmForm->buildPasswordField("hidden", "action", "toss")
->buildPasswordField("hidden", "itemname", $mysidia->input->post("itemname"))
->buildButton("Please Toss", "confirm", "confirm");
$document->add($confirmForm);
}
}
?>

Anyway, yeah, the Key item thing seems to be a bug or afterthought with the baseline Mysidia framework... by the sounds of it. In classes/class_itemtablehelper.php, the category "Key Items" is referenced twice, rather than the function "Key". I literally just imitated the existing file to render the form, so I copied over the same error.

However, if I do create an item with the category "Key Items" on a default install, it renders as expected on a default install of Mysidia (you can never sell key items). I cannot actually recreate your problem on a default install whatsoever.

http://orig00.deviantart.net/cd6b/f/2016/046/c/5/defaultkeyitem_by_kyttias-d9rx8qh.png

So, this DOES come down to being a bug with my mod, AND I managed to fix it. The fix is in the file above. (I moved $document->add($sellForm); inside the if statement, because that makes more sense, anyway. The variable should have still never been built to display, anyway... but apparently it was?)

Corsair
02-15-2016, 07:38 PM
I'm not sure either. I installed a fresh new install and before adding anything I tested it and it came up a error. I installed it as the guide said. Other then that everything else with the mode is working. Until I can figure this out I'll have to warn people not to sell their key items.

As for tooltips they are working now. I'm not sure what happened but that much is cleared up. I must have installed something that broke it.

Kyttias
02-15-2016, 07:46 PM
I made some edits to my last post that should clear everything up. I'm glad the tooltips are working!

edit: And made one last edit to my previous post @ 8:53 EST. Thanks for catching the Key Item thing, it apparently was my fault! I hadn't created a Key Item yet to test, and all I had to do was move one line only slightly. ^^;;;

Corsair
02-15-2016, 08:09 PM
I can't thank you enough. I need to make sure to install mods more carefully. Everything seems to be working now.

Kyttias
02-15-2016, 09:12 PM
I'm glad everything got sorted out. :usedusedused: Maybe it'll help someone in the future!

SilverDragonTears
03-10-2016, 02:03 AM
i cant see the NPC part on my site.

Ittermat
03-18-2016, 12:39 PM
hey maybe you can help me..Im trying to use this mod- but everytime I try I keep getting errors... Im putting everything in as you say to...but it still wont work...Im not sure whats wrong.. maybe you can help?

this is my Itemshop.php code.

<?php

use Resource\Collection\LinkedList;

class Itemshop extends Model{

public $sid;
public $category;
public $shopname;
public $shoptype;
public $description;
public $imageurl;
public $status;
public $restriction;
public $salestax;
public $items;
protected $total = 0;

public function __construct($shopname){
// Fetch the database info into object property
$mysidia = Registry::get("mysidia");
$row = $mysidia->db->select("shops", array(), "shopname ='{$shopname}'")->fetchObject();
if(!is_object($row)) throw new Exception("Invalid Shopname specified");

// loop through the anonymous object created to assign properties
foreach($row as $key => $val){
$this->$key = $val;
}
$this->items = $this->getitemnames();
$this->total = (is_array($this->items))?count($this->items):0;
}

public function getcategory(){
$mysidia = Registry::get("mysidia");
$stmt = $mysidia->db->select("shops", array(), "category ='{$this->category}'");
$cate_exist = ($row = $stmt->fetchObject())?TRUE:FALSE;
return $cate_exist;
}

public function getshop(){
$mysidia = Registry::get("mysidia");
if(empty($this->shopname)) $shop_exist = FALSE;
else{
$stmt = $mysidia->db->select("shops", array(), "shopname ='{$this->shopname}'");
$shop_exist = ($row = $stmt->fetchObject())?TRUE:FALSE;
}
return $shop_exist;
}

public function getitemnames(){
if(!$this->items){
$mysidia = Registry::get("mysidia");
$stmt = $mysidia->db->select("items", array("itemname"), "shop ='{$this->shopname}'");
$items = array();

while($item = $stmt->fetchColumn()){
$items[] = $item;
}
return $items;
}
else return $this->items;
}

public function gettotal(){
return $this->total;
}
public function display(){
$mysidia = Registry::get("mysidia");
$document = $mysidia->frame->getDocument();
$document->addLangvar($mysidia->lang->select_item);

if($this->gettotal() == 0){
$document->addLangvar($mysidia->lang->empty);
return FALSE;
}

# Choose the NPC image based on the name of the shop
switch ($this->shopname) {
case "Bookstore":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/646f59544e20a3ba433292c85fa7cd68.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Arent books wonderful??"; break;
case 2: $npc_text = "Nothing like traveling to a whole new world with a book!"; break;
case 3: $npc_text = "Welcome to {$this->shopname}!"; break;
case 4: $npc_text = "Off to see the wizard?"; break;
case 5: $npc_text = "Once I was covered in books, and I thought I was in heaven!"; break;
case 6: $npc_text = "Promise you'll tell me how it ends!!"; }
break;
case "Caratrises candy":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/2d0485231a263b02740ce1ea57b926d1.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "All candy is made by me!"; break;
case 2: $npc_text = "Cavities Guaranteed!"; break;
case 3: $npc_text = "Welcome to {$this->shopname}!"; break;
case 4: $npc_text = "Okay...but im not going to pay for your dental bills."; break;
case 5: $npc_text = "If you come back on a holiday I'll have special candy for you!"; break;
case 6: $npc_text = "I wont tell if you dont tell."; }
break;
case "Catari Necessities":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/fc29ee5d45ec433a1faf8fc9ff75c408.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "My favorite toy is the Teaser!"; break;
case 2: $npc_text = "Dont forget to get your Catari some treats!"; break;
case 3: $npc_text = "Welcome to {$this->shopname}!"; break;
case 4: $npc_text = "You're right! I should stock some live mice."; break;
case 5: $npc_text = "Catari are pretty easy to please"; break;
case 6: $npc_text = "Have you been to the Shrine yet? If so Tell Eyre I said hi!"; }
break;

case "Catfucious stall":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/36a5e23916c437d13755cef4e28a95ee.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Please browse as long as you need my child."; break;
case 2: $npc_text = "The first step to tranquility is not paying attention to anyone but yourself."; break;
case 3: $npc_text = "I am not here to make money my child..I am here to spread love."; break;
case 4: $npc_text = "I hope that I can help you improve your life"; break;
case 5: $npc_text = "Dont ask for too much...only want what is needed"; break;
case 6: $npc_text = "There is more to life than money...Happiness is golden"; }
break;

case "Delilahs drinks":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/24e509b16d94ee2becfa134eb335cbac.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Hi there Sweetie! I make everything myself!"; break;
case 2: $npc_text = "I'll sell holiday exclusive items, so please check back during a holiday!"; break;
case 3: $npc_text = "All you need is love!"; break;
case 4: $npc_text = "You're so adorable! Thank you for coming in!"; break;
case 5: $npc_text = "Even if I dont have something you want now- I might later!"; break;
case 6: $npc_text = "Yes, Habibi is my Brother...why do you ask?"; }
break;


case "Eyres treasury":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/a01f278da98365994ea4c1dd4e0d8212.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Im not giving my things up that easily..."; break;
case 2: $npc_text = "You know if you arent going to buy anything? you can go away..."; break;
case 3: $npc_text = "I am NOT Cute"; break;
case 4: $npc_text = "............."; break;
case 5: $npc_text = "I dont do trades...I want cold hard cash!"; break;
case 6: $npc_text = "Havent you left yet?"; }
break;

case "Feesh Fundamentals":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/9a50351b442506040eac15e7bf0589aa.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Blub blub...blub,,"; break;
case 2: $npc_text = "Blub..."; break;
case 3: $npc_text = "Blubb blub,,,"; break;
case 4: $npc_text = "............."; break;
case 5: $npc_text = "Blub..."; break;
case 6: $npc_text = "*sound of bubbles* "; }
break;

case "Glidera Goodies":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/1f3616733a28da078a709e93f3a2914a.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Glidera are wonderfully loyal pets!"; break;
case 2: $npc_text = "Cinnamon here has been with me for a really long time!"; break;
case 3: $npc_text = "Welcome to {$this->shopname}!; break;
case 4: $npc_text = "Have you tried giving your Glidera a mealworm yet?"; break;
case 5: $npc_text = "I hope you find everything you're looking for"; break;
case 6: $npc_text = "If you need help just let me know! "; }
break;

case "Habibis Holiday":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/5f47dde45fffa266ba4b26594034bc4a.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "I love holidays.."; break;
case 2: $npc_text = "I hope you're having a good time.."; break;
case 3: $npc_text = "Welcome to {$this->shopname}!; break;
case 4: $npc_text = "Its a lovely day isnt it?"; break;
case 5: $npc_text = "I hope you find everything you're looking for"; break;
case 6: $npc_text = "If you need help just let me know! "; }
break;

case "Hounda essentials":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/7e50a54e67ea07f33274ddbd55f4c681.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "I love Toys!"; break;
case 2: $npc_text = "I hope you're having a good time.."; break;
case 3: $npc_text = "Welcome to {$this->shopname}!; break;
case 4: $npc_text = "Please dont throw the ball...I need to stay behind the counter!"; break;
case 5: $npc_text = "I hope you find everything you're looking for"; break;
case 6: $npc_text = "If you need help just let me know! "; }
break;

case "Supermarket":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/5306b4da3d1c288c80f4ff1709e3580a.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Yea...what you're looking for is around here somewhere..."; break;
case 2: $npc_text = "Thats nice....."; break;
case 3: $npc_text = "Welcome to the {$this->shopname}...; break;
case 4: $npc_text = "With this price gun, I am invincible..."; break;
case 5: $npc_text = "I hope you find everything you're looking for...I guess.."; break;
case 6: $npc_text = "If you need help just let me know..or dont, because I dont care..."; }
break;

case "Camerons toys":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/29ebda897900480c07a5e1a9bc1c1994.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Hewwo!.."; break;
case 2: $npc_text = "Mummy says Im the bestest at selling toys!....."; break;
case 3: $npc_text = "Welcome to {$this->shopname}!; break;
case 4: $npc_text = "Can we be Fwiends?..."; break;
case 5: $npc_text = "If you need help, tell me!!.."; break;
case 6: $npc_text = "Pwease come back again!..."; }
break;

case "Caseys Crafts":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/bef6477cc0e7308db3ea9a88f841c956.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Hello! What are you going to make today?"; break;
case 2: $npc_text = "My son Cameron is next door!"; break;
case 3: $npc_text = "Welcome to {$this->shopname}!; break;
case 4: $npc_text = "I cant wait to see what you make!"; break;
case 5: $npc_text = "If you need help, Just let me know!!"; break;
case 6: $npc_text = "Please come back again!"; }
break;


case "Pet paints":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/e053750b18df3ab752793c365bfd61ec.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Hello! We have a bunch of cool colors!"; break;
case 2: $npc_text = "When im not here, I'm usually painting!"; break;
case 3: $npc_text = "Welcome to {$this->shopname}!; break;
case 4: $npc_text = "I cant wait to see your new pet!"; break;
case 5: $npc_text = "If you need help, Just let me know!!"; break;
case 6: $npc_text = "Please come back again!"; }
break;

case "Premium pet paints":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/e053750b18df3ab752793c365bfd61ec.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Hello! We have a bunch of cool colors!"; break;
case 2: $npc_text = "These Paints are only for the specialist of members!!"; break;
case 3: $npc_text = "Welcome to {$this->shopname}!; break;
case 4: $npc_text = "I cant wait to see your new pet!"; break;
case 5: $npc_text = "If you need help, Just let me know!!"; break;
case 6: $npc_text = "Please come back again!"; }
break;

case "Potters Potions":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/6bdb9f184918c39f01114ca8736331eb.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "Oh wait....those two things arent supposed to be mixed..."; break;
case 2: $npc_text = "I make everything here myself."; break;
case 3: $npc_text = "Welcome to {$this->shopname}!; break;
case 4: $npc_text = "Dont be alarmed...its only smoke."; break;
case 5: $npc_text = "If you need help, Just let me know.."; break;
case 6: $npc_text = "Please come back again!"; }
break;

case "Account upgrades":
$npc_img = "http://atrocity.mysidiahost.com/picuploads/png/1dd6406902d48dafb229ca6d74ed3365.png";
#Based on the random number, sets a quote for $npc_text
$num = Rand (1,6);
switch ($num) {
case 1: $npc_text = "If you want to change something on your account this is the place to go!."; break;
case 2: $npc_text = "Only premium members can be here!."; break;
case 3: $npc_text = "Welcome to {$this->shopname}!; break;
case 4: $npc_text = "I know we dont have much...."; break;
case 5: $npc_text = "If you need help, Just let me know.."; break;
case 6: $npc_text = "Please come back again!"; }
break;
default;
$npc_img = "http://placekitten.com/g/200/500";
$npc_text = "Welcome to {$this->shopname}!";
break;
}

# let's begin rendering the page
$document->add(new Comment("
<style>
.s_top {
overflow:hidden;
display: block;
}
.sc_npc_text{
width: 300px;
float: left;
position: relative;
height: 70px;
padding: 15px;
margin: 10px;
margin-top: 180px;
font-family: 'Trebuchet MS', Helvetica, sans-serif;
overflow: auto;
}
.sc_npc_img{
width: 40%;
float: left;
}

.sc_item {
display: inline-table;
padding: 5px;
text-align: center;
font-family: 'Trebuchet MS', Helvetica, sans-serif;
font-size: 14px;
margin-bottom: 3px;
}
.s_panel {
border-radius: 2px;
border: 1px solid #CCC;
background-color: #FBFDF2;
}
</style>
<!-- START Container for Text and NPC -->
<div class='s_top s_container'>
<div class='s_panel sc_npc_text'>{$npc_text}</div>
<div class='sc_npc_img'><img src='{$npc_img}' height='300'></div>
</div>
<!-- END Container for Text and NPC -->
<!-- START Container for Items -->
<div class='s_container'>
", FALSE));

# Now render each item the store has
foreach($this->items as $stockitem){
$item = $this->getitem($stockitem);

#descriptions of the item functions
switch ($item->function) {
case "Click1": $usage = "<br/><b>use:</b> Feed a pet to give them {$item->value} EXP."; break;
case "Click2": $usage = "<br/><b>use:</b> Feed a pet to set their EXP to {$item->value}."; break;
case "Click3": $usage = "<br/><b>use:</b> Resets EXP earned today to 0."; break;
case "Level1": $usage = "<br/><b>use:</b> Raises the Level of your pet by {$item->value}."; break;
case "Level2": $usage = "<br/><b>use:</b> Sets the Level of your pet to {$item->value}."; break;
case "Level3": $usage = "<br/><b>use:</b> Makes your pet Level 0 again!"; break;
case "Gender": $usage = "<br/><b>use:</b> Swaps the gender of your pet to its opposite!"; break;
default;
$usage = "";
break;
}

# Now let's render each item icon, name, price and tooltip
$document->add(new Comment("
<div class=\"s_panel sc_item\">
<img rel=\"tooltip\" title=\"{$item->description} <em>{$usage}</em>\" src=\"{$item->imageurl}\"/><br/>
<b>{$item->itemname}</b>
<br/>
{$item->price} {$mysidia->settings->cost}<br/>
", FALSE));


# Building the Buy form
$buyForm = new FormBuilder("buyform", "../purchase/{$mysidia->input->get("shop")}", "post");
$buyForm->setLineBreak(FALSE);
$buyForm->buildPasswordField("hidden", "action", "purchase")
->buildPasswordField("hidden", "itemname", $item->itemname)
->buildPasswordField("hidden", "shopname", $shop->shopname)
->buildPasswordField("hidden", "shoptype", "itemshop")
->buildPasswordField("hidden", "salestax", $shop->salestax);
$quantity = new TextField("quantity", "1");
$quantity->setSize(3);
$quantity->setMaxLength(3);
$quantity->setLineBreak(FALSE);
$buy = new Button("Buy", "buy", "buy");
$buy->setLineBreak(FALSE);
$buyForm->add($quantity);
$buyForm->add($buy);

# Actually adding in the Quantity field Buy button now
$document->add($buyForm);

# Now we finish off the item by closing its div
$document->add(new Comment("</div>", FALSE));
}

# And that's a wrap
$document->add(new Comment("</div><!-- END Container for Items -->", FALSE));

} #END display function


public function getitem($itemname){
return new StockItem($itemname);
}

public function purchase(Item $item){
$mysidia = Registry::get("mysidia");
if($item->owner != $mysidia->user->username) Throw new NoPermissionException('Something is very very wrong, please contact an admin asap.');
else{
$item->quantity = $mysidia->input->post("quantity");
$cost = $item->getcost($this->salestax, $item->quantity);
$moneyleft = $mysidia->user->money - $cost;
if($moneyleft >= 0 and $item->quantity > 0){
$purchase = $item->append($item->quantity, $item->owner);
$mysidia->db->update("users", array("money" => $moneyleft), "username = '{$item->owner}'");
$status = TRUE;
}
else throw new InvalidActionException($mysidia->lang->money);
}
return $status;
}

public function rent($item, $period){

}

public function execute($action){

}

protected function save($field, $value){
$mysidia = Registry::get("mysidia");
$mysidia->db->update("shops", array($field => $value), "sid='{$this->sid}' and shoptype = 'adoptshop'");
}
}
?>

Please and thank you

Kyttias
03-18-2016, 01:41 PM
Looks like you've copy pasted your error into nearly every single shop. Make sure there is a closing " in case 3 of every shop. Specifically lines 176, 189, 202, 215, 228, 241, 255, 268, 281, and 294.

Please check out the free text editor Notepad++ (https://notepad-plus-plus.org/)! It comes with syntax highlighting meant for coding so it's EASY to spot syntax errors because the colors coded system of how it displays lines will jam up. Lines are also numbered.
http://orig03.deviantart.net/1a9c/f/2016/078/c/d/syntax_by_kyttias-d9vo4ly.png
All I literally had to do was copy paste your code into my text editor and the errors were all just sitting there, very easy to spot. Definitely look into getting a program to program in if you're going to be modding your site so heavily.

Ittermat
03-18-2016, 01:58 PM
thanks kyttias... stupid mistakes I know...but i dont see the mistakes since I dont get the coding...and i do have notepad ++ it just doesnt actually help me much XD (Again probably because of my lack of knowledge on the subject) Thanks though...now i know what the issue was.. XD

LUC1G07CH1
04-03-2016, 11:16 AM
Edit: Nevermind! I have writen the shop name wrong!

Ittermat
06-06-2016, 03:09 PM
How would I make it so the tooltips appear on a specific spot on the map where the hotspot is located? At the moment Im using them as Titles for buildings on an image map, but the tool tip appears at the top of the image- even though I have the Rel=tooltip and Title=building in the code for each one.

Suzanne
06-13-2016, 04:28 PM
Thank you for sharing this. Installed and works great.

If anyone knows how to use this on the adoption page and the my adopts page please share :-)

Thanks,
Suzanne

parayna
09-03-2016, 06:03 PM
Glad I found this again for installing.. XD Do you have plans to make a similar adopt shop? That would be awesome 0w0

Kyttias
09-05-2016, 01:32 PM
My retail job is eating a lot of my time. I'm not actually sure when I'll be around to work on stuff like this. :ti:

parayna
09-05-2016, 02:00 PM
Oh, that's totally fine ^_^ I think a job is definitely more important! XD

(Oh, and I dunno if anyone is interested but I started a new course at college and I'm doing IT and one of the parts we're doing is coding and we're doing PHP, server side scripting, CSS, HTML and Javascript! I'm so excited! I can actually learn stuff in an actual teaching environment! Why didn't I think of this before?! XD I didn't actually know that we were doing coding when I chose IT, I just like computers... XD Yeah, sorry XD)

ffsharriet
01-14-2017, 11:45 AM
I've seemed to have messed up the code.

It's saying:

Parse error: syntax error, unexpected '$document' (T_VARIABLE), expecting function (T_FUNCTION) in /home/equiland/public_html/view/inventoryview.php on line 34


Here is the code:

public function index(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
$document->setTitle($mysidia->lang->inventory);

$inventory = $this->getField("inventory");
$inventoryTable = new TableBuilder("inventory");
$inventoryTable->setAlign(new Align("center", "middle"));
$inventoryTable->buildHeaders("Image", "Category", "Name", "Description", "Quantity", "Use", "Sell", "Toss");
$inventoryTable->setHelper(new ItemTableHelper);

$iids = $inventory->getiids();
for($i = 0; $i < $iids->length(); $i++){
$item = $inventory->getitem($iids[$i]);
$cells = new LinkedList;
$cells->add(new TCell($inventory->getitemimage($item->imageurl)));
$cells->add(new TCell($item->category));
$cells->add(new TCell($item->itemname));
$cells->add(new TCell($item->description));
$cells->add(new TCell($item->quantity));
$cells->add(new TCell($inventoryTable->getHelper()->getUseForm($item)));
$cells->add(new TCell($inventoryTable->getHelper()->getSellForm($item)));
$cells->add(new TCell($inventoryTable->getHelper()->getTossForm($item)));
$inventoryTable->buildRow($cells);
}
$document->add($inventoryTable);
}
$document->add($inventoryTable);
}
public function uses(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
if($mysidia->input->post("aid")){
$message = (string)$this->getField("message");
$document->setTitle($mysidia->lang->global_action_complete);
$document->addLangvar($message);
return;
}

$petMap = $this->getField("petMap");
$document->setTitle($mysidia->lang->select_title);
$document->addLangvar($mysidia->lang->select);
$chooseFrom = new Form("chooseform", "uses", "post");

$adoptable = new DropdownList("aid");
$adoptable->add(new Option("None Selected", "none"));
if($petMap->size() > 0){
$iterator = $petMap->iterator();
while($iterator->hasNext()){
$adopt = $iterator->nextEntry();
$adoptable->add(new Option($adopt->getValue(), $adopt->getKey()));
}
}
$chooseFrom->add($adoptable);

$chooseFrom->add(new PasswordField("hidden", "itemname", $mysidia->input->post("itemname")));
$chooseFrom->add(new PasswordField("hidden", "validation", "valid"));
$chooseFrom->add(new Button("Choose this Adopt", "submit", "submit"));
$document->add($chooseFrom);
}

public function sell(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
$document->setTitle($this->lang->global_transaction_complete);
$document->addLangvar("{$this->lang->sell}{$mysidia->input->post("quantity")} {$mysidia->input->post("itemname")} {$this->lang->sell2}");
}

public function toss(){
$mysidia = Registry::get("mysidia");
$document = $this->document;
if($mysidia->input->get("confirm")){
$document->setTitle($this->lang->global_action_complete);
$document->addLangvar("{$this->lang->toss}{$mysidia->input->post("itemname")}{$this->lang->toss2}");
return;
}

$document->setTitle($this->lang->toss_confirm);
$document->addLangvar($this->lang->toss_warning);

$confirmForm = new FormBuilder("confirmform", "toss/confirm", "post");
$confirmForm->buildPasswordField("hidden", "action", "toss")
->buildPasswordField("hidden", "itemname", $mysidia->input->post("itemname"))
->buildButton("Please Toss", "confirm", "confirm");
$document->add($confirmForm);
}
}
?>

Dinocanid
01-14-2017, 12:03 PM
This part includes duplicate lines:
$document->add($inventoryTable);
}
$document->add($inventoryTable);
}

Change it to this:
$document->add($inventoryTable);
}

kingsofjuly
06-24-2018, 10:38 PM
Worked first pop, no hiccups - thanks so much!

csunberry
07-10-2019, 09:33 AM
I must be doing something wrong. This works with Bootstrap, but if I try using the Main template, it just gives me a 500 error. What might I be doing wrong?:veeee::hmmm: Am I putting the stuff for <head> in the wrong place somehow?

Micolai
06-17-2020, 11:41 PM
I'm using 1.3.4 and my script just doesn't like this bit of code:

# Rendering items now
$document->add(new Comment("
<div class="s_panel sc_item">
<img rel="tooltip" title="{$item->description} <em>{$usage}</em>" src="{$item->imageurl}"/><br/>
<b>{$item->itemname}</b><br> Own &times;{$item->quantity}<br/>", FALSE));

It's not liking anything that's closed inside of these <> and keeps saying it's a syntax error.

Kyttias
06-19-2020, 09:56 AM
It doesn't like that you have " inside your ". You're going to have to use ' instead on either the outside new Comment("") or all the content inside.

Micolai
06-19-2020, 11:21 AM
It doesn't like that you have " inside your ". You're going to have to use ' instead on either the outside new Comment("") or all the content inside.

Thank you I've got it all working now 😊