Event Wrapper

Help spread the word!Share on FacebookShare on TumblrTweet about this on TwitterShare on Google+Share on LinkedInShare on RedditFlattr the author

This script provides a wrapper for the RPG::Event class and other related classes. It adds additional methods to allow you to create event commands directly without having to go through the event editor, and provides intuitive names that are based on the command names available on the event editor.

This is mainly a scripting tool, and is not intended to replace the event editor.
If something can be achieved using the event editor, use it.

You will typically use this in your own scripts when you need to create events on the spot, especially if the event will be complex.

Download

Script: download here
If you are not sure where to start, I’ve provided some examples in this demo.

Usage

Currently, your scripted events are just scripts, so they are not very accessible. You must have an event on the map to be able to use a script call to create more events, though after that your custom events can create their own events provided that you’ve written the logic into their command list.

You can choose to write methods in Game_Interpreter or just a custom module. As long as you can call the methods that will create the event.

class Game_Interpreter

   def make_my_event
      # your event building code
   end
end

eventWrapper1

Creating an event is simple.
1. Instantiate an Event object, passing in x,y coordinates

event = Event.new(2, 4)
  1. Set some page properties. For a list of properties, refer to the help manual, or look through the Event class. You can either access the properties directly, or use some convenience methods defined in the Event class. So for example, assuming we are on page 0,
event.page[0].character_name = "actor1"
event.character_name = "actor1"

Both do the same thing, since it is more convenient to write the latter
Some common properties you might set are

event.priority_type = 1    # 1 is "same as characters". You can choose 0, 1, or 2
event.trigger = 2    # 2 is "event touch". It goes from 0 to 4, same order as in the editor
event.direction_fix = true

Note that the convenience methods always operate on the “current” page.
When you first initialize a new event, the “current” page is 0.
You can change the page by calling

event.set_page(n)

For some integer n. Thus, you may want to work on one page a time, as such:

event.set_page(0)
#do stuff for page 0

event.set_page(1)
# do stuff for page 1

event.set_page(2)
# do stuff for page 2
  1.  Set some page conditions. Refer to the Event_Condition class for details.
event.condition.switch1_id = 2   # this means switch 2 must be ON
event.condition.switch2_id = 3   # remember that the event supports two switches
event.condition.actor_id = 4     # actor 4 must be in party
  1.  Add the event to the map
$game_map.add_event(event)

That should create an event on the map at the designated x,y coords when we make a script call to create this event, but it’s not very useful. We want to add some event commands.

I’ve provided an “Event Builder” that allows you to use a custom syntax to create your events in addition to regular ruby syntax.

Examples

Simple example

I have written a set of methods that essentially alias Game_Interpreter methods, except instead of using command codes, I use the common editor names to identify what the command is. All of the methods are available in the EventCommands class. So for example, let’s write an event that will display a simple message

event = Event.new(3, 3)
event.character_name = "actor1"
event.character_index = 2
event.build {
  show_text("actor1", 2)
  add_message("Hello World")
}
$game_map.add_event(event)

When you create this event, you can talk to it and it will say “Hello World”

eventWrapper2

Note that add_message can take multiple strings. Each string will be treated as a new line.

event.build {
  show_text("actor1", 2)
  add_message("Hello World", "Goodbye")
}

Branching your commands

The event builder supports branching, which is used in various commands such as showing a list of choices, conditional branching, and other things.

event.build {
   show_text("actor1", 1)
   add_message("What do you like?")
   show_choices(["Health", "Mana"], 0)
   choice_branch(0) {
      show_text("actor1", 1)
      add_message("So you prefer health")
   }
   choice_branch(1) {
      show_text("actor1", 1)
      add_message("Mana is ok too")
   }
}

This example demonstrates how to using branching to create a list of choices that the player can select from, and how to define the commands that should be executed depending on the choice.

Naturally, you can provide an unlimited number of branches, though the choice window is not designed for that (meaning, you might have choices that are drawn outside the screen if there are just too many)

eventWrapper3

Mixing ruby with event commands

It is also possible to use typical ruby syntax when building your commands.
You know, take advantage of loops and variables.

event = Event.new(x, y)
event.character_name = "actor2"
event.character_index = 5

event.build {
  show_text("actor2", 5)
  add_message("Which party member do you wish to view?")
  actors = $game_party.members.collect {|actor| actor.name }
  show_choices(actors, 0)

  $game_party.members.each_with_index { |actor, i|
    choice_branch(i) {
      show_text(actor.face_name, actor.face_index)
      add_message("%s is a level %d %s" %[actor.name, actor.level, actor.class.name])
    }
  }
}
$game_map.add_event(event)

