Object Pushing Puzzle - Noob Script Calls

Catog

Professional Internal Screamer
Veteran
Joined
Feb 9, 2016
Messages
76
Reaction score
23
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?

$gameMap.event(6).x === 11 && $gameMap.event(6).y === 39
My first instinct was to simply do:

$gameMap.event(5, 6).x === 11 && $gameMap.event(5, 6).y === 39
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.
 

MushroomCake28

KAMO Studio
Global Mod
Joined
Nov 18, 2015
Messages
3,776
Reaction score
4,721
First Language
English
Primarily Uses
RMMZ
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.
 

BlueMage

Slime Lv99
Veteran
Joined
Apr 13, 2019
Messages
116
Reaction score
149
First Language
English
Primarily Uses
RMVX
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.
[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
 

Catog

Professional Internal Screamer
Veteran
Joined
Feb 9, 2016
Messages
76
Reaction score
23
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.
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?

[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
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.
 

BlueMage

Slime Lv99
Veteran
Joined
Apr 13, 2019
Messages
116
Reaction score
149
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);}
});
 

MushroomCake28

KAMO Studio
Global Mod
Joined
Nov 18, 2015
Messages
3,776
Reaction score
4,721
First Language
English
Primarily Uses
RMMZ
@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.
 

Catog

Professional Internal Screamer
Veteran
Joined
Feb 9, 2016
Messages
76
Reaction score
23
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?
 

MushroomCake28

KAMO Studio
Global Mod
Joined
Nov 18, 2015
Messages
3,776
Reaction score
4,721
First Language
English
Primarily Uses
RMMZ
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?
 

Catog

Professional Internal Screamer
Veteran
Joined
Feb 9, 2016
Messages
76
Reaction score
23
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?
Event IDs are definitely correct, and there are no conditions or extra pages to the Parallel event :/
 

MushroomCake28

KAMO Studio
Global Mod
Joined
Nov 18, 2015
Messages
3,776
Reaction score
4,721
First Language
English
Primarily Uses
RMMZ
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.
 

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
2,223
Reaction score
1,630
First Language
EN
Primarily Uses
RMMZ
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.
 

Bex

Veteran
Veteran
Joined
Aug 2, 2013
Messages
1,492
Reaction score
409
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:

Catog

Professional Internal Screamer
Veteran
Joined
Feb 9, 2016
Messages
76
Reaction score
23
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.
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?
 

Bex

Veteran
Veteran
Joined
Aug 2, 2013
Messages
1,492
Reaction score
409
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.
 

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
2,223
Reaction score
1,630
First Language
EN
Primarily Uses
RMMZ
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?
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:

...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.
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:
 

Catog

Professional Internal Screamer
Veteran
Joined
Feb 9, 2016
Messages
76
Reaction score
23
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:
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?
 

Bex

Veteran
Veteran
Joined
Aug 2, 2013
Messages
1,492
Reaction score
409
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.
 

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
2,223
Reaction score
1,630
First Language
EN
Primarily Uses
RMMZ
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?
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:
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
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:

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

Latest Threads

Latest Posts

Forum statistics

Threads
107,555
Messages
1,030,485
Members
139,672
Latest member
WDRS
Top