Need help with a plugin to show pictures on item menu

_Soysauce_

Villager
Member
Joined
Sep 12, 2018
Messages
19
Reaction score
5
First Language
English
Primarily Uses
RMMV
Hi everybody,

A close friend of mine is trying to work on a plugin to show images on screen when scrolling the key items in the key item menu.

He's relatively new to programming, and rather new at JavaScript - so he has taken as a reference this thread from 2018:

Where two users discuss how to make such a plugin work, unfortunately without leaving behind a clear solution.

Right now, though, the plugin just keeps crashing right away, giving "Cannot read property 'setImageName' of undefined".
Since he's kinda clueless, would someone more versatile help us by explaining what's stopping the plugin from working and maybe giving a general look into it to tell us if he's on a good track? The attached .js file is the plugin in the current, latest state (of not working).

Thanks a lot to whoever stops by!
 

Attachments

standardplayer

Keeper of Kitties
Veteran
Joined
Apr 6, 2016
Messages
683
Reaction score
3,319
First Language
English
Primarily Uses
N/A
Can you describe what you're trying to accomplish in detail?
The linked thread involved heavily re editing code, it's honestly if your friend wants to learn to ask specifics and make it from scratch.

I'm glad to help, I'm literally in the middle of making menus right now so it's fresh in my mind.
Be specific about what's needed to solve this

EDIT: Anyway, looking at the plugin file you provided, it all goes haywire because the menus activate when they're constructed, even before SceneMap finishes loading.

If you go to the line in your code below, and add the change indicated in the comment

JavaScript:
Window_ItemList.prototype.select = function(index)
    {
        if(!this.isOpenAndActive()) return //<-- add this
        Window_Selectable.prototype.select.call(this, index);
        this.refreshMyItemPicturesWindow(this.item());
    };
That will stop your game from crashing. You can then access the item menu, however it's currently just the 100x100 window.

FYI the code was crashing specifically because later, under the prototype of Window_SelectItem, the .item() method is returning nothing, because the menu isn't truly open and loaded.
 
Last edited:

_Soysauce_

Villager
Member
Joined
Sep 12, 2018
Messages
19
Reaction score
5
First Language
English
Primarily Uses
RMMV
Can you describe what you're trying to accomplish in detail?
The linked thread involved heavily re editing code, it's honestly if your friend wants to learn to ask specifics and make it from scratch.

I'm glad to help, I'm literally in the middle of making menus right now so it's fresh in my mind.
Be specific about what's needed to solve this
What we're trying to accomplish in the end is to have the key item menu show the list of items on the left side of the screen (which we already did - also yes, the key menu is the only menu we're using, that's intentional), and a picture on the right side corresponding to the selected item. The result would be a menu item where you can scroll through the items and the selected ones are shown next to the item's name, one by one.

^ Edited for clarity.
 
Last edited:

standardplayer

Keeper of Kitties
Veteran
Joined
Apr 6, 2016
Messages
683
Reaction score
3,319
First Language
English
Primarily Uses
N/A
What do you mean by a clean key item menu and clean image?
Also, the green and red blocks aren't very helpful lol, I don't understand any better with this.
Are there only one set of items/pictures at a time, or are they in a list?
What do you mean by item on the left side? The name? The amount?

Edit: Also, you're saying key items menu, but that's normally a sub portion of the vanilla item menu. With the current plugin setup, you've replaced the entire item menu, not just the key items. Is that intentional?
 
Last edited:

_Soysauce_

Villager
Member
Joined
Sep 12, 2018
Messages
19
Reaction score
5
First Language
English
Primarily Uses
RMMV
What do you mean by a clean key item menu and clean image?
Also, the green and red blocks aren't very helpful lol, I don't understand any better with this.
Are there only one set of items/pictures at a time, or are they in a list?
What do you mean by item on the left side? The name? The amount?

Edit: Also, you're saying key items menu, but that's normally a sub portion of the vanilla item menu. With the current plugin setup, you've replaced the entire item menu, not just the key items. Is that intentional?
So, we intentionally made the key item menu the only menu - the items are all listed in column and stay on the left side of the screen. So far we got it. What we're missing is that on the right side of the screen, a picture is supposed to be shown when an item is selected. Every picture is associated to an item, and the idea is that the player views a preview of what the item looks like when scrolling through the list.
 

standardplayer

Keeper of Kitties
Veteran
Joined
Apr 6, 2016
Messages
683
Reaction score
3,319
First Language
English
Primarily Uses
N/A
Well how is the picture being signaled? Is it in notetags?
I don't use the regular show picture functions, or the bitmap draw functions, I use the PIXI.Sprite constructors to show images.

So you have to have a way to associate an image file with each item. The easiest way is to provide the path in a notetag, or at least the file name.

