DarielZer0

Veteran
Veteran
Joined
Oct 16, 2021
Messages
34
Reaction score
10
First Language
Spanish
Primarily Uses
RMMV
Hi i am making a project that almost goes about this so i want a better solution that what i am doing
20220820_014711.jpg
20220820_013110.jpg
So there is a pencil that is an event with a move route following you and the same with the eraser,when the pencil is over a splash of paint(that is an event)it draw something usually useful,and the eraser...well...erases thing...events :)

What i am actually doing is using the x and y map coordenates of the pencil,the eraser,the player,the events that interactuate.....too much! Lets suppose there are 15 eraseable enemys on the map,it is like 30 variables, and common events and etc,so it is there an easier way? Oh and also the player have to interact with some of those events too
 

contentdeleted

Villager
Member
Joined
Jul 19, 2022
Messages
22
Reaction score
9
First Language
English
Primarily Uses
RMMV
You can check which events overlap a running event with the following script call:
Code:
let currentEvent = $gameMap._events[this._eventId];
let overlapingEvents = $gameMap.eventsXy(currentEvent.x, currentEvent.y).filter(e => e._eventId != this._eventId);

From there you can perform useful operations on those events such as running them or deleting them.

Code:
// Erase an event with the id
$gameMap.eraseEvent(eventId);
// Start an event with the id
$gameMap._events[eventId].start();

Or you can check their data and use that to determine what you should draw.

Hopefully this helps? $gameMap.eventsXy can be slow if your map has a ton of events so Id caution against calling it every frame from multiple objects or something like that, but it likely wont make an impact otherwise.
 

DarielZer0

Veteran
Veteran
Joined
Oct 16, 2021
Messages
34
Reaction score
10
First Language
Spanish
Primarily Uses
RMMV
You can check which events overlap a running event with the following script call:
Code:
let currentEvent = $gameMap._events[this._eventId];
let overlapingEvents = $gameMap.eventsXy(currentEvent.x, currentEvent.y).filter(e => e._eventId != this._eventId);

From there you can perform useful operations on those events such as running them or deleting them.

Code:
// Erase an event with the id
$gameMap.eraseEvent(eventId);
// Start an event with the id
$gameMap._events[eventId].start();

Or you can check their data and use that to determine what you should draw.

Hopefully this helps? $gameMap.eventsXy can be slow if your map has a ton of events so Id caution against calling it every frame from multiple objects or something like that, but it likely wont make an impact otherwise.
I'm yet not that good with script calls could you explain better with an example or something?
 

contentdeleted

Villager
Member
Joined
Jul 19, 2022
Messages
22
Reaction score
9
First Language
English
Primarily Uses
RMMV
Sure thing, so that first block of code would be called in a script call in your map event, lets say on the eraser.

I'm assigning a variable "overlapingEvents" which will be an array containing the event objects which the map event, in this case the eraser, is currently on top of.

This array is useful because you can start, erase, or check any of the events in the array since the event objects inside of it have both the eventIds and their current positions on the map, as well as some other info such as the comments you assigned on the event page.

Here would be a complete example of an eraser event that moves across the map and erases any event with the comment "eraseable" on their event page:

JavaScript:
// Get the object of the current running event (the eraser) so we can see its position
let currentEvent = $gameMap._events[this._eventId];
// Search through the events on the map and find any that have the same x and y position but ARE NOT our current event
let overlapingEvents = $gameMap.eventsXy(currentEvent.x, currentEvent.y).filter(event => event._eventId != this._eventId);
// Once again filter our array of events to any which have the "erasable" comment
let erasableEvents = overlapingEvents.filter(event => event._comments.contains("erasable"));
// Now remove each of these events from the map
erasableEvents.forEach( event => $gameMap.eraseEvent(event._eventId));

This script call would run on the eraser object in parrallel while it moves across the map with whatever route you have. (there are ways to optimize that but I dont want to overwhelm you with more unfamiliar code)

