1-- This script executes for the very first battle that the player encounters in a new game.
2-- Its purpose is to present a dialogue to the player at the start of the battle to provide
3-- a brief explanation of the battle system.
4
5local ns = {}
6setmetatable(ns, {__index = _G})
7tutorial_battle_dialogs = ns;
8setfenv(1, ns);
9
10local hand1_image = nil
11local hand2_image = nil
12-- hand coordinates
13local hand1_origin_x = 0.0;
14local hand1_origin_y = 0.0;
15local hand2_origin_x = 0.0;
16local hand2_origin_y = 0.0;
17-- bouncing coordinates
18local hand1_bouncing_x = 0.0;
19local bouncing1_force = 0.0;
20local hand2_bouncing_y = 0.0;
21local bouncing2_force = 0.0;
22-- whether the hand should be shown
23local trigger_show_hand1 = false;
24local trigger_show_hand2 = false;
25-- whether the hand should be visible
26local hand1_visible = false;
27local hand2_visible = false;
28-- Keeps track of the latest line.
29local last_line = 0;
30
31local Battle = nil
32local Script = nil
33local DialogueManager = nil
34local stop_script = false;
35local start_timer = nil
36
37local dialogue_started = false;
38
39function Initialize(battle_instance)
40    Battle = battle_instance;
41    Script = Battle:GetScriptSupervisor();
42
43    stop_script = false;
44
45    if (GlobalManager:GetGameEvents():GetEventValue("story", "first_battle") ~= 1) then
46        GlobalManager:GetGameEvents():SetEventValue("story", "first_battle", 1);
47        stop_script = false;
48    else
49        stop_script = true;
50        return;
51    end
52
53    -- Load the hand cursors
54    hand1_image = Script:CreateImage("data/gui/menus/hand.png");
55    hand1_image:SetDimensions(47.0, 26.0);
56    hand2_image = Script:CreateImage("data/gui/menus/hand_down.png");
57    hand2_image:SetDimensions(26.0, 47.0);
58
59    DialogueManager = Battle:GetDialogueSupervisor();
60
61    -- Add all speakers for the dialogues to be added
62    DialogueManager:AddSpeaker("Bronann", vt_system.Translate("Bronann"), "data/entities/portraits/bronann.png")
63    DialogueManager:AddSpeaker("Olivia", vt_system.Translate("Olivia"), "")
64
65    -- The dialogue constructed below offers the player instructions on how to do battle. It is displayed only once in the first few seconds
66    -- of battle, before any action can be taken. The player is presented with several options that they can read to get more information on
67    -- the battle system. One of the options that the player may select from will finish the dialogue, allow the battle to resume.
68    local main_dialogue = vt_common.Dialogue.Create(DialogueManager, "Battle tutorial dialogue");
69    local text = vt_system.Translate("Bronann, do you need a quick reminder about the basics of battle?");
70    main_dialogue:AddLine(text, "Olivia");
71    text = vt_system.Translate("...");
72    main_dialogue:AddLine(text, "Bronann");
73    text = vt_system.Translate("Ask about battle basics.");
74    main_dialogue:AddOption(text, 2);
75    text = vt_system.Translate("Ask nothing. I know how to fight.");
76    main_dialogue:AddOption(text, 13);
77    -- [Line 2] After selecting option: Ask about battle basics.
78    text = vt_system.Translate("Er, I could use a refresher on the fundamentals of combat.");
79    main_dialogue:AddLine(text, "Bronann");
80    text = vt_system.Translate("Here you can find the hit points (HP) and skill points (SP) of the ally party. Don't let your HP reach 0 or you're doomed!");
81    main_dialogue:AddLine(text, "Olivia");
82    text = vt_system.Translate("In battle, your icon and those of our enemies will rise up on the stamina bar. The more stamina you have, the faster your icon will climb.");
83    main_dialogue:AddLine(text, "Olivia");
84    text = vt_system.Translate("Once you or one of your allies has reached the action level, you can select an action for that ally. The battle is then paused and you've got all the time you need to select one, so don't panic.");
85    main_dialogue:AddLine(text, "Olivia");
86    text = vt_system.Translate("There are two action types: The basic 'Weapon' to attack, and later you can also use 'Magic' skills. Last but not least, you'll also be able to use our 'Items'. Simply choose an action followed by a target to trigger it.");
87    main_dialogue:AddLine(text, "Olivia");
88    text = vt_system.Translate("The icon will still need to climb to the top of the stamina bar before the selected action is executed. This is called the 'preparation time'. Generally the more powerful the skill being executed, the longer it will take to prepare.");
89    main_dialogue:AddLine(text, "Olivia");
90    text = vt_system.Translate("By the way, you're not forced to wait for your icon to reach the action level before you can select an action. When these two little arrows here are highlighted, you can use your up and down keys to preselect an action for the corresponding ally.");
91    main_dialogue:AddLine(text, "Olivia");
92    text = vt_system.Translate("So long as the little arrows there are still visible, you can change the selected action at any time.");
93    main_dialogue:AddLine(text, "Olivia");
94    text = vt_system.Translate("Don't forget that you can press '") .. InputManager:GetHelpKeyName() .. vt_system.Translate("' if you need more details.");
95    main_dialogue:AddLine(text, "Olivia");
96    text = vt_system.Translate("Shall I repeat all that?");
97    main_dialogue:AddLine(text, "Olivia");
98    text = vt_system.Translate("...");
99    main_dialogue:AddLine(text, "Bronann");
100    text = vt_system.Translate("Yes, please.");
101    main_dialogue:AddOption(text, 3);
102    text = vt_system.Translate("No, it's alright.");
103    main_dialogue:AddOption(text, 14);
104
105    -- [Line 13] End
106    text = vt_system.Translate("Don't worry Olivia, I have not forgotten my training.");
107    main_dialogue:AddLine(text, "Bronann", 15);
108    -- [Line 14] After selecting option: Ask nothing. (After a topic has already been asked).
109    text = vt_system.Translate("Thanks Olivia, I'm prepared now.");
110    main_dialogue:AddLine(text, "Bronann");
111    -- [Line 25] Final line of dialogue
112    text = vt_system.Translate("Good. I'll let you quickly dispatch this minor threat.");
113    main_dialogue:AddLine(text, "Olivia");
114
115    -- Construct a timer so we can start the dialogue a couple seconds after the battle begins
116    start_timer = vt_system.SystemTimer(100, 0);
117
118    dialogue_started = false;
119end
120
121
122function Update()
123    if (stop_script == true) then
124        return;
125    end
126
127    start_timer:Update();
128
129    -- Wait until the initial battle sequence ends to begin running the dialogue start timer
130    if ((start_timer:IsInitial() == true) and (Battle:GetState() ~= vt_battle.BattleMode.BATTLE_STATE_INITIAL)) then
131        start_timer:Run();
132    end
133
134    -- If the dialogue is done, end the scene
135    if ((dialogue_started == true) and (DialogueManager:IsDialogueActive()) == false) then
136        Battle:SetSceneMode(false);
137        stop_script = true;
138    end
139
140    -- If the dialogue has not been seen yet, check if its time to start it
141    if ((dialogue_started == false) and (start_timer:IsFinished() == true) and (DialogueManager:IsDialogueActive() == false)) then
142        DialogueManager:StartDialogue("Battle tutorial dialogue");
143        Battle:SetSceneMode(true);
144        dialogue_started = true;
145    end
146
147    -- Set up whether the hand should be shown and where
148    if (DialogueManager:GetLineCounter() < 3) then
149        hand1_visible = false;
150        hand2_visible = false;
151    elseif (last_line ~= 3 and DialogueManager:GetLineCounter() == 3) then
152        hand1_visible = false;
153        hand2_visible = true;
154        hand2_origin_x = 350.0;
155        hand2_origin_y = 598.0;
156        trigger_show_hand2 = false;
157        last_line = 3;
158    elseif (last_line ~= 4 and DialogueManager:GetLineCounter() == 4) then
159        hand1_visible = true;
160        hand2_visible = false;
161        hand1_origin_x = 850.0;
162        hand1_origin_y = 468.0;
163        trigger_show_hand1 = false;
164        last_line = 4;
165    elseif (last_line ~= 5 and DialogueManager:GetLineCounter() == 5) then
166        hand1_visible = true;
167        hand2_visible = false;
168        hand1_origin_x = 850.0;
169        hand1_origin_y = 278.0;
170        trigger_show_hand1 = false;
171        last_line = 5;
172    elseif (last_line ~= 6 and DialogueManager:GetLineCounter() == 6) then
173        hand1_visible = false;
174        hand2_visible = true;
175        hand2_origin_x = 650.0;
176        hand2_origin_y = 598.0;
177        trigger_show_hand2 = false;
178        last_line = 6;
179    elseif (last_line ~= 7 and DialogueManager:GetLineCounter() == 7) then
180        hand1_visible = true;
181        hand2_visible = false;
182        hand1_origin_x = 850.0;
183        hand1_origin_y = 168.0;
184        trigger_show_hand1 = false;
185        last_line = 7;
186    elseif (last_line ~= 8 and DialogueManager:GetLineCounter() == 8) then
187        hand1_visible = false;
188        hand2_visible = true;
189        hand2_origin_x = 550.0;
190        hand2_origin_y = 598.0;
191        trigger_show_hand2 = false;
192        last_line = 8;
193    elseif (last_line ~= 10 and DialogueManager:GetLineCounter() == 10) then
194        hand1_visible = false;
195        hand2_visible = false;
196        last_line = 10;
197    elseif (DialogueManager:GetLineCounter() >= 13) then
198        hand1_visible = false;
199        hand2_visible = false;
200        last_line = 15;
201    end
202
203    -- get time expired
204    local time_expired = SystemManager:GetUpdateTime();
205
206    -- Left to right hand handling
207    -- The hand has reached the origin point, let's make it bounce
208    if (hand1_bouncing_x >= hand1_origin_x) then
209        bouncing1_force = 5.0;
210    end
211
212    -- Apply pseudo gravity
213    bouncing1_force = bouncing1_force - (time_expired * 0.01);
214
215    hand1_bouncing_x = hand1_bouncing_x - bouncing1_force;
216
217    -- Update the hand shown.
218    if (hand1_visible == true) then
219        if (trigger_show_hand1 == false) then
220            trigger_show_hand1 = true;
221            hand1_bouncing_x = hand1_origin_x;
222        end
223    end
224
225    -- Top to bottom hand handling
226    -- The hand has reached the origin point, let's make it bounce
227    if (hand2_bouncing_y >= hand2_origin_y) then
228        bouncing2_force = 5.0;
229    end
230
231    -- Apply pseudo gravity
232    bouncing2_force = bouncing2_force - (time_expired * 0.01);
233
234    hand2_bouncing_y = hand2_bouncing_y - bouncing2_force;
235
236    -- Update the hand shown.
237    if (hand2_visible == true) then
238        if (trigger_show_hand2 == false) then
239            trigger_show_hand2 = true;
240            hand2_bouncing_y = hand2_origin_y;
241        end
242    end
243end
244
245local white_color = vt_video.Color(1.0, 1.0, 1.0, 1.0);
246
247function DrawPostEffects()
248
249    -- Draw the hands
250    if (hand1_visible == true) then
251        VideoManager:Move(hand1_bouncing_x, hand1_origin_y);
252        hand1_image:Draw(white_color);
253    end
254    if (hand2_visible == true) then
255        VideoManager:Move(hand2_origin_x, hand2_bouncing_y);
256        hand2_image:Draw(white_color);
257    end
258end
259