MV - Follow Player Path (Altimit Pixel Movement)

● ARCHIVED · READ-ONLY
Started by AquaEcho 19 posts View original ↗
  1. This plugin is for use with (Altimit) pixel movement.

    4/6/24 v1.0 Latest release
    Everything is controlled in the plugin file and through plugin parameters now. No more setting up a parallel common event.

    Make an event follow the player's path exactly. This is useful for events
    and enemies that chase the player but keep getting caught on corners or behind
    walls. By default the last 150 positions the player has been will be saved.
    It is not foolproof and events still occasionally get caught on corners if
    the player takes a tight turn around a corner, if the player goes over water
    or other terrain the follower cannot pass, or another event or obstacle gets in
    the event's way


    To use put the following code in the event's moveroute
    this.followPlayerPath();
    or in an event page (if you want to control the event from another event)
    this.character(EVENTID).followPlayerPath();

    Download the attached .js file OR
    Copy and save the following code in a .js file with the name FollowPlayerPathPixel.js in your plugins folder and import it into your project through the plugin manager.

    Do not change the file name as it will break the plugin.
    Code:
    //=============================================================================
    // FollowPlayerPathPixel.js (version 1.0)
    //=============================================================================
    /*:
    *@plugindesc Script call to make an event follow the player's path
    *@author AquaEcho
    *
    * @param Tracking Switch ID
    * @desc Switch ID to turn on/off player path logging. Leaving this at 0 will make it so the path is always logged.
    * @default 0
    *
    * @param Path Length
    * @desc Max number of coordinates stored in the player path
    * @default 150
    *
    *@help
    *Make an event follow the player's path exactly. This is useful for events
    *and enemies that chase the player but keep getting caught on corners or behind
    *walls. By default the last 150 positions the player has been will be saved.
    *It is not foolproof and events still occasionally get caught on corners if
    *the player takes a tight turn around a corner, if the player goes over water
    *or other terrain the follower cannot pass, or another event or obstacle gets in
    *the event's way
    *
    *
    *To use put the following code in the event's moveroute
    *this.followPlayerPath();
    *or in an event page (if you want to control the event from another event)
    *this.character(EVENTID).followPlayerPath();
    
    *This plugin uses Restart's distanceToPoint and tLoc functions with
    *"Do whatever you want" permissions
    *(https://forums.rpgmakerweb.com/index.php?threads/cross-engine-combining-chrono-engine-with-altimit-movement.122622/)
    *
    *Free for commercial or non-commercial use with credit to AquaEcho and Restart
    
    */
    
    var AquaEcho = AquaEcho || {};
    var AEplayerCoord=[];
    AquaEcho.Params = AquaEcho.Params || {};
    
    AquaEcho.SetupParameters = function(){
      var parameters = PluginManager.parameters('FollowPlayerPathPixel');
      AquaEcho.Params.pathLogSwitch = Number(parameters["Tracking Switch ID"]);
      AquaEcho.Params.maxPathLength = Number(parameters["Path Length"]);
    }
    
    AquaEcho.SetupParameters();
    
    AquaEcho.setMovementSuccess = Game_Player.prototype.setMovementSuccess;
    Game_Player.prototype.setMovementSuccess= function(success) {
      if(AquaEcho.Params.pathLogSwitch==0 || (AquaEcho.Params.pathLogSwitch!=0 && $gameSwitches.value(AquaEcho.Params.pathLogSwitch))){
      AEplayerCoord.push([$gamePlayer.x, $gamePlayer.y]);
     
      //save up to maxPathLength coordinates, dump the oldest 1/3 if more than that
      if (AEplayerCoord.length > AquaEcho.Params.maxPathLength) {
          AEplayerCoord.splice(0, AquaEcho.Params.maxPathLength/3);
        }
      } 
    };
    
    AquaEcho.reserveTransfer = Game_Player.prototype.reserveTransfer;
      Game_Player.prototype.reserveTransfer = function(mapId, x, y, d, fadeType) {
          AquaEcho.reserveTransfer.apply(this, arguments);
          AEplayerCoord=[];
        };
    
    Game_CharacterBase.prototype.followPlayerPath = function(){
    
    //Find the closest coordinates to the current event in the playerCoordinates array
    var closestX;
    var closestY;
    var closestDistance = Infinity;
    var closestArrayPosition;
    
    
    for (var i = 0; i < AEplayerCoord.length; i++) {
        var x = AEplayerCoord[i][0];
        var y = AEplayerCoord[i][1];
        var distance = Math.sqrt((x - this.x) ** 2 + (y - this.y) ** 2);
        if (distance < closestDistance) {
          closestX = x;
          closestY = y;
          closestDistance = distance;
          closestArrayPosition = i;
        }
     }
    
    
    //Make current event go to the closest coordinates
    this.tLoc(closestX, closestY, true);
    
    //When it reaches the coordinates make it go to the next position in the array, then the next, etc.
    
      for (var j = closestArrayPosition; j < AEplayerCoord.length; j++) {
        if(this.distanceToPoint(closestX,closestY)<=.5){
          closestX = AEplayerCoord[closestArrayPosition][0];
          closestY = AEplayerCoord[closestArrayPosition][1];
          this.tLoc(closestX, closestY, true);
          closestArrayPosition++;
        }
      }
    }
    
    
    //calculates the distance from an event to a given point. @author Restart
    Game_CharacterBase.prototype.distanceToPoint = function(xcoord,ycoord)
    {
      var distance = Math.sqrt( (this.x-xcoord)*(this.x-xcoord) + (this.y-ycoord)*(this.y-ycoord) );
      return distance;
    }
    
    //sets target location to coordinates (short so can see in movement route window) @author Restart
    Game_CharacterBase.prototype.tLoc = function(xcoord,ycoord,skippable)
    {
        this._moveTargetX = xcoord;
        this._moveTargetY = ycoord;
        this.setDirectionVector(xcoord-this.x,ycoord-this.y); // turn
        this._moveTarget = true;
        if (skippable==undefined)
        {
            this._moveTargetSkippable = true;
        }else{
            this._moveTargetSkippable = skippable;
        }
    }
    
    //._inMotion @author Restart
    var Game_CharacterBase_update_for_ismoving = Game_CharacterBase.prototype.update;
      Game_CharacterBase.prototype.update = function() {
        //.isMoving doesn't really work in altimit
        //this fixes it with the addition of a new function which I can use to tell
        //if the character is actually like, moving
        // the problem seems to be that the isMoving gets cleared midway through
        // this update step (because the .updateMove in rpg_objects sets ._realX to equal .x)
        // but lots of things break if I monkey around with _isMoving
        // so I'm creating my own clone of it here.
        // this is true if the character is in motion and false if they aren't.
        if (this.isMoving())
        {
          this._inMotion=true;
        }else{
          this._inMotion=false;
        }
       
      Game_CharacterBase_update_for_ismoving.call( this );
    }

    You're free to use it commercially, non-commercially, or edit it as long as you credit me and Restart since it uses several of his functions.
  2. Snowcone said:
    Really hyped for this! I have a question though, from my recollection, the last time I used the altimit plugin, there was no way to turn the pixel movement off (and go back to tile) with a script call. If it was or is it's still this way, would it be a bother to try to implement it in this?

    Edit: Sorry if it's weird to ask you, it's just that the original creator of the plugin doesn't seem to be active on it anymore.
    The creator of Altimit likely intended for the RPG Maker community to maintain it which is why they made it open source on Github and the plugin credit is to "Altimit Community Contributors".

    It's not going to be easy to just toggle it on and off as it overwrites a lot of movement and collision functions. Once you load all those changes during game startup you'd have to overwrite them again to "toggle Altimit off", then run Altimit again to toggle it back on again. Realistically it might be possible to mimic turning altimit off by having a script loop through every tile and event on the map to force them to have collision boxes 1x1 tile in area, and the player, and the party followers, and change them back to the 4 (or 8) directional movement
  3. Snowcone said:
    Would a work around that would require a game restart or map reload/new map load work maybe? I am not the wisest on these types of details especially with this plugin, still a code noob.
    I use Ritter Map Transform that has a script call that will refresh the map and redraw collision boundaries for Altimit on command so at least that part is possible with just calling a map refresh.
  4. Can this plugin work for MZ as well? Altimit Pixel movement had an MZ port by someone which worries me if this still works even with FOSSIL.
  5. Qrim said:
    Can this plugin work for MZ as well? Altimit Pixel movement had an MZ port by someone which worries me if this still works even with FOSSIL.
    I don't have MZ so I can't test or support it. I'm also fairly sure this plugin as it is will only work with Altimit because setDirectionVector() is an Altimit function.

    It's possible to edit it for other uses outside of Altimit but I don't have the time for that.
  6. Turning off altimit pixel movement is fairly easy to do, as I said it in that thread too.

    (some have it inside the plugin to disable or enable it others does not) but if you want
    to enable/disable it, use a switch like this (on top)

    if ($gameSwitches.value(ID) !== true ) { // when its OFF
    //all the code here.

    on the bottom of the plugin code, add those

    } else { // else handler
    // as we do nothing when switch is ON
    }

    that should do the trick, but I suggest to check the helpfile before implementing it though.
    as it can be done to any plugin that doesn't has it :) (but use it on your own risk and only for
    personal use) as most wont add it as they want it to be simply activated.
  7. ShadowDragon said:
    Turning off altimit pixel movement is fairly easy to do, as I said it in that thread too.

    (some have it inside the plugin to disable or enable it others does not) but if you want
    to enable/disable it, use a switch like this (on top)

    if ($gameSwitches.value(ID) !== true ) { // when its OFF
    //all the code here.

    on the bottom of the plugin code, add those

    } else { // else handler
    // as we do nothing when switch is ON
    }

    that should do the trick, but I suggest to check the helpfile before implementing it though.
    as it can be done to any plugin that doesn't has it :) (but use it on your own risk and only for
    personal use) as most wont add it as they want it to be simply activated.
    Did you actually test this? Because the last time you mentioned it I tried it and it just made it so Altimit never started at all. Maybe it'll work if you encapsulate only certain functions you want to toggle in a switch instead of the entire plugin code.

    As far as this plugin goes, it shouldn't be that hard to modify it to work without pixel movment in the base engine, but to get diagonal movement it would have to use the functions from another plugin that provided it. It's not a priority for me though so I might get around to it later.
  8. I did test that and works on my end.

    once the true,1 or whatever you want to use (multi checks for safety, it just disable the
    plugin functions and default movement will work.

    if you turn the switch, that the code will run for pixel movement.
    it really depends what you want or not, some modify the plugin to add a function to
    enable and disable it, but that you need to find the source first, would be harder with aliased
    and new functions though.

    the switch approach is the simplies way to toggle pixel/default, but there are cleaner ways
    to make it work and probably better.
  9. Hi, I just test this on cross engine on mz and I got this undefined 'length' error message

    1697477903769.png

    maybe MZ didn't use the same terminology than 'playerCoordinates.length' but do u know how I can whange it to make it work ? It would really improve player detection in my project.
    Thanks again
  10. jackass__ said:
    Hi, I just test this on cross engine on mz and I got this undefined 'length' error message

    View attachment 280299

    maybe MZ didn't use the same terminology than 'playerCoordinates.length' but do u know how I can whange it to make it work ? It would really improve player detection in my project.
    Thanks again
    You need to declare the array somewhere in your game, either in the common event I showed in my screencap or when you enter a map. Script: $gameSystem.playerCoordinates = [];

    I guess I could do it in the plugin file, the problem is it needs to be redeclared/emptied every map, otherwise you'll have events following the player's path from the last map.
  11. AquaEcho said:
    You need to declare the array somewhere in your game, either in the common event I showed in my screencap or when you enter a map. Script: $gameSystem.playerCoordinates = [];

    I guess I could do it in the plugin file, the problem is it needs to be redeclared/emptied every map, otherwise you'll have events following the player's path from the last map.
    Thanks sorry I misread the first post !
  12. I overhauled this plugin so now everything is handled within the plugin file and parameters and you no longer need to set up a parallel common event. Next thing on the list is to apply it to followers since I know that's one of the bigger complaints about Altimit.
  13. Could you add line of sight to this plugin? Also if possible a function to make movement commands to work if a evented enemy is near to the player. I am using Chrono Engine plugin so keep that in mind
    If you can't then I would like to see plugins that do the same thing