Calling a function in another plugin when it's not aliased

● ARCHIVED · READ-ONLY
Started by Shaz 11 posts View original ↗
  1. I've got two plugins that introduce some logic to the canPass function for events. Because Game_Event doesn't have its own canPass function, each plugin creates the function, and does a Game_CharacterBase.prototype.canPass.call(). Unfortunately this means, because I don't have a Game_Event.canPass to alias, that only the plugin at the bottom of the list is working - the Game_Event.canPass() function on the earlier plugin never gets called.

    Original function in rpg_objects.js:
    Code:
    Game_CharacterBase.prototype.canPass = function(x, y, d) {
        var x2 = $gameMap.roundXWithDirection(x, d);
        var y2 = $gameMap.roundYWithDirection(y, d);
        if (!$gameMap.isValid(x2, y2)) {
            return false;
        }
        if (this.isThrough() || this.isDebugThrough()) {
            return true;
        }
        if (!this.isMapPassable(x, y, d)) {
            return false;
        }
        if (this.isCollidedWithCharacters(x2, y2)) {
            return false;
        }
        return true;
    };

    Code from plugin 1 (to make the player move in sync with an event):
    Code:
        Game_Event.prototype.canPass = function(x, y, d) {
            return $gamePlayer.isSyncedWith(this._eventId) || this._playerSync || 
                Game_CharacterBase.prototype.canPass.call(this, x, y, d);
        };

    Code from plugin 2 (to make an event move only within a certain range):
    Code:
        Game_Event.prototype.canPass = function(x, y, d) {
            var x2 = $gameMap.roundXWithDirection(x, d);
            var y2 = $gameMap.roundYWithDirection(y, d);
            return Game_CharacterBase.prototype.canPass.call(this, x, y, d) &&
                x2 >= this._tlx && x2 <= this._brx && y2 >= this._tly && y2 <= this._bry;
        };

    I need a way for the plugins to call other versions of Game_Event.canPass, and if no other versions can be found, to THEN call Game_CharacterBase.canPass. Does anyone know how to do this?
  2. if i understand, try play with something like this

    PHP:
    Game_Event.prototype.canPass = Game_Event.prototype.canPass2 || Game_Event.prototype.canPass;
  3. Well, I have to say that the Game_Event class has the canPass method.
    Because of this:

    Code:
    Game_Event.prototype = Object.create(Game_Character.prototype);

    When the Game_Event class is created the Game_Character.prototype is parsed.
    The Game_Character class is created from the Game_CharacterBase that have the canPass method.

    This means that if you type in your console the Game_Event.prototype.canPass you can see that it's the same of the Game_CharacterBase.prototype.canPass.
    The canPass method exists in the Game_Event class, because the Game_Event class extends the Game_Character one that extends the Game_CharacterBase class.

    So, you can use without any problem the alias trick:

    Code:
    var alias = Game_Event.prototype.canPass
    Game_Event.prototype.canPass = function(x, y, d) {
            return $gamePlayer.isSyncedWith(this._eventId) || this._playerSync ||
                alias.call(this, x, y, d);
        };

    Code:
     var alias = Game_Event.prototype.canPass
    Game_Event.prototype.canPass = function(x, y, d) {
            var x2 = $gameMap.roundXWithDirection(x, d);
            var y2 = $gameMap.roundYWithDirection(y, d);
            return alias.call(this, x, y, d) &&
                x2 >= this._tlx && x2 <= this._brx && y2 >= this._tly && y2 <= this._bry;
        };
  4. Shaz said:
    Because Game_Event doesn't have its own canPass function,

    Ah. It does though, because the Game_Event prototype inherits all methods from the Game_Character prototype (which inherits all methods from the Game_CharacterBase prototype).

    Edit: Ninja'd
  5. so I can do a

    var _my_game_event_canpass = Game_Event.prototype.canPass;

    even though it's not explicitly listed?

    Why, then, does it do Game_CharacterBase.prototype.initialize.call(this) if, by default, its initialize function IS the Game_CharacterBase.initialize function, and that's the only thing being done?


    edit: tried it and it works beautifully! You can teach an old dog new tricks! Thanks for helping, but I'd still like to know about the initialize call if you know.
  6. Shaz said:
    so I can do a

    var _my_game_event_canpass = Game_Event.prototype.canPass;
    yes , you can transfere a function like this.

    those Rmmv dev very love call everything everywhere. :barf:
    personally it was so messy inside and bad optimising, that I've all gotten rid of that and recreated my own code.
    This is the best advice I can give you.
    the questions you ask yourself, I also asked myself and I have lost patience.
  7. Shaz said:
    by default, its initialize function IS the Game_CharacterBase.initialize function? Same for initMembers and updateStop.
    Better to think of it as: the Game_Event initialize method WAS exactly the same as the Game_Character initialize method, until it was overwritten.

    Code:
    //As of this moment, the Game_Event.prototype.initialize method is exactly the same as Game_Character.prototype.initialize due to prototype inheritance.
    
    Game_Event.prototype.initialize = function(mapId, eventId) {
    
       //But now, as of this moment, the Game_Event.prototype.initialize method is different because we are now overwriting it.
    
       Game_Character.prototype.initialize.call(this); //Call the method from the "parent class" for code re-usability
    
       //Add whatever we want now for the "child class"
       this._mapId = mapId;
       this._eventId = eventId;
       this.locate(this.event().x, this.event().y);
       this.refresh();
    };
  8. Jonforum said:
    I've all gotten rid of that and recreated my own code
    That's a nice idea, and I know it's paid off well in your case, but what happens when there's an update? If you've pretty much rewritten the core engine, you can't just take an update, without reapplying all of your own changes. Or you have to just apply the new changes to your version. Or miss out on them.

    Aloe Guvner said:
    Game_Event initialize method WAS exactly the same as the Game_Character initialize method, until it was overwritten
    But, as it is, there was no extra added to it. So it was redundant and if I wanted to, I could remove it without any issues. Correct?
  9. I think you'd want to do exactly what Gamefall Team suggests, and just alias Game_Event.prototype.canPass rather than calling the parent class' function. You're modifying the canPass method in two different plugins, which I assume is for convenience sake and organization, so it would be aliased twice.

    Code:
    var alias = Game_Event.prototype.canPass;
    Game_Event.prototype.canPass = function(x, y, d) {
           return $gamePlayer.isSyncedWith(this._eventId) || this._playerSync ||
               alias.call(this, x, y, d);
    };
    Code:
    var alias2 = Game_Event.prototype.canPass;
    Game_Event.prototype.canPass = function(x, y, d) {
           var x2 = $gameMap.roundXWithDirection(x, d);
           var y2 = $gameMap.roundYWithDirection(y, d);
           return alias2.call(this, x, y, d) &&
               x2 >= this._tlx && x2 <= this._brx && y2 >= this._tly && y2 <= this._bry;
    };
    ^^repasted from Gamefall Team, I just changed the second part to "alias2" to better illustrate the point.
  10. yep, that's what I did, and it works perfectly.

    Thanks everyone :)
  11. This thread is being closed, due to being solved. If for some reason you would like this thread re-opened, please report this post and leave a message why. Thank you.