This example demonstrates how you would write an event that will go through all of the actors in your party, display their names in a choice list, and then when you select an actor, it will display information about the actor in a text box.

eventWrapper4 eventWrapper5

However, note that because this code is run only when the event is created, the event commands have already been hardcoded into the event. It is no different from manually creating an event and writing your own choice branches and such.

Move routes

Working with move routes is very similar to event commands.
You create a MoveRoute object, and then build some move commands.

event.build {
   route = MoveRoute.new
   route.build {
      move_up
      move_down(2)
      move("2L2R")
   }
   set_move_route(-1, route)
}

The move commands are pretty much the same as what you have in the editor, except I’ve added some additional options that make the lists easier to build.

All methods are available in the MoveCommands class.

Notes

Conditional branches use the following commands

cond_if (condition)
cond_else

I have decided to only support ruby statements as the condition to satisfy, rather than trying to map a dozen different options which would take some time to reference just to figure out which to use.

Aside from using event.build, which might be too restrictive, I’ve provided an EventBuilder if you only want to create a list a commands. For example, if you are creating some custom quick events.

command_list = EventBuilder.build {
  show_text
  add_message("hello")
}

You can then take that list and assign it to an event using

event.list = command_list

Reference

The objects of interest are

RPG::Event
RPG::Event::Page
RPG::Event::Page::Condition
RPG::Event::Page::Graphic
RPG::EventCommand
RPG::MoveRoute
RPG::MoveCommand

All of these are described in the help manual under RGSS Reference Manual -> Game Library -> RPGVXAce Data Structures.

Help spread the word!Share on FacebookShare on TumblrTweet about this on TwitterShare on Google+Share on LinkedInShare on RedditFlattr the author

You may also like...

