diff --git a/data/plugins/bootstrap.rb b/data/plugins/bootstrap.rb
index 75c90ef9..f36c1493 100644
--- a/data/plugins/bootstrap.rb
+++ b/data/plugins/bootstrap.rb
@@ -18,6 +18,9 @@ java_import 'org.apollo.game.model.World'
java_import 'org.apollo.game.model.entity.Player'
java_import 'org.apollo.game.model.event.EventListener'
java_import 'org.apollo.game.model.event.PlayerEvent'
+java_import 'org.apollo.game.model.event.impl.LoginEvent'
+java_import 'org.apollo.game.model.event.ProxyEvent'
+java_import 'org.apollo.game.model.event.ProxyEventListener'
java_import 'org.apollo.game.model.entity.setting.PrivilegeLevel'
java_import 'org.apollo.game.scheduling.ScheduledTask'
java_import 'org.apollo.game.plugin.PluginContext'
@@ -129,23 +132,26 @@ def schedule(*args, &block)
end
end
-# Defines some sort of action to take upon an message. The following types of
-# message are currently valid:
+@@proxy_listener = ProxyEventListener.new
+$world.listen_for(ProxyEvent.java_class, @@proxy_listener)
+
+# Defines some sort of action to take upon an message. The following types of message are currently
+# valid:
#
# * :command
# * :message
# * :button
# * Any valid Event, as a symbol in ruby snake_case form.
#
-# A command takes one or two arguments (the command name and optionally the
-# minimum rights level to use it). The minimum rights level defaults to
-# STANDARD. The block should have two arguments: player and command.
+# A command takes one or two arguments (the command name and optionally the minimum rights level to
+# use it). The minimum rights level defaults to STANDARD. The block should have two arguments:
+# player and command.
#
-# An message takes no arguments. The block should have three arguments: the chain
-# context, the player and the message object.
+# An message takes no arguments. The block should have two arguments: the player and the message
+# object.
#
-# A button takes one argument (the id). The block should have one argument: the
-# player who clicked the button.
+# A button takes one argument (the id). The block should have one argument: the player who clicked
+# the button.
def on(type, *args, &block)
case type
when :command then on_command(args, block)
@@ -153,11 +159,41 @@ def on(type, *args, &block)
when :button then on_button(args, block)
else
class_name = type.to_s.camelize.concat('Event')
- type = Java::JavaClass.for_name("org.apollo.game.model.event.impl.#{class_name}")
+
+ begin
+ type = Java::JavaClass.for_name("org.apollo.game.model.event.impl.#{class_name}")
+ rescue
+ @@proxy_listener.add(class_name, ProcEventListener.new(block))
+ return
+ end
+
$world.listen_for(type, ProcEventListener.new(block))
end
end
+# Contains extension methods for World.
+module WorldExtensions
+
+ # Overrides World#submit, providing special-case behaviour for Events defined in Ruby, which
+ # need to be wrapped in a ProxyEvent, until https://github.com/jruby/jruby/issues/2359 is
+ # resolved.
+ def submit(event)
+ if event.java_class.name.end_with?(".Event", ".PlayerEvent")
+ event = ProxyEvent.new(event.class.name, event)
+ end
+
+ super(event)
+ end
+
+end
+
+# Prepend the methods defined in WorldExtensions to World.
+class World
+ prepend WorldExtensions
+end
+
+private
+
# Defines an action to be taken upon a button press.
def on_button(args, proc)
fail 'Button must have one argument.' unless args.length == 1
diff --git a/data/plugins/dialogue/dialogue.rb b/data/plugins/dialogue/dialogue.rb
index aba43f4b..dd8d3666 100644
--- a/data/plugins/dialogue/dialogue.rb
+++ b/data/plugins/dialogue/dialogue.rb
@@ -254,7 +254,7 @@ class Dialogue
def options
@options.dup
end
-
+
# Sets the precondition of this dialogue.
def precondition(player=nil, &block)
@precondition = block unless block.nil?
@@ -413,8 +413,11 @@ end
# Sends a dialogue displaying only text.
def send_text_dialogue(player, dialogue)
- title = dialogue.title
- send_generic_dialogue(player, dialogue, title, TEXT_DIALOGUE_IDS)
+ text = dialogue.text
+ dialogue_id = TEXT_DIALOGUE_IDS[text.size - 1]
+
+ text.each_with_index { |line, index| set_text(player, dialogue_id + 1 + index, line) }
+ player.interface_set.open_dialogue(ContinueDialogueAdapter.new(player, dialogue.options[0]), dialogue_id)
end
# Sends a dialogue displaying the player's head.
@@ -555,4 +558,4 @@ GLYPH_SPACING = [ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
# Gets the width of a single character.
def get_width(char)
return GLYPH_SPACING[char.ord]
-end
\ No newline at end of file
+end
diff --git a/data/plugins/location/tutorial-island/guide.rb b/data/plugins/location/tutorial-island/guide.rb
index a03de11e..74778a48 100644
--- a/data/plugins/location/tutorial-island/guide.rb
+++ b/data/plugins/location/tutorial-island/guide.rb
@@ -9,27 +9,48 @@ java_import 'org.apollo.game.model.Position'
private
-# The ids of tabs that are displayed when the player has yet to start the tutorial.
-INITIAL_TABS = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2449, 904, -1, -1]
+# Contains constants used during the Runescape Guide part of Tutorial Island.
+module GuideConstants
-# The character design interface id.
-CHARACTER_DESIGN = 3559
+ # The Runescape Guide Npc.
+ RUNESCAPE_GUIDE = spawn_npc name: :runescape_guide, x: 3093, y: 3107
-# The Runescape guide Npc
-@runescape_guide = spawn_npc name: :runescape_guide, x: 3093, y: 3107
+ # The character design interface id.
+ CHARACTER_DESIGN_INTERFACE = 3559
+
+ # The id of the door of the house new players spawn in.
+ DOOR_ID = 3014
+
+ # The Position of the door of the house new players spawn in.
+ DOOR_POSITION = Position.new(3098, 3107)
+
+ # The HintIconMessage sent to display a hint arrow above the door of the house new players spawn
+ # in.
+ DOOR_HINT = PositionHintIconMessage.new(HintIconMessage::Type::WEST, DOOR_POSITION, 120)
+
+ # The ids of tabs that are displayed when the player has yet to start the tutorial.
+ INITIAL_TABS = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2449, 904, -1, -1].freeze
+
+ # The HintIconMessage sent to remove a hint arrow from above the door.
+ RESET_DOOR_HINT = PositionHintIconMessage.reset
+
+ # The HintIconMessage sent to remove a hint arrow from an Npc.
+ RESET_NPC_HINT = MobHintIconMessage.reset(EntityType::NPC)
+
+end
# Sends the appropriate data to the client when the player logs in to the game.
on :login do |_event, player|
if player.in_tutorial_island && player.privilege_level != RIGHTS_ADMIN
TutorialInstructions.show_instruction(player)
- INITIAL_TABS.each_with_index do |tab, index|
+ GuideConstants::INITIAL_TABS.each_with_index do |tab, index|
player.send(SwitchTabInterfaceMessage.new(index, tab))
end
if player.tutorial_island_progress == :not_started
- show_hint_icon(player)
- player.interface_set.open_window(CHARACTER_DESIGN)
+ player.interface_set.open_window(GuideConstants::CHARACTER_DESIGN_INTERFACE)
+ player.send(MobHintIconMessage.create(GuideConstants::RUNESCAPE_GUIDE))
end
end
end
@@ -95,23 +116,43 @@ conversation :tutorial_runescape_guide do
close do |player|
if player.tutorial_island_progress < :runescape_guide_finished
- reset_hint_icon(player)
- # TODO: Maybe move this, define a constant for the Position and height
- player.send(PositionHintIconMessage.new(HintIconMessage::Type::SOUTH, Position.new(3097, 3107), 120))
+ player.send(GuideConstants::RESET_NPC_HINT)
+
+ player.send(GuideConstants::DOOR_HINT)
player.tutorial_island_progress = :runescape_guide_finished
end
TutorialInstructions.show_instruction(player)
end
end
+
+ # The dialogue displayed if the player attempts to leave the Runescape Guide's house before they
+ # have spoken to him.
+ dialogue :talk_to_guide do
+ type :text
+
+ text 'You need to talk to the Runescape Guide before you are allowed to proceed through this '\
+ 'door.'
+
+ close do |player|
+ TutorialInstructions.show_instruction(player)
+ end
+ end
+
end
-# Enables the hint icon above the Runescape guide.
-def show_hint_icon(player)
- player.send(MobHintIconMessage.create(@runescape_guide))
+on :open_door do |event, player|
+ door = event.door
+
+ if player.in_tutorial_island && door.position.equals(GuideConstants::DOOR_POSITION)
+ if player.tutorial_island_progress < :runescape_guide_finished
+ send_dialogue(player, get_dialogue(:tutorial_runescape_guide, :talk_to_guide))
+ event.terminate
+ elsif player.tutorial_island_progress == :runescape_guide_finished
+ player.tutorial_island_progress = :moving_around
+ player.send(GuideConstants::RESET_DOOR_HINT)
+ TutorialInstructions.show_instruction(player)
+ end
+ end
end
-# Resets the hint icon.
-def reset_hint_icon(player)
- player.send(MobHintIconMessage.reset(EntityType::NPC))
-end
diff --git a/data/plugins/location/tutorial-island/instructions.rb b/data/plugins/location/tutorial-island/instructions.rb
index f4c7b4bc..49931ee4 100644
--- a/data/plugins/location/tutorial-island/instructions.rb
+++ b/data/plugins/location/tutorial-island/instructions.rb
@@ -18,7 +18,8 @@ module TutorialInstructions
when :given_axe then :viewing_items
when :cut_tree then :cut_tree
when :cutting_tree then :please_wait
- else fail 'No dialogue for current stage #{progress} exists.'
+
+ else raise "No dialogue for current stage #{progress} exists."
end
dialogue = instructions.part(name)
diff --git a/data/plugins/location/tutorial-island/plugin.xml b/data/plugins/location/tutorial-island/plugin.xml
index 2306c8ec..72537461 100644
--- a/data/plugins/location/tutorial-island/plugin.xml
+++ b/data/plugins/location/tutorial-island/plugin.xml
@@ -17,7 +17,8 @@
dialogue
+ door
entity-spawning
quest
-
\ No newline at end of file
+
diff --git a/data/plugins/location/tutorial-island/stages.rb b/data/plugins/location/tutorial-island/stages.rb
index 5e691cad..b5ac6cca 100644
--- a/data/plugins/location/tutorial-island/stages.rb
+++ b/data/plugins/location/tutorial-island/stages.rb
@@ -2,15 +2,15 @@
private
# The array of stages in tutorial island.
-STAGES = []
+@stages = []
# The stages that are used when interacting with the Runescape Guide.
RUNESCAPE_GUIDE = [:not_started, :talk_to_people, :go_through_door, :runescape_guide_finished,
- :moving_around]
-STAGES.concat(RUNESCAPE_GUIDE)
+ :moving_around].freeze
+@stages.concat(RUNESCAPE_GUIDE)
# The stages that are used when interacting with the Survival Expert.
-SURVIVAL_EXPERT = [:given_axe, :cut_tree, :cutting_tree]
-STAGES.concat(SURVIVAL_EXPERT)
+SURVIVAL_EXPERT = [:given_axe, :cut_tree, :cutting_tree].freeze
+@stages.concat(SURVIVAL_EXPERT)
-quest :tutorial_island, STAGES
+quest :tutorial_island, @stages
diff --git a/data/plugins/location/tutorial-island/survival.rb b/data/plugins/location/tutorial-island/survival.rb
index 1f8d04bf..863110b6 100644
--- a/data/plugins/location/tutorial-island/survival.rb
+++ b/data/plugins/location/tutorial-island/survival.rb
@@ -42,7 +42,7 @@ conversation :tutorial_surivival_expert do
' tricks. First off we\'re going to start with the most basic survival skill of all: '\
'making a fire.'
- close(&:add_survival_items)
+ close { |player| add_survival_items(player) }
end
dialogue :hello_again do
@@ -54,7 +54,7 @@ conversation :tutorial_surivival_expert do
text 'Hello again. I\'m here to teach you a few survival tips and tricks. First off we\'re '\
'going to start with the most basic survival skill of all: making a fire.'
- close(&:add_survival_items)
+ close { |player| add_survival_items(player) }
end
# The dialogue displayed when the Survival Expert gives the player a bronze axe.
@@ -123,7 +123,7 @@ def add_survival_items(player)
unless inventory.contains(SurvivalConstants::TINDERBOX)
inventory.add(SurvivalConstants::TINDERBOX)
- dialogue = (dialogue == :give_bronze_axe) ? :give_axe_and_tinderbox : give_tinderbox
+ dialogue = (dialogue == :give_bronze_axe) ? :give_axe_and_tinderbox : :give_tinderbox
end
send_dialogue(player, get_dialogue(:tutorial_surivival_expert, dialogue))
diff --git a/data/plugins/navigation/door/door.rb b/data/plugins/navigation/door/door.rb
index 4c7e7797..e0ee818b 100644
--- a/data/plugins/navigation/door/door.rb
+++ b/data/plugins/navigation/door/door.rb
@@ -1,5 +1,8 @@
java_import 'org.apollo.game.action.DistancedAction'
+java_import 'org.apollo.game.model.event.Event'
+
+private
# A distanced action which opens a door.
class OpenDoorAction < DistancedAction
@@ -13,8 +16,11 @@ class OpenDoorAction < DistancedAction
end
def executeAction
- mob.turn_to(@door.position)
- DoorUtil.toggle(@door)
+ if $world.submit(OpenDoorEvent.new(mob, @door))
+ mob.turn_to(@door.position)
+ DoorUtil.toggle(@door)
+ end
+
stop
end
@@ -24,10 +30,25 @@ class OpenDoorAction < DistancedAction
end
-# MessageListener for opening and closing doors.
+# A PlayerEvent that is fired when a player attempts to open a door.
+class OpenDoorEvent < PlayerEvent
+ attr_reader :door
+
+ def initialize(player, door)
+ super(player)
+ @door = door
+ end
+
+end
+
+
+# Listens for FirstObjectActions performed on doors.
on :message, :first_object_action do |player, message|
- if DoorUtil.door?(message.id)
- door = DoorUtil.get_door_object(message.position, message.id)
+ id = message.id
+
+ if DoorUtil.door?(id)
+ door = DoorUtil.get_door_object(message.position, id)
player.start_action(OpenDoorAction.new(player, door)) unless door.nil?
end
end
+
diff --git a/game/src/main/org/apollo/game/message/impl/HintIconMessage.java b/game/src/main/org/apollo/game/message/impl/HintIconMessage.java
index 6c71c4fc..a6611262 100644
--- a/game/src/main/org/apollo/game/message/impl/HintIconMessage.java
+++ b/game/src/main/org/apollo/game/message/impl/HintIconMessage.java
@@ -25,24 +25,24 @@ public abstract class HintIconMessage extends Message {
CENTER(2),
/**
- * A HintIcon that hovers north over a Position.
+ * A HintIcon that hovers west over a Position.
*/
- NORTH(3),
-
- /**
- * A HintIcon that hovers south over a Position.
- */
- SOUTH(4),
+ WEST(3),
/**
* A HintIcon that hovers east over a Position.
*/
- EAST(5),
+ EAST(4),
/**
- * A HintIcon that hovers west over a Position.
+ * A HintIcon that hovers south over a Position.
*/
- WEST(6),
+ SOUTH(5),
+
+ /**
+ * A HintIcon that hovers north over a Position.
+ */
+ NORTH(6),
/**
* A HintIcon that hovers over a Player.
diff --git a/game/src/main/org/apollo/game/message/impl/PositionHintIconMessage.java b/game/src/main/org/apollo/game/message/impl/PositionHintIconMessage.java
index 428f6806..763aaec6 100644
--- a/game/src/main/org/apollo/game/message/impl/PositionHintIconMessage.java
+++ b/game/src/main/org/apollo/game/message/impl/PositionHintIconMessage.java
@@ -1,8 +1,7 @@
package org.apollo.game.message.impl;
-import org.apollo.game.model.Position;
-
import com.google.common.base.Preconditions;
+import org.apollo.game.model.Position;
/**
* A {@link HintIconMessage} which displays a hint over a Position.
@@ -16,20 +15,20 @@ public final class PositionHintIconMessage extends HintIconMessage {
/**
* Tests if the specified Type if valid for a Position HintIcon.
- *
+ *
* @param type The Type to test.
* @return The Type if it was valid.
*/
private static Type testType(Type type) {
Preconditions.checkArgument(type != Type.NPC && type != Type.PLAYER,
- "Hint icons over a Position may not have a type of Player or Npc.");
+ "Hint icons over a Position may not have a type of Player or Npc.");
return type;
}
/**
* Creates a new {@link PositionHintIconMessage} which resets the current
* HintIcon.
- *
+ *
* @return The new {@link PositionHintIconMessage}, never {@code null}.
*/
public static PositionHintIconMessage reset() {
@@ -48,7 +47,7 @@ public final class PositionHintIconMessage extends HintIconMessage {
/**
* Constructs a new {@link PositionHintIconMessage}.
- *
+ *
* @param type The Type of the HintIcon.
* @param position The Position of the hint icon.
* @param height The display height of the hint icon.
@@ -61,7 +60,7 @@ public final class PositionHintIconMessage extends HintIconMessage {
/**
* Gets the Position of the HintIcon.
- *
+ *
* @return The Position of the HintIcon.
*/
public Position getPosition() {
@@ -70,7 +69,7 @@ public final class PositionHintIconMessage extends HintIconMessage {
/**
* Gets the display height of the HintIcon.
- *
+ *
* @return The display height of the HintIcon.
*/
public int getHeight() {
diff --git a/game/src/main/org/apollo/game/model/World.java b/game/src/main/org/apollo/game/model/World.java
index 27536ab8..09ca1962 100644
--- a/game/src/main/org/apollo/game/model/World.java
+++ b/game/src/main/org/apollo/game/model/World.java
@@ -7,6 +7,7 @@ import java.util.Map;
import java.util.Queue;
import java.util.logging.Logger;
+import com.google.common.base.Preconditions;
import org.apollo.Service;
import org.apollo.cache.IndexedFileSystem;
import org.apollo.cache.decoder.ItemDefinitionDecoder;
@@ -31,8 +32,6 @@ import org.apollo.game.scheduling.Scheduler;
import org.apollo.game.scheduling.impl.NpcMovementTask;
import org.apollo.util.NameUtil;
-import com.google.common.base.Preconditions;
-
/**
* The world class is a singleton which contains objects like the {@link MobRepository} for players and NPCs. It should
* only contain things relevant to the in-game world and not classes which deal with I/O and such (these may be better
@@ -86,6 +85,11 @@ public final class World {
*/
private final MobRepository npcRepository = new MobRepository<>(WorldConstants.MAXIMUM_NPCS);
+ /**
+ * The Queue of Npcs that have yet to be removed from the repository.
+ */
+ private final Queue oldNpcs = new ArrayDeque<>();
+
/**
* The {@link MobRepository} of {@link Player}s.
*/
@@ -100,11 +104,6 @@ public final class World {
* The Queue of Npcs that have yet to be added to the repository.
*/
private final Queue queuedNpcs = new ArrayDeque<>();
-
- /**
- * The Queue of Npcs that have yet to be removed from the repository.
- */
- private final Queue oldNpcs = new ArrayDeque<>();
/**
* This world's {@link RegionRepository}.
@@ -209,8 +208,8 @@ public final class World {
releaseNumber = release;
SynchronousDecoder decoder = new SynchronousDecoder(new ItemDefinitionDecoder(fs),
- new NpcDefinitionDecoder(fs), new GameObjectDecoder(fs, this),
- EquipmentDefinitionParser.fromFile("data/equipment-" + release + "" + ".dat"));
+ new NpcDefinitionDecoder(fs), new GameObjectDecoder(fs, this),
+ EquipmentDefinitionParser.fromFile("data/equipment-" + release + "" + ".dat"));
decoder.block();
@@ -315,8 +314,7 @@ public final class World {
* @param npc The npc.
*/
public void unregister(final Npc npc) {
- Preconditions.checkNotNull(npc, "Npc may not be null.");
-
+ Preconditions.checkNotNull(npc, "Npc must not be null.");
oldNpcs.add(npc);
}
@@ -362,7 +360,7 @@ public final class World {
npcMovement.addNpc(npc);
}
} else {
- logger.warning("Failed to register npc, repository capacity reached: [count=" + npcRepository.size() + "]");
+ logger.warning("Failed to register npc (capacity reached): [count=" + npcRepository.size() + "]");
}
}
}
@@ -373,7 +371,7 @@ public final class World {
private void unregisterNpcs() {
while (!oldNpcs.isEmpty()) {
Npc npc = oldNpcs.poll();
-
+
Region region = regions.fromPosition(npc.getPosition());
region.removeEntity(npc);
diff --git a/game/src/main/org/apollo/game/model/event/ProxyEvent.java b/game/src/main/org/apollo/game/model/event/ProxyEvent.java
new file mode 100644
index 00000000..b59c3dca
--- /dev/null
+++ b/game/src/main/org/apollo/game/model/event/ProxyEvent.java
@@ -0,0 +1,52 @@
+package org.apollo.game.model.event;
+
+/**
+ * An {@link Event} that wraps another {@link Event}.
+ *
+ * This is a workaround for JRuby issue 2359. This class
+ * should not be used in Java.
+ *
+ * @author Major
+ */
+public final class ProxyEvent extends Event {
+
+ /**
+ * The Event created by a Ruby plugin.
+ */
+ private final Event event;
+
+ /**
+ * The name of the Ruby Event.
+ */
+ private final String name;
+
+ /**
+ * Creates the ProxyEvent.
+ *
+ * @param name The name of the {@link Event} defined in Ruby.
+ * @param event The Event created by a Ruby plugin.
+ */
+ public ProxyEvent(String name, Event event) {
+ this.name = name;
+ this.event = event;
+ }
+
+ /**
+ * Gets the name of the {@link Event} defined in Ruby.
+ *
+ * @return The name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the {@link Event} created in a Ruby plugin.
+ *
+ * @return The Ruby {@link Event}.
+ */
+ public Event getRuby() {
+ return event;
+ }
+
+}
diff --git a/game/src/main/org/apollo/game/model/event/ProxyEventListener.java b/game/src/main/org/apollo/game/model/event/ProxyEventListener.java
new file mode 100644
index 00000000..4c973ef4
--- /dev/null
+++ b/game/src/main/org/apollo/game/model/event/ProxyEventListener.java
@@ -0,0 +1,52 @@
+package org.apollo.game.model.event;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An {@link EventListener} for {@link ProxyEvent}s.
+ *
+ * This is a workaround for JRuby issue 2359.
+ *
+ * @author Major
+ */
+public final class ProxyEventListener implements EventListener {
+
+ /**
+ * The {@link Map} from Event names to {@link List}s of {@link EventListener}s.
+ */
+ private final Map>> listeners = new HashMap<>();
+
+ /**
+ * Registers an {@link EventListener} to this proxy. This method is not type-safe, and must only
+ * be called from ruby.
+ *
+ * @param name The name of the Event. Must not be {@code null}.
+ * @param listener The {@link EventListener} to add. Must not be {@code null}.
+ */
+ public void add(String name, EventListener listener) {
+ List> listeners = this.listeners.computeIfAbsent(name, n -> new ArrayList<>(2));
+ listeners.add(listener);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void handle(ProxyEvent event) {
+ List> chain = listeners.get(event.getName());
+
+ if (chain != null) {
+ for (EventListener listener : chain) {
+ Event ruby = event.getRuby();
+ listener.handle(ruby);
+
+ if (ruby.terminated()) {
+ event.terminate();
+ break;
+ }
+ }
+ }
+ }
+
+}
diff --git a/game/src/main/org/apollo/game/plugin/RubyPluginEnvironment.java b/game/src/main/org/apollo/game/plugin/RubyPluginEnvironment.java
index 3ec06194..9ac48c67 100644
--- a/game/src/main/org/apollo/game/plugin/RubyPluginEnvironment.java
+++ b/game/src/main/org/apollo/game/plugin/RubyPluginEnvironment.java
@@ -20,11 +20,6 @@ public final class RubyPluginEnvironment implements PluginEnvironment {
*/
private final ScriptingContainer container = new ScriptingContainer();
- /**
- * The World this RubyPluginEnvironment is for.
- */
- private final World world;
-
/**
* Creates and bootstraps the Ruby plugin environment.
*
@@ -32,7 +27,7 @@ public final class RubyPluginEnvironment implements PluginEnvironment {
* @throws IOException If an I/O error occurs during bootstrapping.
*/
public RubyPluginEnvironment(World world) throws IOException {
- this.world = world;
+ container.put("$world", world);
parseBootstrapper();
}
@@ -42,7 +37,7 @@ public final class RubyPluginEnvironment implements PluginEnvironment {
container.runScriptlet(is, name);
} catch (Exception e) {
e.printStackTrace();
- throw new RuntimeException("Error parsing scriptlet " + name + ".");
+ throw new RuntimeException("Error parsing scriptlet " + name + ".", e);
}
}
@@ -61,7 +56,6 @@ public final class RubyPluginEnvironment implements PluginEnvironment {
@Override
public void setContext(PluginContext context) {
container.put("$ctx", context);
- container.put("$world", world);
}
}
\ No newline at end of file
diff --git a/game/src/main/org/apollo/game/release/r377/FlashTabInterfaceMessageEncoder.java b/game/src/main/org/apollo/game/release/r377/FlashTabInterfaceMessageEncoder.java
index 3c0da5b2..8fce05d2 100644
--- a/game/src/main/org/apollo/game/release/r377/FlashTabInterfaceMessageEncoder.java
+++ b/game/src/main/org/apollo/game/release/r377/FlashTabInterfaceMessageEncoder.java
@@ -15,7 +15,7 @@ public final class FlashTabInterfaceMessageEncoder extends MessageEncoder