Note that this currentEvent will only work for a map event, since common events are stored elseware and do not have xy positions.

Hopefully this is enough to go off of but if you're just getting started with script calls you can use f12 to open the debug menu and type any javascript function to see the result.
For example you can see the information for all events on your map if you type into the console $gameMap._events or console.log($gameMap._events)
This can be very helpful for understanding the form of this data and what is available to you from script calls
 

DarielZer0

Veteran
Veteran
Joined
Oct 16, 2021
Messages
34
Reaction score
10
First Language
Spanish
Primarily Uses
RMMV
Sure thing, so that first block of code would be called in a script call in your map event, lets say on the eraser.

I'm assigning a variable "overlapingEvents" which will be an array containing the event objects which the map event, in this case the eraser, is currently on top of.

This array is useful because you can start, erase, or check any of the events in the array since the event objects inside of it have both the eventIds and their current positions on the map, as well as some other info such as the comments you assigned on the event page.

Here would be a complete example of an eraser event that moves across the map and erases any event with the comment "eraseable" on their event page:

JavaScript:
// Get the object of the current running event (the eraser) so we can see its position
let currentEvent = $gameMap._events[this._eventId];
// Search through the events on the map and find any that have the same x and y position but ARE NOT our current event
let overlapingEvents = $gameMap.eventsXy(currentEvent.x, currentEvent.y).filter(event => event._eventId != this._eventId);
// Once again filter our array of events to any which have the "erasable" comment
let erasableEvents = overlapingEvents.filter(event => event._comments.contains("erasable"));
// Now remove each of these events from the map
erasableEvents.forEach( event => $gameMap.eraseEvent(event._eventId));

This script call would run on the eraser object in parrallel while it moves across the map with whatever route you have. (there are ways to optimize that but I dont want to overwhelm you with more unfamiliar code)

Note that this currentEvent will only work for a map event, since common events are stored elseware and do not have xy positions.

Hopefully this is enough to go off of but if you're just getting started with script calls you can use f12 to open the debug menu and type any javascript function to see the result.
For example you can see the information for all events on your map if you type into the console $gameMap._events or console.log($gameMap._events)
This can be very helpful for understanding the form of this data and what is available to you from script calls
Works but if i deactivate a pixel movement plugin i had,it makes the movement of the player and the events smoother so if posible i wont like to deactivate it is there a way to round the x y to work or something?dont worry if not,and also in place of erase the event what script is used to activate self switches?
EDIT:i checked the player position and it was irregular numbers like 16.0625, 6.8125 so for events is probably the same,is there a way for rounding to a entire number?or if not,a way for it to be with numbers beetween both for example the event is at x 15 so it get erased if the eraser is in some part beetween x14 and x16 or bether x14.5 and x 15.5,this other option would be better because i could set bigger hitboxes,Sorry if i am asking too much im just trying to think some posibilities but if is not posible is still ok
 
Last edited:

contentdeleted

Villager
Member
Joined
Jul 19, 2022
Messages
22
Reaction score
9
First Language
English
Primarily Uses
RMMV
is there a way for rounding to a entire number?or if not,a way for it to be with numbers beetween both for example the event is at x 15 so it get erased if the eraser is in some part beetween x14 and x16
Yup! We can make a few simple modifications to our script call to accomplish either of these.

Our problem is that the helper function included in the engine only checks the tile coordinates of events, while your plugin is moving them at smaller than tile increments.

To fix this we can replace it with an equivalent function.

For rounding down the positions to the nearest tile the second line of the script call would now look like:
JavaScript:
let overlapingEvents = $gameMap._events.filter(mapEvent => Math.floor(mapEvent.x) == Math.floor(currentEvent.x) && Math.floor(mapEvent.y) == Math.floor(currentEvent.y) ).filter(event => event._eventId != this._eventId);