To reserve an image as a PIXI Sprite, use the following
JavaScript:
let img = new PIXI.Sprite.fromImage('img/folder/file.png')
myItemWindow.addChild(img);
I see you're Window_Base for the item image window, that's fine, you could also look into Window_Selectable, although if I'm understanding how you're trying to show these, it's one at a time.

What I mean by asking if they're scrolled one by one, I mean are they in a list where you can see four or five at a time etc.
Or are they in a list where you can only see one item at a time?

But when the items are drawn, you should use the name of that item, or it's id to read the notetag associated with it.

Upon reading the notetag, you'll obtain the image path, and can use the method described in the code above to load the image. Then, you use the .addChild function of the window to add it.

When you're closing the menu, be sure to destroy any PIXI images.
JavaScript:
img.destroy(true, true); //Destroys image base texture in the cache

img = undefined; //Gets rid of reference to the PIXI.Sprite object



//To be sure the images are getting destroyed, you can check the base texture cache

PIXI.utils.BaseTextureCache['img/folder/file.png'] //The properties of the BaseTextureCache

//are the string names of the filepaths. If yours is in there, then the texture hasn't been destroyed.

PIXI.utils.BaseTextureCache['img/folder/file.png'].destroy(true
 

_Soysauce_

Villager
Member
Joined
Sep 12, 2018
Messages
19
Reaction score
5
First Language
English
Primarily Uses
RMMV
Thanks to your code snippets and general help, finally we managed to get a working plugin that properly displays pictures along items, and everything works perfectly fine.

Thanks again for your help!

I just have one last question about a matter that worries me - when the game will be encrypted, is the plugin going to work with the encrypted's pictures extention or not, since you seem to be calling them specifically as .pngs?
 

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
1,825
Reaction score
1,282
First Language
EN
Primarily Uses
RMMZ
WHO CALLS UPON TH - oh, it's you, hi! :kaohi:

Decryption is typically handled via RMMV's Bitmap class; while it's possible to do it manually, it might be a better idea to use one of RMMV's wrappers for PIXI.Sprite (e.g. Sprite, rpg_core.js) rather than referencing the PIXI stuff directly. Doing so would also automatically make use of the ImageManager (rpg_managers.js), which in turn automatically handles image reservation (caching); I think it also handles dereferencing and destruction of sprites on the previous scene, meaning you only have to worry about loading and assigning the image to the parent object. :kaothx:

Will take a look at it and @ you guys if/when I find an answer~ :kaopride:
 

standardplayer

Keeper of Kitties
Veteran
Joined
Apr 6, 2016
Messages
683
Reaction score
3,319
First Language
English
Primarily Uses
N/A
Ahh, ok that makes sense.
So to load up one the the RM class sprites @_Soysauce_ , you would need the bitmap of the image.
I just tested this, loading a bitmap.
First, get your image path.

let str = 'img/someFolder/myImage.png";

Next, use ImageManager.loadBitmap to return a bitmap with this image

let bmp = ImageManager.loadBitmap(str);

Finally create the RM sprite using your bitmap.

let spr = new Sprite(bmp);
SceneManager._scene.addChild(spr);


I'm still gonna wait and see what other stuff @caethyril comes back with, I had actually never though of encryption and decryption before with my PIXI Sprites

Thanks @caethyril XD

EDIT: I use my own image cache to get away the RM managers, its honestly all up to you.
I did however find this @Poryg tutorial on encryption that does cover what to do with encrypting/decrypting images.
Again, I didn't know the RM Sprite classes (for example) would function in the way @caethyril explained, so it's possible that is the better route.
 
Last edited:

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
1,825
Reaction score
1,282
First Language
EN
Primarily Uses
RMMZ
Yep, looks good! Also, the error in question was because Scene_Map (like many other scenes, actually) happens to feature an instance of Window_ItemList: it's used for the Select Item command. So to avoid that error you can do a check first to see if the window exists, or whether the scene has an appropriate constructor, something like that. :kaophew:

@_Soysauce_: here's my take on the basic structure, it seems to work for me but you'll probably want to edit/expand on it~
JavaScript:
/*:
 * @plugindesc Shows item pictures when browsing your inventory!
 * @author
 * @plugindesc Put a <name:text> icon on items to assign them a picture.
 * Replace "text" with the picture's name, e.g. "item1" for "item1.png".
 * All pictures are loaded from img/pictures.
 * 
 * @noteParam name
 * @noteRequire 1
 * @noteDir img/pictures/
 * @noteType file
 * @noteData items
 */
// ^ See Help > Documentation > [Exclude unused files] Plugin Configuration //

(function() {
'use strict';

// ===== (NEW) Window_ItemPictures ===== //

    /** @constructor */
    window.Window_ItemPictures = function() { this.initialize.apply(this, arguments); };

    Window_ItemPictures.prototype = Object.create(Window_Base.prototype);
    Window_ItemPictures.prototype.constructor = Window_ItemPictures;

    // Called on construction
    Window_ItemPictures.prototype.initialize = function(x, y) {
        var w = 100, h = 100;
        Window_Base.prototype.initialize.call(this, x, y, w, h);
        this._image = new Sprite();
        this.addChild(this._image);
    };

    // Update image bitmap appropriately
    Window_ItemPictures.prototype.refresh = function() {
        let bmp = new Bitmap();
        if (this._imageName) bmp = ImageManager.loadPicture(this._imageName);
        this._image.bitmap = bmp;
    };

    // Returns the value of the specified item's "name" notetag
    Window_ItemPictures.prototype.readTag = function(item) {
        if (item) {
            let tag = item.meta.name;
            if (tag && tag !== true) return tag.trim();
        }
        return '';
    };

    // Update image name
    Window_ItemPictures.prototype.setItem = function(item) {
        this._imageName = this.readTag(item);
        this.refresh();
    };

// ===== (ADD) Extensions for existing scenes and windows ===== //

    // Add new window to item scene (inventory)
    (function(alias) {
        Scene_Item.prototype.create = function() {
            alias.call(this);
            this._itemPicsWindow = new Window_ItemPictures();
            this.addWindow(this._itemPicsWindow);
            this._itemWindow._itemPicsWindow = this._itemPicsWindow;
        };
    })(Scene_Item.prototype.create);

    // Refresh item picture window when selected item changes
    (function(alias) {
        Window_ItemList.prototype.select = function(index) {
            alias.apply(this, arguments);
            this.refreshWindowItemPics(this.item());
        };
    })(Window_ItemList.prototype.select);

    // New method: update the associated item picture window
    Window_ItemList.prototype.refreshWindowItemPics = function(item) {
        if (this._itemPicsWindow) this._itemPicsWindow.setItem(item);
    };

})();
Since you mentioned being new to this, I included a bunch of comments and a little header section, too. :kaojoy:

@standardplayer: the decryption stuff can be seen in Bitmap._requestImage (rpg_core.js ~line 1667). The actual Decrypter class is further down in the same file, ~line 9173. Looks like it outputs a Data URI (image source) generated from the encrypted file? I'm not all that sure of the details. :kaoswt2:
 

_Soysauce_

Villager
Member
Joined
Sep 12, 2018
Messages
19
Reaction score
5
First Language
English
Primarily Uses
RMMV
Thanks @caethyril, your structure helps A LOT - now I see how everything is best laid down.

This code doesn't seem to show the first picture when opening the menu, but that's something we can look into and make it work on our own (especially considering I always have the first item on the first slot when opening the menu, in my specific case).

You've been very helpful, and I wonder if I can ask one last question - are notetags editable?
I'd like for the same item picture to change later on, and while I sometimes just made an entirely different item to do this trick, I wonder if I can easily edit the notetag so that it would load an updated picture of the "upgraded" item, while technically being the same one in the database.
 

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
1,825
Reaction score
1,282
First Language
EN
Primarily Uses
RMMZ
Great, happy to help! :kaojoy:

You've been very helpful, and I wonder if I can ask one last question - are notetags editable?
I'd like for the same item picture to change later on, and while I sometimes just made an entirely different item to do this trick, I wonder if I can easily edit the notetag so that it would load an updated picture of the "upgraded" item, while technically being the same one in the database.
Unfortunately notetags are part of the database, they're not included in save files. :kaoslp:

One option could be to include a method that lets you define "override" images for specific items. These overrides can then be saved along with the usual save data. A lazy way to do it would be to add a property to an existing object that gets saved, e.g. $gameSystem. In the plugin, try adding/changing a couple of parts:
JavaScript:
  // Add a property to Game_System when it gets initialised
  (function(alias) {
    Game_System.prototype.initialize = function() {
      alias.call(this);
      this._itemPics = [];  // array of picture name overrides
    };
  })(Game_System.prototype.initialize);

  Window_ItemPictures.prototype.readTag = function(item) {
    let sysName = $gameSystem._itemPics[item.id];  // check for replacement picture name
    if (sysName) return sysName;  // return that if it exists
    if (item) {  // the rest is the same as before
      let tag = item.meta.name;
      if (tag && tag !== true) return tag.trim();
    }
    return '';
  };
Then you could use a Script command mid-game to store a different image name, e.g.
JavaScript:
var itemId = 1;
var itemName = 'magicSword';
$gameSystem._itemPics[itemId] = itemName;
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

I started to paint again after it didn't fit my female character. (I really intend to draw women)

I was more focused on female characters than men.

Score Rundown for the demo I'm trying to get done before Halloween, Or around it. Ending is based on your score currently.
Oh goooood, why am putting so many skills into my game AAAAAAAAAAAA!

Forum statistics

Threads
103,160
Messages
997,713
Members
134,633
Latest member
NeoLightningProductions
Top