Jump to content
Sign in to follow this  
RinTinTen

Coding Event to Refer to Itself.

Recommended Posts

Okay, so this problem I'm having is a little specific, but I think I've narrowed down a potential solution.

 

Basically, I'm using Yanfly's Spawn Event script as well as Neon Black's Mystery Dungeon script with the intention of creating a monster that chases the player through a randomized dungeon. Since the dungeon's gonna be dark, I also used some scripting knowledge to make the monster turn invisible when outside a certain proximity of the player (well, different ranges for different levels of invisibility, I guess). Scare factor kinda thing. I also want to use proximity for spawning and de-spawning the monster (wouldn't want it spawning in plain view, total immersion breaker).

 

So I'm using the spawner to have the monster spawn at random points in the dungeon, but I'm noticing that the spawned monster doesn't disappear. I placed the original event in the map and walked away from it, and it turned invisible, so this seems to be a problem with the spawned events specifically.

 

But I think I know why. The original monster has code that specifically references itself as event ID 2, and I assume the spawned monsters aren't the same. Text and such still works on the spawned events, so they are being copied correctly.

 

Here's the code:

def proximity(range)
  inside_x = $game_map.events[2].x <= $game_player.x + range && $game_map.events[2].x >=
$game_player.x - range
  inside_y = $game_map.events[2].y <= $game_player.y + range && $game_map.events[2].y >=
$game_player.y - range
  return inside_x && inside_y
end

I'm thinking if I alter the code so that it refers to itself in a more generalized way (along the lines of say "this event", instead of "event 2"), then the copied events will have the same ability and turn invisible. But I don't know how to code in RPG Maker all that well, so I don't really know what I can do. I assume I just need to alter the $game_map.events[2] to something else.

 

I suppose if I figure this out, it might also be a good idea to use this code in a common event, then have the original call that common event, so that I can re-use this ability for other enemies down the line. Well, maybe. Just another reason to not refer to a specific event I guess.

Share this post


Link to post
Share on other sites

Without seeing the rest of the modifications to the code, this would be difficult to advise upon. To be more precise, how you would reference something in object-oriented languages like Ruby depends on where the method is located and you have not provided that information.

 

FYI, if you were running this code from an event Script Call command, then this would be running under the Game_Interpreter class. Same with Conditional Branch script boxes and any script boxes that are used in any event command.

Share this post


Link to post
Share on other sites

It's an event Script Call. I have it in the original monster's event, that way the copied events have the same code. I want the copies to have the same piece of the code inside their events as well, but the code won't affect the copies as is, since they refer to event 2 explicitly..

Share this post


Link to post
Share on other sites

During the spawn process set the copy to eventid in a variable, like

 

$game_variables[1] = event.id

 

Then replace the 2 with the variable

 

$game_map.events[$game_variables[1]]

 

this is an incredibly similar problem to one I'm having in my game.

[the 1 above can be changed to a variable you don't necessarily interact with]

Edited by omegarion

Share this post


Link to post
Share on other sites

If this piece is code is being called using a script call in each event, then it's relatively simple. The Game_Interpreter stores the event ID of the event being run in an attribute that is called.... "event_id".

All you would need to do is replace "$game_map.events[2]" with "$game_map.events[event_id]" for each event to reference itself when they run the script call. Even if you run the script call through a Common Event command, the Game_Interpreter will handily attach the calling event's ID to the new Game_Interpreter instance of the Common Event, so you don't have to worry about the Common Event's interpreter having a different event_id attribute.

Unless I misinterpreted what you meant by that and you were planning on using a standalone autorun/parallel-process Common Event as some sort of controller to iterate through every map event and you call it before transitioning into the map, in which case it would have no event_id of its own (well it would, but it would be set to 0). But if you were doing that, then the Common Event would already have to have some way of detecting event IDs, so I assume that's not what you're talking about.

By the way, if you were interested in learning how the code in RPGMaker works there are some nice tutorials people have around here, although I always say the best way to go about it is to look through the default scripts. Of course, neither will help unless you know some basic Ruby syntax and how the inheritance stuff works, but if you already have other programming knowledge it shouldn't be too hard to grasp. I dunno how much this will help for now, but if you come back later on this is basic logic of how the maps and events work:

 

 


All the data for a map's events is stored inside the MapXXX.rvdata2 file along with all the rest of the map's data. This data is meant to be loaded by the default script Game_Map, which is itself called by DataManager when the game starts up and gets assigned to the global variable "$game_map". An instance of Game_Interpreter, which is what reads event commands and executes them, is also created when $game_map is created (but at this point does nothing because there are no events to run).

Nothing is actually loaded by $game_map until the player presses the new game button in the title screen, at which point the DataManager tells $game_map to load the starting map. When $game_map loads a map, it reads the corresponding .rvdata2 file and, amongst other things, creates a whole bunch of Game_Event objects based on the event data in the file (not all the data is used - for example, the names of events do not get loaded into their Game_Event counterparts). These Game_Event instances contain the event commands, trigger conditions, sprites, ect. but the actual processing of the event commands has to be done Game_Interpreters.

If there are any parallel process events in the map, a new Game_Interpreter instance is created for each of them. Otherwise, they use $game_map's interpreter to process their event code and will only run when their trigger conditions are met. If any parallel process Common Events are meant to be running, $game_map will create a whole bunch of Game_CommonEvent instances for those, which will come with their own Game_Interpreter instances attached. Autorun Common Events/map events are NOT given their own Game_Interpreter, but use $game_map's. This is why every non-parallel-process map event freezes whenever autorun events are processing - when $game_map detects an autorun event, its interpreter immediately starts running the autorun event and stops running everything else.

Whenever told to run an event, a Game_Interpreter is given the event ID of the event and the list of commands to run by $game_map and will also store the ID of the map the player is currently situated on in its "map_id" attribute. But unlike map events, Common Events are stored in their own CommonEvents.rvdata2 file, and do not have event IDs like map events - the Game_Interpreters attached to Game_CommonEvents all have an "event_id" of 0. Moreover, whenever a Common Event is called through the Call Common Event command, a new Game_Interpreter instance is created to run that Common Event (but not a new Game_CommonEvent or Game_Event object). This new Interpreter is both created and told to run at the same time.

The first Interpreter performs a check creating the second - if its "map_id" is different from the actual ID of the map the player is in (i.e. it was a parallel process Common Event called on MAP001 that was still running when the player proceeded to MAP002), then the new Common Event gets an event ID of 0. Otherwise, it gets given the event ID of whichever event it was that had the Call Common Event command.

 


 

@omegarion: That solution will not work, as Game_Interpreter has no "event" getter method or any direct access to any event object from $game_map. The only two things that ever get passed to it are "map_id", "event_id" and the list of event commands to process. You could feed it a random number for the "event_id" and a list of random event commands and it could never check whether those commands actually belong to the map event with the ID you gave. Only $game_map has direct access to the Game_Event objects themselves.

Edited by Traverse
  • Like 1

Share this post


Link to post
Share on other sites

I replaced "$game_map.events[2]" with "$game_map.events[event_id]", but now I'm getting an error when I load the map.

 

"Script 'Game Interpreter' line 450: NoMethodError occured.

Undefined method 'x' for [2]:Array."

 

I assume that's the x used to determine the events position, so I kinda need that to set a proximity. Unless there's another way to do that that I don't know about.

 

Maybe I'll have to find a way to make the single event I have working be the only variation of the monster, and have it randomly spawn. It might require more eventing, but if I can't figure out how to script this.

Share this post


Link to post
Share on other sites

 

I replaced "$game_map.events[2]" with "$game_map.events[event_id]",

 

No. You haven't. At least not in all of the instances of it that you had in your event.

 

 

"Script 'Game Interpreter' line 450: NoMethodError occured.

Undefined method 'x' for [2]:Array."

 

Error messages DO actually mean things, you know. You'll be able to figure out how to script better if you learn to pay attention to them. In this case, this error message pretty clearly says you have some loose bit of code reading something like this:

[2].x

that is lying around in one of your script calls. Obviously, an array containing the number 2 will not have any method called "x", so the game throws an error.

 

Moreover, since Line 450 of Game_Interpreter is responsible for handling a script calls in Conditional Branches (which you would easily realize if you glanced at the actual line of code in Game_Interpreter), you more than likely have a Conditional Branch somewhere in your event that you did an incomplete replacement of code in, even if you replaced everything in the Script Call command that you were running.

 

Ultimately, it's your call how you want to do your system - perhaps a purely evented system would be a better option if you are unwilling to learn how to trace error messages (it's kinda very necessary for scripting).

Edited by Traverse

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
Top ArrowTop Arrow Highlighted