We can also modify this line to check if any of the events are in an area of 2 tiles (as in your example of 14 to 16).
To do so instead of flooring (rounding down) the x and y position and checking if they are equal like in the above example, we must check if our current event position plus 1 is >= (greater than or equal to) the position of the map event, and that our current event position position minus 1 is less than our map position.
Let's see if you can translate that to our script call example on your own and if you have any trouble I'll give you the exact answer. ( Mostly because I won't be at my computer for a while and I don't want to type more code on my phone :p )
Good luck!
 
Last edited:

DarielZer0

Veteran
Veteran
Joined
Oct 16, 2021
Messages
34
Reaction score
10
First Language
Spanish
Primarily Uses
RMMV
let overlapingEvents = $gameMap.filter(mapEvent => Math.floor(mapEvent.x) == Math.floor(currentEvent.x) && Math.floor(mapEvent.y) == Math.floor(currentEvent.y) ).filter(event => event._eventId != this._eventId);
When i replace the second line of the code with this the game show an error "$gameMap.filter is not a function"
 

contentdeleted

Villager
Member
Joined
Jul 19, 2022
Messages
22
Reaction score
9
First Language
English
Primarily Uses
RMMV
Oops sorry about that, made a typo, should be $gameMap._events.filter
Edited my original post
 

DarielZer0

Veteran
Veteran
Joined
Oct 16, 2021
Messages
34
Reaction score
10
First Language
Spanish
Primarily Uses
RMMV
We can also modify this line to check if any of the events are in an area of 2 tiles (as in your example of 14 to 16).
To do so instead of flooring (rounding down) the x and y position and checking if they are equal like in the above example, we must check if our current event position plus 1 is >= (greater than or equal to) the position of the map event, and that our current event position position minus 1 is less than our map position.
Let's see if you can translate that to our script call example on your own and if you have any trouble I'll give you the exact answer. ( Mostly because I won't be at my computer for a while and I don't want to type more code on my phone :p )
Good luck!
I have tried some edits to the code but them dont work you will have to give me the answer, and if posible in place of the code to erase the event i want to activate self switch A, i am sorry to keep bothering you

How can i learn scripting like this?
 
Last edited:

contentdeleted

Villager
Member
Joined
Jul 19, 2022
Messages
22
Reaction score
9
First Language
English
Primarily Uses
RMMV
To give you the example for checking in an area:
JavaScript:
let radius = 1;
let overlapingEvents = $gameMap._events.filter(mapEvent => 
mapEvent.x + radius  >= currentEvent.x && 
mapEvent.x - radius  <= currentEvent.x &&
mapEvent.y + radius  >= currentEvent.y &&
mapEvent.y - radius   <= currentEvent.y
).filter(event => event._eventId != this._eventId);

For activating a self switch... thats a bit complex with a scripting call, since the self switch data is not stored on events themselves but in a separate global object which is indexed by a 3 part key.

To toggle a switch for an event, given an event object that we've found with our previous scripting calls:
JavaScript:
// "A" is the self switch we are toggling, you can set it to a variable instead
let key = [event._mapId, event._eventId, "A"];
// in this case we're setting it to true
$gameSelfSwitches.setValue(key, true);

If you wanted to modify the previous script call to set this self switch on instead of erasing the event you would just call this in place of gameMap.eraseEvent like this:
JavaScript:
erasableEvents.forEach( event =>$gameSelfSwitches.setValue([event._mapId, event._eventId, "A"], true) );

As for learning scripting there's a section on this forum for getting started with javascript: https://forums.rpgmakerweb.com/index.php?forums/learning-javascript.127/, I'd recommend checking that out but I cant speak to its quality. Personally I think the mozzilla intro to javascript is a good place to start if you have zero programming experience: https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics, but it may go into markup languages and other stuff thats not super relevant to working in the context of rpgmaker.

All in all you don't really need JS to accomplish things in rpgmaker (thats the point!) but it does make more complicated things like interactions between events much simpler than setting many rpgmaker game variables.

