Object Pushing Puzzle - Noob Script Calls

Discussion in 'Javascript/Plugin Support' started by Catog, May 12, 2019.

  1. Catog

    Catog Professional Internal Screamer Veteran

    Messages:
    50
    Likes Received:
    12
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    Hey guys,

    So I followed along with SumRndmDde's javascript/event rock-pushing puzzle, and while complicating it for later rooms, I've hit a bit of a snag. This might be really simple, but I'm also a bit of a coding noob.

    The event works when it comes to a single, specific event or "rock" arriving at a particular coordinate on the map. But if I have multiple possible rocks that could arrive at that particular coordinate, how do I express that using this script call?

    My first instinct was to simply do:

    But that didn't work. I've messed around a bit, but I realise I have no idea what I'm doing. So I thought it best to ask before I mess something up or arrive at a "solution" that will end up causing huge issues for me down the line.
     
    #1
  2. MushroomCake28

    MushroomCake28 KAMO Studio Veteran

    Messages:
    1,714
    Likes Received:
    3,065
    Location:
    Montreal, Canada
    First Language:
    English
    Primarily Uses:
    RMMV
    You start with an event command condition: if the event 5 is in this position. Then if it's not (so in the else part of that conditional), you add another conditional checking the same thing for event 6.

    The $gameMap.event() only accepts one parameter, therefore you can't check multiple events at the same time.
     
    #2
  3. BlueMage

    BlueMage Slime Lv99 Veteran

    Messages:
    108
    Likes Received:
    129
    First Language:
    English
    Primarily Uses:
    RMVX
    [5,6].forEach(function(eventId) {
    if ($gameMap.event(eventId).x == 11 && $gameMap.event(eventId).y == 39 {
    $gameVariables.setValue(1,1);
    } else {$gameVariables.setValue(1,0);}
    });

    If event 5 or 6 position is on x:11, y:39 location, variable 1 will be set to true, or else - false
     
    #3
  4. Catog

    Catog Professional Internal Screamer Veteran

    Messages:
    50
    Likes Received:
    12
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    Hey! That really seemed to work for me, but only for those two particular events. What would I do if there was a third possible rock that could get to that position? Would I have to run a completely new event?

    What do I run this as? I've run this as a script call in a parallel and changed the ID from 1 to 65, but the value doesn't change.
     
    #4
  5. BlueMage

    BlueMage Slime Lv99 Veteran

    Messages:
    108
    Likes Received:
    129
    First Language:
    English
    Primarily Uses:
    RMVX
    @Catog Oh my bad, i forgot this:
    [5,6].forEach(function(eventId) {
    if ($gameMap.event(eventId).x == 11 && $gameMap.event(eventId).y == 39 {
    $gameVariables.setValue(1,1); break;
    } else {$gameVariables.setValue(1,0);}
    });
     
    #5
    Catog likes this.
  6. MushroomCake28

    MushroomCake28 KAMO Studio Veteran

    Messages:
    1,714
    Likes Received:
    3,065
    Location:
    Montreal, Canada
    First Language:
    English
    Primarily Uses:
    RMMV
    @Catog For three events you can just add another conditional branch in it. If you're starting to have too many events, then you should follow @BlueMage method. However, there is a flaw in his method, which is the reason why it's not working: he forgot to break the loop once the condition has been cleared. So basically after event 1, it sets the variable to 1, but after the second event, which isn't in the correct position, it resets the variable to 0. So here's the fixed method:

    Code:
    [5,6].forEach(function(eventId) {
       if ($gameMap.event(eventId).x == 11 && $gameMap.event(eventId).y == 39 {
          $gameVariables.setValue(1,1);
          break;
       } else {$gameVariables.setValue(1,0);}
    });
    
    // Also, if you want to change the variable ID, change the first parameter, not the second one:
    // $gameVariables.setValue(65, 0) is variable 65. Don't touch the 0.
     
    #6
    Catog likes this.
  7. Catog

    Catog Professional Internal Screamer Veteran

    Messages:
    50
    Likes Received:
    12
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    @MushroomCake28 & @BlueMage : Unfortunately, that's still not working - stuff works if I change the value from 0 to 1 in the debug menu, so that's set up okay, but unfortunately, the script I'm being given doesn't change the value when I move those events over. I've got them set up as prescribed, as well as only the first value (ID value) being the only thing I change between. Is there possibly an issue about it being called as a parallel or as a script call?
     
    #7
  8. MushroomCake28

    MushroomCake28 KAMO Studio Veteran

    Messages:
    1,714
    Likes Received:
    3,065
    Location:
    Montreal, Canada
    First Language:
    English
    Primarily Uses:
    RMMV
    Did you check if the event id are correct in the array (the first [ ])? Did you run it in a script call in a parallel event that is active?
     
    #8
  9. Catog

    Catog Professional Internal Screamer Veteran

    Messages:
    50
    Likes Received:
    12
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    Event IDs are definitely correct, and there are no conditions or extra pages to the Parallel event :/
     
    #9
  10. MushroomCake28

    MushroomCake28 KAMO Studio Veteran

    Messages:
    1,714
    Likes Received:
    3,065
    Location:
    Montreal, Canada
    First Language:
    English
    Primarily Uses:
    RMMV
    Well if it isn't working and you don't have too many events, you can always go back to the conditional branch method I mentioned earlier.
     
    #10
  11. caethyril

    caethyril ^_^ Veteran

    Messages:
    1,167
    Likes Received:
    719
    Location:
    UK
    First Language:
    English
    Primarily Uses:
    RMMV
    forEach will always iterate in full (unless there's an exception); use some or a plain for loop if you want to break early.

    Try this in Conditional Branch > Script:
    Code:
    [1,2,3].some(function(eventId) { var ev = $gameMap.event(eventId); return ev && ev.pos(5, 6); });
    This should return true if map event 1, 2, or 3 is at map coordinates x = 5, y = 6, else false. Just add/remove event IDs as needed from the list at the start. :kaothx:

    If you need to check multiple endpoints instead (or as well), then here's a couple of examples I've used before:
    • One type of object, multiple endpoints:
      Code:
      var ends = [{x:3,y:4}, {x:6,y:4}, {x:9,y:4}, {x:3,y:5}, {x:6,y:5}, {x:9,y:5}];
      for (var n = 1; n < 7; n++) {
        var bl = $gameMap.event(n);
        if (ends.some(function(e) { return e.x === bl.x && e.y === bl.y; })) {
          $gameVariables._data[2]++;
        }
      }
    • Two types of object, multiple endpoints for each:
      Code:
      var endA = [{x:5,y:5}, {x:6,y:6}, {x:7,y:7}];
      var endB = [{x:5,y:6}, {x:6,y:5}, {x:7,y:5}, {x:5,y:7}, {x:6,y:7}, {x:7,y:6}];
      for (var n = 1; n < 10; n++) {
        var bl = $gameMap.event(n);
        if (n < 4 && endA.some(function(e) { return e.x === bl.x && e.y === bl.y; })) {
          $gameVariables._data[2]++;
        } else if (n > 3 && endB.some(function(e) { return e.x === bl.x && e.y === bl.y; })) {
          $gameVariables._data[2]++;
        }
      }
    Both of these tally the number of events in position using game variable #2, so you can run these in a Script command, then use Conditional Branch > Variable to check whether all (or enough) of them are correctly-placed.
     
    #11
    Bex and Catog like this.
  12. Bex

    Bex Veteran Veteran

    Messages:
    1,262
    Likes Received:
    292
    First Language:
    German
    Primarily Uses:
    RMMV
    I would try to Event my pushable Rocks in a way, that they can be simply copy and pasted.

    Here a Picture of a Copy paste Rock, and its destination is Region1.
    It doesnt matter if you got 1 or 20 Rocks and if you also got 1 or 20 target places. Its all copy and paste from here on.
    In my example i increased or decreased a variable in case a rock enters or leaves a target maptile position.
    I did not include magic to open a door one time or to make it open and closable again and again, because iam not sure what is needed on your end.
    PushRockbexhjk478.PNG
    Edit:
    Sorry iam not able to answer your initial Question.
    $gameMap.event(MYSELF).x === 11 && $gameMap.event(MYSELF).y === 39
    Sadly Myself isnt the correct Syntax. Maybe one of the Scripters know?
    I also assumed that this codelines are only executed by the pushed rock when pushed. You used this most likely inside the eventcommand Conditional Branch? I believe your initial Question got misunderstood, but not sure my english aint the best.
    Edit2: Just watching the tutorial. You can change trigger action button to player touch in my example, no problem.
     
    Last edited: May 12, 2019
    #12
  13. Catog

    Catog Professional Internal Screamer Veteran

    Messages:
    50
    Likes Received:
    12
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    The .some function worked perfectly! Thank you! That'll make things a lot easier.

    Now, just to clarify, because I feel like the other functions you've described will do this, but just to clarify:
    If I wanted to make it so when two "rock" objects are in two separate, specific spots, the other switches (let's say for S1 and S2) turn off, and one switch (S3) turns on, I would first run a Condition Branch > Variable 2 = 2 and then go S1 = OFF, S2 = 0FF, S3= ON? And which script would do that?
     
    #13
  14. Bex

    Bex Veteran Veteran

    Messages:
    1,262
    Likes Received:
    292
    First Language:
    German
    Primarily Uses:
    RMMV
    Me again, i was Lucky i had the answer still on my PC, and if i remember correctly i got it from Caethyril some time ago =)

    $gameMap.events()[ this._eventId - 1 ].x === 4 && $gameMap.events()[ this._eventId - 1 ].y === 3

    If you change it like that, its like your initial command, but instead of a specified event id in the code, the pushed rock is using its own event id. thatway you should be able to copy paste as many rocks as you like.
     
    #14
    Catog likes this.
  15. caethyril

    caethyril ^_^ Veteran

    Messages:
    1,167
    Likes Received:
    719
    Location:
    UK
    First Language:
    English
    Primarily Uses:
    RMMV
    Yes, sounds like you have the right idea. Basically you just need to check each event against each possible position: you have two rocks and two end points; either rock can go to either point, right? In that case, you have a single "match" type (rock -> goal), so the first script is the way to go. :)

    May be worth noting that your example only has four possible combinations...you could actually do that with eventing, no big deal. :kaothx:

    For only two positions, here's a more concise script to try in Conditional Branch > Script:
    Code:
    [1,2].every(function(eventId) { var ev = $gameMap.event(eventId); return ev && (ev.pos(5,6) || ev.pos(7,8)); })
    This says: "is every one of these events (IDs 1 and 2) at either (5, 6) or (7, 8)?" It will return true if they both are, and false otherwise. Just change the numbers as needed~ :kaopride:

    Note that if you do decide to make use of either of those standalone "tally" script calls, the variable should be set to 0 just before the script call or strange things could happen. :kaoswt2:

    This is what I'd suggest for "is This Event at x=5, y=6?"
    Code:
    this.character(0).pos(5, 6)
    I don't think I've ever used events()[index-1]; much easier to use the built-in event(index) function instead, if needed. :kaophew:

    Besides, that only handles the pushed rock, not the others. Prone to difficulties if you can push the rock out of position, unless you check before and after the push to adjust the "correct position" counter. :kaoswt:
     
    #15
    Bex and Catog like this.
  16. Catog

    Catog Professional Internal Screamer Veteran

    Messages:
    50
    Likes Received:
    12
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    Ah, the only problem with that one, is that there isn't just those possible combinations:

    - Potentially, every rock in the room can get to that point due to how you can transfer rocks via teleportation. So in the end, I probably need something like "if any two of the events in this list are at these two positions, activate this switch."
    - What can I do when there are three possible positions?
     
    #16
  17. Bex

    Bex Veteran Veteran

    Messages:
    1,262
    Likes Received:
    292
    First Language:
    German
    Primarily Uses:
    RMMV
    You could use a Region Id instead of x,y coordinates.
    The Scriptcall list helped me find something. Or are your target coordinates not static and can move around? Than Regions would not work.
    https://forums.rpgmakerweb.com/index.php?threads/rpg-maker-mv-script-call-list.46456/

    Code:
    $gameMap.regionId($gameMap.events()[ this._eventId - 1 ].x, $gameMap.events()[ this._eventId - 1 ].y ) === 1
    But i like to see more of Caethyrils Scripting Solutions also, was just mentioning this Idea.
     
    #17
    Catog and caethyril like this.
  18. caethyril

    caethyril ^_^ Veteran

    Messages:
    1,167
    Likes Received:
    719
    Location:
    UK
    First Language:
    English
    Primarily Uses:
    RMMV
    Ah, right. Yes, then, you'll want a "tally" type script call, e.g.
    Code:
    var vId = 2;                                           // "Tally" variable ID
    var tiles = [{x:5, y:6}, {x:7, y:8}];                  // Coordinates to check
    var eventIds = [1,2,3,4,5,6,72];                       // Event IDs to check
    tiles.forEach(function(tile) {                         // For each point
      var eventHere = eventIds.some(function(eventId) {    // Check the event IDs
        var ev = $gameMap.event(eventId);                  // Get the actual event
        return ev && ev.pos(tile.x, tile.y);       // Return true if it is here
      });
      if (eventHere) $gameVariables._data[vId]++;  // +1 to tally if event is here
    });
    Note I've included //comments here, as a helpful reminder of what's going on. You'll probably need to change the numbers in the first three lines. You can add/remove entries from arrays as you like, just include commas between entries. Note that different types of brackets mean very different things in the code. Just carefully follow the pattern and you should be OK~ :kaothx:

    Here's a plain English translation of the script:
    • Let the tally variable ID equal 2
    • Let the tiles to check be (5,6) and (7,8)
    • Let the event IDs to check be 1, 2, 3, 4, 5, 6, and 72
    • Go through all tiles...
      • Check through all events until one is found on this tile
      • If one was found, +1 to the tally variable's value
    Use it in an event something like this:
    Code:
    ◆Control Variables:#0002 Rock Counter = 0
    ◆Script:var vId = 2;                                           // "Tally" variable ID
    :      :var tiles = [{x:5, y:6}, {x:7, y:8}];                  // Coordinates to check
    :      :var eventIds = [1,2,3,4,5,6,7];                        // Event IDs to check
    :      :tiles.forEach(function(tile) {                         // For each tile
    :      :  var eventHere = eventIds.some(function(eventId) {    // Check the event IDs
    :      :    var ev = $gameMap.event(eventId);                  // Get the actual event
    :      :    return ev && ev.pos(tile.x, tile.y);       // Return true if it is here
    :      :  });
    :      :  if (eventHere) $gameVariables._data[vId]++;  // +1 to tally if event is here
    :      :});
    ◆If:Rock Counter ≥ 2
      ◆Comment:At least two rocks in place!
      ◆Text:None, Window, Bottom
      :    :Congratulations!
      ◆
    :Else
      ◆Comment:Not yet, keep pushin' stuff around.
      ◆
    :End

    Edit:
    This is a valid alternative! ^_^ I personally prefer to use pure coordinates, since you need the x & y anyway to get the region ID and regions, in my experience, tend to get used for a lot of other things. :kaoswt:
     
    Last edited: May 13, 2019
    #18
    Catog likes this.

Share This Page