diff --git a/data/plugins/location/tutorial-island/guide.rb b/data/plugins/location/tutorial-island/guide.rb
new file mode 100644
index 00000000..efa0b04b
--- /dev/null
+++ b/data/plugins/location/tutorial-island/guide.rb
@@ -0,0 +1,119 @@
+require 'java'
+
+java_import 'org.apollo.game.message.impl.HintIconMessage'
+java_import 'org.apollo.game.message.impl.SwitchTabInterfaceMessage'
+
+
+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 ]
+
+# The character design interface id.
+CHARACTER_DESIGN = 3559
+
+# The Runescape guide Npc
+@runescape_guide = spawn_npc :name => :runescape_guide, :x => 3093, :y => 3107
+
+# 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
+ TutorialInstructions::show_instruction(player)
+ # INITIAL_TABS.each_with_index { |tab, index| player.send(SwitchTabInterfaceMessage.new(index, tab)) } # This is commented so the lame hack works
+
+ if (player.tutorial_island_progress == :not_started)
+ show_hint_icon(player)
+ player.interface_set.open_window(CHARACTER_DESIGN)
+ end
+ end
+end
+
+## TODO lame hack to get round the lack of door support - must remove
+
+
+on :message, :fifth_item_option do |ctx, player, message|
+ player.teleport(Position.new(3100, 3107)) if message.id == 1
+ player.tutorial_island_progress = :moving_around
+ player.interface_set.open_dialogue_overlay(-1)
+end
+
+on :login do |event, player|
+ player.inventory.add(1)
+end
+
+## END lame hack
+
+
+# The conversation with the Runescape Guide, when on tutorial island.
+conversation :tutorial_runescape_guide do
+
+ # The first dialogue of the Runescape Guide, greeting the Player.
+ dialogue :greetings do
+ type :npc_speech
+ npc :runescape_guide
+
+ precondition { |player| player.tutorial_island_progress == :not_started }
+
+ text "Greetings! I see you are a new arrival to this land. My job is to welcome all new visitors. So welcome!"
+
+ continue :dialogue => :go_through_door do |player|
+ player.tutorial_island_progress = :talk_to_people
+ end
+ end
+
+
+ # The Guide welcomes back the Player if they speak to him after they have already gone through the conversation once.
+ dialogue :welcome_back do
+ type :npc_speech
+ npc :runescape_guide
+
+ precondition { |player| player.tutorial_island_progress != :not_started }
+
+ text "Welcome back."
+
+ continue :dialogue => :talk_to_people
+ end
+
+
+ # The Guide tells Players to speak to people in order to succeed.
+ dialogue :talk_to_people do
+ type :npc_speech
+ npc :runescape_guide
+
+ text "You have already learned the first thing you need to succeed in this world: talking to people!",
+ "You will find many inhabitants of this world have useful things to say to you. By clicking on them with your mouse you can talk to them.",
+ "I would also suggest reading through some of the supporting information on the website. There you can find maps, a bestiary, and much more."
+
+ continue :dialogue => :go_through_door
+ end
+
+ # The Guide tells Players to go through the door, advancing the tutorial progress if this is the first time the Player has heard this.
+ dialogue :go_through_door do
+ type :npc_speech
+ npc :runescape_guide
+
+ text "To continue the tutorial go through that door over there, and speak to your first instructor."
+
+ continue :close => true do |player|
+ if (player.tutorial_island_progress == :not_started)
+ reset_hint_icon(player)
+ # TODO door hint icon
+ player.tutorial_island_progress = :runescape_guide_finished
+ end
+
+ TutorialInstructions.show_instruction(player)
+ end
+ end
+
+end
+
+
+# Enables the hint icon above the Runescape guide.
+def show_hint_icon(player)
+ player.send(HintIconMessage.for_npc(@runescape_guide.index))
+end
+
+# Resets the hint icon.
+def reset_hint_icon(player)
+ player.send(HintIconMessage.reset_npc())
+end
\ No newline at end of file
diff --git a/data/plugins/location/tutorial-island/instructions.rb b/data/plugins/location/tutorial-island/instructions.rb
new file mode 100644
index 00000000..7320ca55
--- /dev/null
+++ b/data/plugins/location/tutorial-island/instructions.rb
@@ -0,0 +1,119 @@
+
+# TODO update the status to :moving_around when the door is opened
+
+# Contains members related to the instructions issues during tutorial island.
+module TutorialInstructions
+
+ # Sends the appropriate instruction to the player.
+ def self.show_instruction(player)
+ instructions = CONVERSATIONS[:tutorial_island_instructions]
+ name = case player.tutorial_island_progress
+ # The Runescape Guide instructions.
+ when :not_started then :getting_started
+ when :runescape_guide_finished then :scenery
+ when :moving_around then :moving_around
+
+ # The Survival Guide instructions.
+ when :given_axe then :viewing_items
+ when :cut_tree then :cut_tree
+ when :cutting_tree then :please_wait
+ end
+
+ dialogue = instructions.part(name)
+ send_dialogue(player, dialogue)
+ end
+
+
+ # The one-sided 'conversation' of instruction instructions.
+ conversation :tutorial_island_instructions do
+
+ # The initial instruction displayed when the player logs in, before they have spoken to the guide.
+ dialogue :getting_started do
+ type :text
+
+ title "Getting started"
+ text "To start the tutorial, use your left mouse button to click on the Runescape Guide in this room. He is indicated by "\
+ "a flashing yellow arrow above his head. If you can't see him, use your keyboard's arrow keys to rotate the view."
+ end
+
+ # The instruction displayed after the player has spoken to the Runescape Guide.
+ dialogue :scenery do
+ type :text
+
+ title "Interacting with scenery"
+ text "You can interact with many items of the scenery by simply clicking on them. Right clicking will also give more options. "\
+ "Click on the door indicated with the yellow arrow to go through to the next area and speak with your next instructor."
+ end
+
+ ## TODO !! When we have door support, the player's tutorial island progress needs to be set to :moving_around when they walk through the door !!
+
+ # The instruction displayed after the player has left the initial building.
+ dialogue :moving_around do
+ type :text
+
+ title "Moving around"
+ text "Follow the path to find the next instructor. Clicking on the ground will walk you to that point. Talk to the survival expert "\
+ "by the pond to continue the tutorial. Remember you can rotate the view by pressing the arrow keys."
+ end
+
+ # The instruction displayed after the player has been given the tinderbox and bronze axe by the Survival Guide.
+ dialogue :viewing_items do
+ type :text
+
+ title "Viewing the items you were given"
+ text "Click on the flashing backpack icon to the right side of the main window to view your inventory. Your inventory is a list of "\
+ "everything you have in your backpack."
+ end
+
+ # The instruction displayed before the player has begun to cut the tree.
+ dialogue :cut_tree do
+ type :text
+
+ title "Cut down a tree"
+ text "You can click on the backpack icon at any time to view the items that you currently have in your inventory. You will see that you "\
+ "now have an axe in your inventory. Use this to get some logs by clicking on the indicated tree."
+ end
+
+ # The instruction displayed when the player begins to cut the tree.
+ dialogue :please_wait do
+ type :text
+
+ title "Please wait..."
+ text "Your character is now attempting to cut down the tree. Sit back for a moment whilst he does all the hard work." # TODO she instead of he if applicable
+ end
+
+ # The instruction displayed after the player has successfully cut logs from the tree.
+ dialogue :make_a_fire do
+ type :text
+
+ title "Making a fire"
+ text "Well done! You managed to cut some logs from the tree! Next, use the tinderbox in your inventory to light the logs. First click on the "\
+ "tinderbox to 'use' it. Then click on the logs in your inventory to light them."
+ end
+
+ # The instruction displayed when the player begins to light the fire.
+ dialogue :lighting_fire do
+ type :text
+
+ title "Please wait..."
+ text "Your character is now attempting to light the logs. Sit back for a moment whilst he does all the hard work." # TODO she instead of he if applicable
+ end
+
+ # The instruction displayed when the has lit the logs.
+ dialogue :gained_experience do
+ type :text
+
+ text "You gained some experience."\
+ "Click on the flashing bar graph icon near the inventory button to see your skill stats."
+ end
+
+ # The dialogue displayed when the Player has clicked the flashing skill tab icon.
+ dialogue :skill_stats do
+ type :text
+
+ title "Your skill stats."
+ text "" # TODO !!
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/data/plugins/location/tutorial-island/npcs.rb b/data/plugins/location/tutorial-island/npcs.rb
index 2ce4f67d..7d377be1 100644
--- a/data/plugins/location/tutorial-island/npcs.rb
+++ b/data/plugins/location/tutorial-island/npcs.rb
@@ -16,8 +16,6 @@
# 'Above-ground' npcs
-spawn_npc :name => :runescape_guide, :x => 3093, :y => 3107
-spawn_npc :name => :survival_expert, :x => 3104, :y => 3095, :face => :north
spawn_npc :name => :master_chef, :x => 3076, :y => 3085
spawn_npc :name => :quest_guide, :x => 3086, :y => 3122, :face => :north
spawn_npc :name => :financial_advisor, :x => 3127, :y => 3124, :face => :west
diff --git a/data/plugins/location/tutorial-island/plugin.xml b/data/plugins/location/tutorial-island/plugin.xml
index bf9bf322..2306c8ec 100644
--- a/data/plugins/location/tutorial-island/plugin.xml
+++ b/data/plugins/location/tutorial-island/plugin.xml
@@ -3,14 +3,21 @@
location-tutorial-island
0.1
Tutorial Island
- Adds funtionality to Tutorial island.
+ Adds functionality to Tutorial island.
Major
+
+
+
+
+
+ dialogue
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
new file mode 100644
index 00000000..73e732f6
--- /dev/null
+++ b/data/plugins/location/tutorial-island/stages.rb
@@ -0,0 +1,13 @@
+
+private
+
+# The array of stages in tutorial island.
+STAGES = []
+
+# The stages that are used when interacting with the Runescape Guide.
+STAGES << RUNESCAPE_GUIDE = [ :not_started, :talk_to_people, :go_through_door, :runescape_guide_finished, :moving_around ]
+
+# The stages that are used when interacting with the Survival Expert.
+STAGES << SURVIVAL_EXPERT = [ :given_axe, :cut_tree, :cutting_tree, ]
+
+quest :tutorial_island, STAGES
\ No newline at end of file
diff --git a/data/plugins/location/tutorial-island/survival.rb b/data/plugins/location/tutorial-island/survival.rb
new file mode 100644
index 00000000..cbe12b30
--- /dev/null
+++ b/data/plugins/location/tutorial-island/survival.rb
@@ -0,0 +1,108 @@
+require 'java'
+
+java_import 'org.apollo.game.message.impl.FlashTabInterfaceMessage'
+java_import 'org.apollo.game.message.impl.FlashingTabClickedMessage'
+java_import 'org.apollo.game.message.impl.SwitchTabInterfaceMessage'
+
+private
+
+# The Survival Expert Npc.
+@survival_expert = spawn_npc :name => :survival_expert, :x => 3104, :y => 3095, :face => :north
+
+# The inventory tab index.
+INVENTORY_TAB_INDEX = 3
+
+# The inventory tab id.
+INVENTORY_TAB_ID = 3213
+
+# The id of the tree the Player will cut down.
+TREE_ID = 3033
+
+# TODO prevent axe equipping
+
+# The conversation with the Survival Expert, when on tutorial island.
+conversation :tutorial_surivival_expert do
+
+ dialogue :introduction do
+ type :npc_speech
+ npc :survival_expert
+
+ precondition { |player| player.tutorial_island_progress == :moving_around }
+
+ text "Hello there, newcomer. My name is Brynna. My job is 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."
+
+ continue :dialogue => :items
+ end
+
+
+ dialogue :hello_again do
+ type :npc_speech
+ npc :survival_expert
+
+ precondition { |player| player.tutorial_island_progress == :moving_around }
+
+ 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."
+
+ continue :close => true, &:add_survival_items
+ end
+
+ # The dialogue displayed when the Survival Guide hands both a bronze axe and a tinderbox to the player.
+ dialogue :items do
+ type :message_with_item
+ item :bronze_axe, 200 # TODO the tinderbox is also displayed - find this dialogue id. Scale looks like the default http://i.imgur.com/i1abN5X.png
+
+ text "The Survival Guide gives you a tinderbox and a bronze axe!"
+
+ continue :close => true do |player|
+ if (player.tutorial_island_progress != :given_axe)
+ player.tutorial_island_progress = :given_axe
+ player.send(SwitchTabInterfaceMessage.new(INVENTORY_TAB_INDEX, INVENTORY_TAB_ID))
+ player.send(FlashTabInterfaceMessage.new(INVENTORY_TAB_INDEX))
+ end
+
+ add_survival_items(player)
+ end
+ end
+
+ # The dialogue displayed when the player has succesfully cut down a tree.
+ dialogue :get_logs do
+ type :message_with_item
+ item :logs
+
+ text "You get some logs."
+ continue :close => true do |player|
+ TutorialInstructions.show_instruction(player)
+ end
+ end
+
+end
+
+# The id of the bronze axe.
+BRONZE_AXE = lookup_item(:bronze_axe)
+
+# The id of the tinderbox.
+TINDERBOX = lookup_item(:tinderbox)
+
+# Add the survival items (bronze axe and tinderbox) to the inventory of the player, if they do not already have them.
+def add_survival_items(player)
+ inventory = player.inventory
+ [ BRONZE_AXE, TINDERBOX ].each { |item| inventory.add(item) unless inventory.contains(item) }
+ TutorialInstructions.show_instruction(player)
+end
+
+on :message, :first_object_action do |ctx, player, message|
+ # TODO display "You cannot cut down this tree; you must first follow the guide's instructions." if the player has yet to get the axe
+ if (player.in_tutorial_island && player.tutorial_island_progress == :cut_tree && message.id == TREE_ID)
+ player.tutorial_island_progress = :cutting_tree # Don't break the chain, so that the Woodcutting event actually happens.
+ end
+end
+
+# Intercept the FlashingTabClickedMessage to update the player's progress, if applicable.
+on :message, :flashing_tab_clicked do |ctx, player, message|
+ if (player.in_tutorial_island && message.tab == INVENTORY_TAB_INDEX)
+ player.tutorial_island_progress = :cut_tree
+ ctx.break_handler_chain()
+ end
+end
\ No newline at end of file
diff --git a/data/plugins/location/tutorial-island/utils.rb b/data/plugins/location/tutorial-island/utils.rb
new file mode 100644
index 00000000..00250f6c
--- /dev/null
+++ b/data/plugins/location/tutorial-island/utils.rb
@@ -0,0 +1,34 @@
+require 'java'
+
+java_import 'org.apollo.game.model.entity.Player'
+
+# Declare the tutorial island progress attribute.
+declare_attribute(:tutorial_island_progress, :not_started, :persistent)
+
+
+# The existing player class.
+class Player
+
+ # Returns whether or not this Player is currently on tutorial island.
+ def in_tutorial_island
+ x, y = self.position.x, self.position.y
+
+ return above_ground(x, y) || below_ground(x, y)
+ end
+
+end
+
+
+private
+
+
+# Returns whether or not the specified coordinate pair is above ground on tutorial island.
+def above_ground(x, y)
+ return (x >= 3053 && x <= 3156 && y >= 3056 && y <= 3136)
+end
+
+
+# Returns whether or not the specified coordinate pair is 'below' ground on tutorial island.
+def below_ground(x, y)
+ return (x >= 3072 && x <= 3118 && y >= 9492 && y <= 9535)
+end
\ No newline at end of file