I have a CS degree and years of work experience so its been a long time since I had to learn scripting from scratch, Ive likely forgotten many of the pitfalls which a newcomer might fall into so I apologize if any of my explanations were overly confusing.
 

DarielZer0

Veteran
Veteran
Joined
Oct 16, 2021
Messages
34
Reaction score
10
First Language
Spanish
Primarily Uses
RMMV
To give you the example for checking in an area:
JavaScript:
let radius = 1;
let overlapingEvents = $gameMap._events.filter(mapEvent =>
mapEvent.x + radius  >= currentEvent.x &&
mapEvent.x - radius  <= currentEvent.x &&
mapEvent.y + radius  >= currentEvent.y &&
mapEvent.y - radius   <= currentEvent.y
).filter(event => event._eventId != this._eventId);

For activating a self switch... thats a bit complex with a scripting call, since the self switch data is not stored on events themselves but in a separate global object which is indexed by a 3 part key.

To toggle a switch for an event, given an event object that we've found with our previous scripting calls:
JavaScript:
// "A" is the self switch we are toggling, you can set it to a variable instead
let key = [event._mapId, event._eventId, "A"];
// in this case we're setting it to true
$gameSelfSwitches.setValue(key, true);

If you wanted to modify the previous script call to set this self switch on instead of erasing the event you would just call this in place of gameMap.eraseEvent like this:
JavaScript:
erasableEvents.forEach( event =>$gameSelfSwitches.setValue([event._mapId, event._eventId, "A"], true) );

As for learning scripting there's a section on this forum for getting started with javascript: https://forums.rpgmakerweb.com/index.php?forums/learning-javascript.127/, I'd recommend checking that out but I cant speak to its quality. Personally I think the mozzilla intro to javascript is a good place to start if you have zero programming experience: https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics, but it may go into markup languages and other stuff thats not super relevant to working in the context of rpgmaker.

All in all you don't really need JS to accomplish things in rpgmaker (thats the point!) but it does make more complicated things like interactions between events much simpler than setting many rpgmaker game variables.

I have a CS degree and years of work experience so its been a long time since I had to learn scripting from scratch, Ive likely forgotten many of the pitfalls which a newcomer might fall into so I apologize if any of my explanations were overly confusing.
Before your reply i did this:
JavaScript:
let overlapingEvents = $gameMap._events.filter(mapEvent => (mapEvent.x -1) <= (currentEvent.x +1) && (mapEvent.y -1) <= (currentEvent.y +1) ).filter(event => event._eventId != this._eventId);
I think i get pretty close hahaha at least it worked more or less
Whatever,i will do as you post,if i make various scripts like that but with diferent radius and diferents comments i will be able to have events will diferents sizes right? and i will test that of self switches,i think this is what i needed thanks for your help!:biggrin:

EDIT:I tested those scripts and they worked,thanks!!!
 
Last edited:

contentdeleted

Villager
Member
Joined
Jul 19, 2022
Messages
22
Reaction score
9
First Language
English
Primarily Uses
RMMV
Glad you were able to get it working!
 

Latest Threads

Latest Profile Posts

ScreenShot_10_3_2022_4_27_17.png
welp, thanks to Luna MV, I was able to add the Balloon as a window... thus allowing me to edit the font color and outline... so now it looks like comic bubbles above characters. I have NO idea why I couldn't get this to work through more conventional means, but here we are.
CUTE CUTE CUTE.gif
I cannot cease doing cute art
War and Wonder is a 100% choice-based open-world visual novel.
1664821313732.png
1664821466359.png
1664821547746.png
Going live soon on Twitch, and will continue Fortunastreet's game "Verloren". For those who are curious, you are welcome to join ;)

-> Franz' Twitch channel
still cursed with having an issue then solving it myself as soon as someone else explains it to me/is trying to help.

sure hope nobody thinks im weird not responding to them after they're only trying to help.

Forum statistics

Threads
125,749
Messages
1,173,217
Members
164,908
Latest member
Wyzardy
Top