29 Responses

  1. Kris says:

    Is there any way to move events using this wrapper? Something equivalent to $game_map.events[x].moveto(x,y)? I attempted to use a switch and set_event_location, but I am not sure how to use game variables inside build (the event needs to move, as instantly as possible, to a random location).

  2. internet person says:

    I wish the scripts on your site were clearly marked commercial or non-commercial license.

    I can’t tell what is using what license. Even inside the script code the license is not marked.

    • Hime says:

      I would prefer devs contacting me so I can, for example, take a look at their project.
      There are some scripts that are marked as free for use.

  3. Kris says:

    I am trying to create dynamic mob spawns, where a variable number of mobs will spawn and the type of each mob is randomized. The only problem I am having is removing the event after defeating a mob. After hours of testing, I included a message box to pop up upon winning a battle and found that the event id of every spawned mob was zero. If I used the id of another event already on the map, it worked perfectly (that event disappeared after defeating a spawned monster).

    What am I doing wrong?

    e = Event.new(x[cy], y[cy])

    e.build {
    call_battle(m_id, 0, true, true) {
    battle_win { call_script("$game_map.remove_event(#{e.id})") }
    battle_lose { call_common_event(DEATH_NIGHT) }
    show_text("actor1", 0)
    add_message("Id is #{e.id}")
    }
    }

    • Anonymous says:

      Nevermind… turns out I was using a VERY outdated version (June 2012). The answer was in the patch notes — the ‘delete’ method… lol

  4. Roland says:

    Hey, I’m trying to do a multi-level nested event.build block and I’d like to separate it into multiple files if possible.

    I have a loop to keep asking for a choice until the user selects “cancel”.

    In each choice (that’s not cancel), there’s another prompt for more choices. For each of those choices i’d like to handle the logic in individual methods, but I can’t figure out how to call a method from outside the code block, and everything is going to turn into an unreadable mess, plus I need to use shared code for a lot of the choices, so without duplication it seems impossible.

    Like:

    loop
    A? -> {A1? ->A1() A2? ->A2() A3? A3() ... Cancel}
    B? -> {B1?->B1() B2?->B2() B3?->B3() ... Cancel}
    C? -> {C1?->C1() C2?->B2() C3?->B3() ... Cancel}
    D (cancel loop)

    Is there any way I can do this nicely?
    Thanks!

    • Hime says:

      This is undocumented but there is an event builder command called process_method. Take a look at this example:
      https://gist.github.com/HimeWorks/fa30c5e6d575e055e4f6

      It was supposed to be modeled after method calls but I couldn’t figure out how to implement it nicely.

      • Roland says:

        Hmm thanks, that looks good for splitting up the code. However looking more closely I think my whole design is actually flawed – I can’t create the entire event in advance because they depend on the current state (eg. How much health my character has when they interact with the event). I think I need to be able to create new events dynamically just for the choice/message interaction.

        (I’m trying to make NPCs that will interact differently depending on their properties and so forth, and allow the character to modify them). I’m kind of stumped. Do you know a better way to do this?
        Thanks

        • Roland says:

          I figured it out – I’m storing the NPCs in an array in another module and call one of the module’s function using call_script(“module_name.function_name(” + npc_id.to_s +”)”). I can also get the choice ID by overriding Window_Command and storing the choice in $game_variables[1].
          Thanks for the awesome script!

        • Hime says:

          Yes, as you have found out, the event wrapper allows you to use references to build the commands, so you have a lot of flexibility when it comes to dynamic events.

    • Anonymous says:

      Nevermind…. turns out I was using a VERY outdated very (June 2012). I found the answer in the patch log — just used the “delete” method. LOL

      • Hime says:

        Yes, the delete method is pretty useful when you want to permanently delete events. I don’t think it works for events that were created in the editor though.

  5. Alex says:

    Hey it’s me again! :s I’m trying to spawn event from a module, but I keep getting “can’t add a new key into hash during iteration”. Do you know what this is about, by any chance? Thanks!

    • Hime says:

      What line, how are you adding the event?

      • Anonymous says:

        Well I tried a few things and nothing works so far. I have an event on my map, and this event calls a module methods, who then tries to spawn an event and gives an error.

        I alos tried simply copy-pasting your “Quick” module and it gives the same error. The onyl thing I see different from your setup, is that I put my events in a parallel process….

        I just tested with an event set to trigger and it works. How can I spawn events in a parallel process? I have the feeling it tries to create events before the map is even loaded. Thanks for your help!

        • Hime says:

          Problem is likely the fact that parallel process runs whenever the event is updated. This means that while the map is iterating over all the events to update them, the parallel process is trying to add new events.

          This isn't an issue for events that are running through the map interpreter (eg: action trigger, etc) because the map interpreter runs separate from event updates. I can't think of a solution beyond changing when events are actually added. For example, when you call add_event, the event might show up a second later because the map has only finished updating all events at that time.

          Script has been updated.

          • Anonymous says:

            Hey thanks, that was quick! But I just checked the script it’s the same as before, are you sure it’s updated? The last update is still in 2013 😉

          • Hime says:

            Hmm I definitely updated something…now I’m kind of wondering what I updated.
            Oh wait, now I remember, they moved my files to a new web server and I’m still pushing to the old one.

            Now it’s updated

      • Alex says:

        It seems my problem is that my events are parallel processes, when I put my code in a action trigger event, it works fine. Is there a work around for this?

  6. Alex says:

    Actually… i meant to say that I could pass these arguments, but they’ll be interpreted immediately instead of when the event is triggered. I tried replacing them with simple text messages, and the event works fine in the latter case.

  7. Alex says:

    Hi, it seems it’s not possible to pass arguments such as
    SceneManager.call(Dialogue_Event)
    SceneManager.scene::start_dialogue(“General_Discussion”)

    in event.build. Is these a work around? What is the reason exactly?

    • Hime says:

      Are you adding a script call command, or are you trying to call scripts directly?

      • Anonymous says:

        Ah! That might be it: I’m calling them directly Thanks, I’ll let you know if it doesn’t work, but it makes sense.

      • Anonymous says:

        Hm, so after a quick test it doesn’t seem to work either. I’m using “call_scipt(SceneManager.call(Dialogue_Event))” is that right?

        Here’s the full event:

        event = Event.new(28,21)

        event.set_page(0)

        event.priority_type = 0

        event.trigger = 1

        event.build {

        call_script(SceneManager.call(Dialogue_Event))

        call_script(SceneManager.scene::start_dialogue(“General_
        Discussion”))
        control_self_switch(“A”, true)

        }

        event.set_page(1)

        event.priority_type = 0

        event.condition.self_switch = “A”

        $game_map.add_event(event)

        • Hime says:

          The contents of the script call must be a string.

          • Anonymous says:

            Ok, I think I found the problem. I actually tried using strings at first, but it was giving me an error. The problem is that since my argument also needs to send a string, it cuts the argument at the second “, for example:

            call_script(“SceneManager.call(Dialogue_Event”)

            Will be interpreted as:

            call_script(“SceneManager.scene::start_dialogue(”

            And I’ll get an error saying that it’s expecting “)”.

            Is there a way to circumvent that? I tried using double “” but it doesn’t seem to do anything.

          • Anonymous says:

            Nevermind. Using \” worked. 🙂 Thanks!

          • Hime says:

            Alternatively you can mix single and double quotes to make it look somewhat cleaner if escaping quotes makes it look a bit unattractive.

Leave a Reply

Your email address will not be published.

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax