1-- Set the namespace according to the map name.
2local ns = {};
3setmetatable(ns, {__index = _G});
4layna_forest_crystal_script = ns;
5setfenv(1, ns);
6
7-- The map name, subname and location image
8map_name = "Layna Forest"
9map_image_filename = "data/story/common/locations/layna_forest.png"
10map_subname = "???"
11
12-- The music file used as default background music on this map.
13-- Other musics will have to handled through scripting.
14music_filename = "data/sounds/wind.ogg"
15
16-- c++ objects instances
17local Map = nil
18local EventManager = nil
19
20-- the main character handler
21local hero = nil
22
23-- Dialogue heroes
24local bronann = nil
25local kalya =  nil
26local orlinn = nil
27
28-- the main map loading code
29function Load(m)
30
31    Map = m;
32    EventManager = Map:GetEventSupervisor();
33    Map:SetUnlimitedStamina(true); -- no other enemies than the boss here.
34
35    _CreateCharacters();
36    _CreateObjects();
37
38    -- Set the camera focus on hero
39    Map:SetCamera(hero);
40    -- This is a dungeon map, we'll use the front battle member sprite as default sprite.
41    Map:SetPartyMemberVisibleSprite(hero);
42
43    _CreateEvents();
44    _CreateZones();
45
46    -- Add clouds overlay
47    Map:GetEffectSupervisor():EnableAmbientOverlay("data/visuals/ambient/clouds.png", 5.0, -5.0, true);
48
49    -- Permits the display of the crystal ect...
50    Map:GetScriptSupervisor():AddScript("data/story/layna_forest/crystal_appearance/layna_forest_crystal_appearance_anim.lua");
51
52    -- Preload the useful musics
53    AudioManager:LoadMusic("data/music/Zander Noriega - School of Quirks.ogg", Map);
54
55    -- Handle time of the day lighting, won't be used when arriving here the first time as expected.
56    _HandleTwilight();
57end
58
59-- Handle the twilight advancement after the crystal scene
60function _HandleTwilight()
61
62    -- If the characters have seen the crystal, then it's time to make the twilight happen
63    if (GlobalManager:GetGameEvents():GetEventValue("story", "layna_forest_crystal_event_done") < 1) then
64        return;
65    end
66
67    -- test if the day time is sufficiently advanced
68    if (GlobalManager:GetGameEvents():DoesEventExist("story", "layna_forest_twilight_value") == false) then
69        GlobalManager:GetGameEvents():SetEventValue("story", "layna_forest_twilight_value", 0);
70    end
71
72    Map:GetScriptSupervisor():AddScript("data/story/layna_forest/after_crystal_twilight.lua");
73end
74
75-- the map update function handles checks done on each game tick.
76function Update()
77    -- Check whether the character is in one of the zones
78    _CheckZones();
79end
80
81-- Character creation
82function _CreateCharacters()
83    -- Default hero and position
84    hero = CreateSprite(Map, "Bronann", 30, 22, vt_map.MapMode.GROUND_OBJECT);
85    hero:SetDirection(vt_map.MapMode.NORTH);
86    hero:SetMovementSpeed(vt_map.MapMode.NORMAL_SPEED);
87
88    -- Load previous save point data
89    local x_position = GlobalManager:GetMapData():GetSaveLocationX();
90    local y_position = GlobalManager:GetMapData():GetSaveLocationY();
91    if (x_position ~= 0 and y_position ~= 0) then
92        -- Make the character look at us in that case
93        hero:SetDirection(vt_map.MapMode.SOUTH);
94        hero:SetPosition(x_position, y_position);
95    end
96
97    -- Create secondary characters
98    bronann = CreateSprite(Map, "Bronann", 0, 0, vt_map.MapMode.GROUND_OBJECT);
99    bronann:SetDirection(vt_map.MapMode.NORTH);
100    bronann:SetMovementSpeed(vt_map.MapMode.NORMAL_SPEED);
101    bronann:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
102    bronann:SetVisible(false);
103
104    kalya = CreateSprite(Map, "Kalya", 0, 0, vt_map.MapMode.GROUND_OBJECT);
105    kalya:SetDirection(vt_map.MapMode.NORTH);
106    kalya:SetMovementSpeed(vt_map.MapMode.NORMAL_SPEED);
107    kalya:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
108    kalya:SetVisible(false);
109end
110
111-- The boss map sprite
112local wolf = nil
113
114local crystal = nil
115local crystal_effect = nil
116
117-- The heal particle effect map object
118local heal_effect = nil
119
120function _CreateObjects()
121    local object = nil
122    local npc = nil
123
124    -- save point
125    vt_map.SavePoint.Create(58, 87);
126
127    local chest1 = CreateTreasure(Map, "layna_forest_crystal_chest", "Wood_Chest1", 16, 38, vt_map.MapMode.GROUND_OBJECT);
128    chest1:AddItem(15, 1); -- Lotus Petal
129
130    -- Load the spring heal effect.
131    heal_effect = vt_map.ParticleObject.Create("data/visuals/particle_effects/heal_particle.lua", 0, 0, vt_map.MapMode.GROUND_OBJECT);
132    heal_effect:Stop(); -- Don't run it until the character heals itself
133
134    -- Heal point
135    npc = CreateSprite(Map, "Butterfly", 69, 86, vt_map.MapMode.GROUND_OBJECT);
136    npc:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
137    npc:SetVisible(false);
138    npc:SetName(""); -- Unset the speaker name
139
140    dialogue = vt_map.SpriteDialogue.Create();
141    text = vt_system.Translate("Your party feels better.");
142    dialogue:AddLineEvent(text, npc, "heal point", "");
143    npc:AddDialogueReference(dialogue);
144
145    npc = CreateObject(Map, "Layna Statue", 69, 86, vt_map.MapMode.GROUND_OBJECT);
146    npc:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
147    npc:SetInteractionIcon("data/gui/map/heal_anim.lua")
148
149    -- The boss map sprite, placed for final battle
150    wolf = CreateSprite(Map, "Fenrir", 42, 63, vt_map.MapMode.GROUND_OBJECT);
151    wolf:SetMovementSpeed(vt_map.MapMode.VERY_FAST_SPEED);
152    wolf:SetDirection(vt_map.MapMode.SOUTH);
153
154    if (GlobalManager:GetGameEvents():GetEventValue("story", "layna_forest_crystal_event_done") == 1) then
155        wolf:SetPosition(0, 0);
156        wolf:SetVisible(false);
157        wolf:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
158    end
159
160    -- Orlinn, waiting...
161    orlinn = CreateSprite(Map, "Orlinn", 42, 58, vt_map.MapMode.GROUND_OBJECT);
162    orlinn:SetDirection(vt_map.MapMode.NORTH);
163    orlinn:SetMovementSpeed(vt_map.MapMode.NORMAL_SPEED);
164
165    if (GlobalManager:GetGameEvents():GetEventValue("story", "layna_forest_crystal_event_done") == 1) then
166        orlinn:SetPosition(0, 0);
167        orlinn:SetVisible(false);
168        orlinn:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
169    end
170
171    crystal = CreateSprite(Map, "Crystal", 41, 45, vt_map.MapMode.GROUND_OBJECT);
172    crystal:SetDirection(vt_map.MapMode.SOUTH);
173    crystal:SetMovementSpeed(vt_map.MapMode.NORMAL_SPEED);
174    crystal:SetVisible(false);
175
176    if (GlobalManager:GetGameEvents():GetEventValue("story", "layna_forest_crystal_event_done") == 1) then
177        crystal:SetPosition(0, 0);
178        crystal:SetVisible(false);
179        crystal:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
180    end
181
182    crystal_effect = vt_map.ParticleObject.Create("data/visuals/particle_effects/inactive_save_point.lua", 41, 46, vt_map.MapMode.GROUND_OBJECT);
183    crystal_effect:Stop(); -- Don't run it until the character heals itself
184
185    -- trees, etc
186    local map_trees = {
187        { "Tree Small4", 8, 62 },
188        { "Tree Tiny1", 81, 79 },
189        { "Tree Tiny3", 81, 28 },
190        { "Tree Small3", 83, 73 },
191        { "Tree Small3", 88, 35 },
192        { "Tree Small5", 75.5, 45 },
193        { "Tree Small6", 3, 65 },
194        { "Tree Little2", 3, 55 },
195        { "Tree Little3", 6, 61 },
196        { "Tree Big1", 54, 78 },
197        { "Tree Small6", 2, 83 },
198        { "Tree Small4", 6, 85 },
199        { "Tree Small3", 10, 87 },
200        { "Tree Small5", 12, 91 },
201        { "Tree Little1", 15, 87 },
202        { "Tree Small4", 6, 89 },
203        { "Tree Small2", 3, 87 },
204        { "Tree Little1", 17, 90 },
205        { "Tree Small4", 16, 92 },
206        { "Tree Small3", 18, 95 },
207        { "Tree Small6", 22, 96 },
208        { "Tree Small3", 8, 93 },
209        { "Tree Small4", 3, 95 },
210        { "Tree Tiny4", 1, 88 },
211        { "Tree Small3", 13, 94 },
212        { "Tree Small6", 10, 97 },
213        { "Tree Big1", 16, 98 },
214        { "Tree Small3", 0, 48 },
215        { "Tree Small6", -2, 42 },
216        { "Tree Small4", -1, 35 },
217        { "Tree Small1", 2.5, 45 },
218        { "Tree Small3", 2, 24 },
219        { "Tree Small3", 84, 66 },
220        { "Tree Small6", 77, 58 },
221        { "Tree Big2", 12, 53 },
222        { "Tree Big1", 16, 37 },
223        { "Tree Small3", 35, 55 },
224        { "Tree Small4", 50, 58 },
225        { "Tree Small3", 87, 13 },
226        { "Tree Small4", 92, 16 },
227        { "Tree Small3", 95, 19 },
228        { "Tree Small6", 82, 10 },
229
230        -- North part
231        { "Tree Big1", 0, 20 },
232        { "Tree Small1", -1, 15 },
233        { "Tree Small3", 6, 19 },
234        { "Tree Little3", 10, 17 },
235        { "Tree Small4", 11, 20 },
236        { "Tree Small3", 15, 15 },
237        { "Tree Small6", 4, 9 },
238        { "Tree Small3", 1, 5 },
239        { "Tree Small5", 7, 2 },
240        { "Tree Tiny2", 13, 6 },
241        { "Tree Small3", 19, 14 },
242        { "Tree Little1", 10, 10 },
243        { "Tree Small3", 19, 17 },
244        { "Tree Small4", 24, 13 },
245        { "Tree Tiny2", 25, 6 },
246        { "Tree Small3", 30, 12 },
247        { "Tree Small6", 34, 6 },
248        { "Tree Little3", 40, 3 },
249        { "Tree Big2", 41, 14 },
250        { "Tree Small5", 46, 9 },
251        { "Tree Small4", 50, 15 },
252        { "Tree Little3", 4, 12 },
253        { "Tree Small4", 19, 7 },
254        { "Tree Small3", 35, 13 },
255        { "Tree Tiny3", 40, 7 },
256        { "Tree Small5", 46, 13 },
257        { "Tree Little2", 52, 11 },
258        { "Tree Small3", 57, 14 },
259        { "Tree Small4", 56, 7 },
260        { "Tree Small3", 61, 4 },
261        { "Tree Small5", 67, 3 },
262        { "Tree Small4", 70, 7 },
263        { "Tree Small3", 72, 13 },
264        { "Tree Small6", 76, 19 },
265        { "Tree Small3", 64, 8 },
266        { "Tree Small5", 66, 14 },
267        { "Tree Small3", 62, 12 },
268        { "Tree Small3", 71, 17 },
269        { "Tree Small4", 81, 18 },
270        { "Tree Small3", 77, 12 },
271        { "Tree Small5", 74, 8.2 },
272        { "Tree Small3", 86, 20 },
273        { "Tree Little2", 90, 23 },
274        { "Tree Tiny1", 88, 27 },
275        { "Tree Small6", 92, 28 },
276        { "Tree Small4", 96, 26 },
277        { "Tree Little2", 100, 25 },
278        { "Tree Little4", 105, 23 },
279        { "Tree Small3", 103, 27.2 },
280        { "Tree Small4", 101, 20 },
281
282        -- south part
283        { "Tree Little1", 37, 99 },
284        { "Tree Small4", 43, 102 },
285        { "Tree Small3", 51, 99 },
286        { "Tree Little4", 55, 98 },
287        { "Tree Tiny3", 61, 98 },
288        { "Tree Small3", 68, 100 },
289        { "Tree Small6", 75, 101 },
290        { "Tree Tiny1", 47, 93 },
291
292        --east part
293        { "Tree Big2", 87, 31 },
294        { "Tree Small3", 91, 33 },
295        { "Tree Little3", 90, 37 },
296        { "Tree Small4", 93, 39 },
297        { "Tree Little2", 95, 42 },
298        { "Tree Small6", 98, 45 },
299        { "Tree Tiny1", 96, 48 },
300        { "Tree Small2", 99, 51 },
301        { "Tree Small4", 100, 54 },
302        { "Tree Small1", 99, 57 },
303        { "Tree Big1", 98, 60 },
304        { "Tree Small4", 99, 63 },
305        { "Tree Small3", 101, 66 },
306        { "Tree Small5", 102, 69.2 },
307        { "Tree Small1", 104, 72 },
308        { "Tree Small6", 105, 75 },
309        { "Tree Small2", 104, 79 },
310        { "Tree Small5", 102, 83 },
311        { "Tree Little2", 100, 86 },
312        { "Tree Small4", 101, 90 },
313        { "Tree Big2", 97, 93 },
314        { "Tree Small5", 94, 96 },
315        { "Tree Big2", 83, 92 },
316        { "Tree Small4", 87, 99 },
317        { "Tree Small5", 101, 94 },
318        { "Tree Big1", 104, 86.2 },
319        { "Tree Little2", 95, 34 },
320        { "Tree Small4", 98, 38 },
321        { "Tree Tiny1", 102, 44 },
322        { "Tree Small6", 103, 50 },
323        { "Tree Small3", 98, 31 },
324        { "Tree Small3", 102, 40 },
325        { "Tree Small5", 105, 55 },
326        { "Tree Small6", 103, 33 },
327        { "Tree Small3", 93.5, 46 },
328        { "Tree Small5", 95, 55 },
329        { "Tree Little2", 93, 68 },
330        { "Tree Big2", 91, 50 },
331        { "Tree Small3", 104, 58 },
332        { "Tree Small3", 107, 62 },
333        { "Tree Small3", 106, 43 },
334        { "Tree Small5", 107, 37 },
335        { "Tree Small2", 108, 48 },
336        { "Tree Small4", 109, 56 },
337        { "Tree Small3", 110, 65 },
338        { "Tree Small6", 108, 69 },
339        { "Tree Small2", 110, 73 },
340        { "Tree Small4", 108, 76 },
341        { "Tree Small6", 112, 60 },
342        { "Tree Small3", 113, 68 },
343        { "Tree Big1", 115, 71 },
344        { "Tree Little2", 114, 75 },
345        { "Tree Small3", 116, 61 },
346        { "Tree Small4", 112, 78 },
347        { "Tree Small1", 109, 81 },
348        { "Tree Small3", 110, 85 },
349        { "Tree Small3", 107, 89 },
350        { "Tree Small5", 105, 93 },
351        { "Tree Small3", 102, 98 },
352        { "Tree Small5", 108, 99 },
353        { "Tree Big2", 109, 92 },
354        { "Tree Small4", 112, 89.2 },
355        { "Tree Small5", 114, 86 },
356        { "Tree Tiny1", 83, 23 },
357        { "Tree Small2", 116, 79 },
358        { "Tree Small3", 118, 76 },
359        { "Tree Small3", 117, 66 },
360        { "Tree Small3", 117, 85 },
361        { "Tree Small4", 115, 90 },
362        { "Tree Small6", 113, 93 },
363        { "Tree Small3", 114, 100 },
364    }
365
366    -- Loads the trees according to the array
367    for my_index, my_array in pairs(map_trees) do
368        --print(my_array[1], my_array[2], my_array[3]);
369        CreateObject(Map, my_array[1], my_array[2], my_array[3], vt_map.MapMode.GROUND_OBJECT);
370    end
371
372    -- grass array
373    local map_grass = {
374        -- the grass, hiding a bit the snakes
375        { "Grass Clump1", 52, 79 },
376        { "Grass Clump1", 9, 63 },
377        { "Grass Clump1", 79, 50 },
378        { "Grass Clump1", 7, 68 },
379        { "Grass Clump1", 5, 76 },
380        { "Grass Clump1", 2, 73 },
381        { "Grass Clump1", 9, 78 },
382        { "Grass Clump1", 14, 80 },
383        { "Grass Clump1", 18, 83 },
384        { "Grass Clump1", 20, 86 },
385        { "Grass Clump1", 27, 92 },
386        { "Grass Clump1", 33, 95 },
387        { "Grass Clump1", 22, 68 },
388        { "Grass Clump1", 30, 66 },
389    }
390
391    -- Loads the grass according to the array
392    for my_index, my_array in pairs(map_grass) do
393        --print(my_array[1], my_array[2], my_array[3]);
394        object = CreateObject(Map, my_array[1], my_array[2], my_array[3], vt_map.MapMode.GROUND_OBJECT);
395        object:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
396    end
397end
398
399-- Special event references which destinations must be updated just before being called.
400local move_next_to_bronann_event = nil
401
402-- Creates all events and sets up the entire event sequence chain
403function _CreateEvents()
404    local event = nil
405    local dialogue = nil
406    local text = nil
407
408    -- Triggered events
409    vt_map.MapTransitionEvent.Create("to forest cave 2", "data/story/layna_forest/layna_forest_cave2_map.lua",
410                                     "data/story/layna_forest/layna_forest_cave2_script.lua", "from layna forest crystal");
411
412    -- Heal point
413    vt_map.ScriptedEvent.Create("heal point", "heal_party", "heal_done");
414
415    -- Wolf final fight
416    event = vt_map.BattleEncounterEvent.Create("Fenrir Battle");
417    event:SetMusic("data/music/accion-OGA-djsaryon.ogg");
418    event:SetBackground("data/battles/battle_scenes/forest_background.png");
419    event:AddEnemy(8, 512, 500);
420    event:SetBoss(true);
421    event:AddEventLinkAtEnd("Make the wolf disappear");
422
423    event = vt_map.ScriptedEvent.Create("Make the wolf disappear", "make_wolf_invisible", "");
424    event:AddEventLinkAtEnd("boss fight post-dialogue");
425
426    -- Start of ending dialogue.
427    event = vt_map.ScriptedEvent.Create("boss fight post-dialogue", "post_boss_dialogue_start", "");
428    event:AddEventLinkAtEnd("Kalya moves next to Bronann", 50);
429
430    vt_map.ScriptedEvent.Create("Map:Popstate()", "Map_PopState", "");
431    vt_map.ScriptedSpriteEvent.Create("kalya:SetCollision(ALL)", kalya, "Sprite_Collision_on", "");
432
433    -- NOTE: The actual destination is set just before the actual start call
434    move_next_to_bronann_event = vt_map.PathMoveSpriteEvent.Create("Kalya moves next to Bronann", kalya, 0, 0, false);
435    move_next_to_bronann_event:AddEventLinkAtEnd("first dialogue part");
436    move_next_to_bronann_event:AddEventLinkAtEnd("Kalya looks at Orlinn");
437    move_next_to_bronann_event:AddEventLinkAtEnd("kalya:SetCollision(ALL)");
438
439    vt_map.LookAtSpriteEvent.Create("Kalya looks at Orlinn", kalya, orlinn);
440    vt_map.LookAtSpriteEvent.Create("Kalya looks at Bronann", kalya, bronann);
441    vt_map.LookAtSpriteEvent.Create("Orlinn looks at Bronann", orlinn, bronann);
442    vt_map.ChangeDirectionSpriteEvent.Create("Kalya looks east", kalya, vt_map.MapMode.EAST);
443    vt_map.ChangeDirectionSpriteEvent.Create("Kalya looks west", kalya, vt_map.MapMode.WEST);
444    vt_map.ChangeDirectionSpriteEvent.Create("Kalya looks north", kalya, vt_map.MapMode.NORTH);
445    vt_map.ChangeDirectionSpriteEvent.Create("Kalya looks south", kalya, vt_map.MapMode.SOUTH);
446    vt_map.ChangeDirectionSpriteEvent.Create("Bronann looks east", bronann, vt_map.MapMode.EAST);
447    vt_map.ChangeDirectionSpriteEvent.Create("Bronann looks west", bronann, vt_map.MapMode.WEST);
448    vt_map.ChangeDirectionSpriteEvent.Create("Bronann looks north", bronann, vt_map.MapMode.NORTH);
449    vt_map.ChangeDirectionSpriteEvent.Create("Bronann looks south", bronann, vt_map.MapMode.SOUTH);
450    vt_map.ChangeDirectionSpriteEvent.Create("Orlinn looks east", orlinn, vt_map.MapMode.EAST);
451    vt_map.ChangeDirectionSpriteEvent.Create("Orlinn looks west", orlinn, vt_map.MapMode.WEST);
452    vt_map.ChangeDirectionSpriteEvent.Create("Orlinn looks north", orlinn, vt_map.MapMode.NORTH);
453
454    dialogue = vt_map.SpriteDialogue.Create();
455    text = vt_system.Translate("Orlinn!");
456    dialogue:AddLineEmote(text, kalya, "exclamation");
457    text = vt_system.Translate("I can feel it, sis'. It's coming!");
458    dialogue:AddLineEvent(text, orlinn, "", "Orlinn comes closer of the crystal spawn point");
459    text = vt_system.Translate("Orlinn, stop!");
460    dialogue:AddLineEmote(text, kalya, "exclamation");
461    event = vt_map.DialogueEvent.Create("first dialogue part", dialogue);
462    event:AddEventLinkAtEnd("Kalya runs to Orlinn");
463    event:AddEventLinkAtEnd("Bronann runs to Orlinn");
464
465    vt_map.PathMoveSpriteEvent.Create("Orlinn comes closer of the crystal spawn point", orlinn, 42, 54, false);
466    vt_map.PathMoveSpriteEvent.Create("Bronann runs to Orlinn", bronann, 40, 56, true);
467
468    event = vt_map.PathMoveSpriteEvent.Create("Kalya runs to Orlinn", kalya, 44, 56, true);
469    event:AddEventLinkAtEnd("First tremor");
470
471    event = vt_map.ScriptedEvent.Create("First tremor", "first_tremor", "");
472    event:AddEventLinkAtEnd("second dialogue part");
473
474    dialogue = vt_map.SpriteDialogue.Create();
475    text = vt_system.Translate("What's happening!?");
476    dialogue:AddLineEmote(text, kalya, "exclamation");
477    event = vt_map.DialogueEvent.Create("second dialogue part", dialogue);
478    event:AddEventLinkAtEnd("Kalya looks east 1", 500);
479    event:AddEventLinkAtEnd("kalya:SetCollision(NONE)");
480
481    event = vt_map.ChangeDirectionSpriteEvent.Create("Kalya looks east 1", kalya, vt_map.MapMode.EAST);
482    event:AddEventLinkAtEnd("Bronann looks west 1", 200);
483
484    event = vt_map.ChangeDirectionSpriteEvent.Create("Bronann looks west 1", bronann, vt_map.MapMode.WEST);
485    event:AddEventLinkAtEnd("Kalya looks west 1", 800);
486
487    event = vt_map.ChangeDirectionSpriteEvent.Create("Kalya looks west 1", kalya, vt_map.MapMode.WEST);
488    event:AddEventLinkAtEnd("Bronann looks east 1", 800);
489
490    event = vt_map.ChangeDirectionSpriteEvent.Create("Bronann looks east 1", bronann, vt_map.MapMode.EAST);
491    event:AddEventLinkAtEnd("Bronann looks north", 1000);
492    event:AddEventLinkAtEnd("Kalya looks north", 1000);
493    event:AddEventLinkAtEnd("Both are surprised", 1000);
494    event:AddEventLinkAtEnd("Set Camera on crystal", 1000);
495
496    vt_map.ScriptedSpriteEvent.Create("Set Camera on crystal", crystal, "SetCamera", "");
497
498    event = vt_map.ScriptedEvent.Create("Both are surprised", "bronann_kalya_exclamation", "");
499    event:AddEventLinkAtEnd("Make crystal appear");
500
501    event = vt_map.ScriptedEvent.Create("Make crystal appear", "make_crystal_appear", "make_crystal_appear_update");
502    event:AddEventLinkAtEnd("third dialogue part", 1000);
503
504    dialogue = vt_map.SpriteDialogue.Create();
505    text = vt_system.Translate("Gosh! By all heavens, is this...?");
506    dialogue:AddLineEmote(text, kalya, "sweat drop");
507    text = vt_system.Translate("A crystal stone?!");
508    dialogue:AddLineEmote(text, bronann, "exclamation");
509    text = vt_system.Translate("This is her. I heard her voice calling.");
510    dialogue:AddLine(text, orlinn);
511    event = vt_map.DialogueEvent.Create("third dialogue part", dialogue);
512    event:AddEventLinkAtEnd("crystal dialogue part");
513
514    vt_map.SoundEvent.Create("crystal voice sound 1", "data/story/layna_forest/crystal_appearance/crystal-sentence1.ogg")
515    vt_map.SoundEvent.Create("crystal voice sound 2", "data/story/layna_forest/crystal_appearance/crystal-sentence2.ogg")
516    vt_map.SoundEvent.Create("crystal voice sound 3", "data/story/layna_forest/crystal_appearance/crystal-sentence3.ogg")
517    vt_map.SoundEvent.Create("crystal voice sound 4", "data/story/layna_forest/crystal_appearance/crystal-sentence4.ogg")
518    vt_map.SoundEvent.Create("crystal voice sound 5", "data/story/layna_forest/crystal_appearance/crystal-sentence5.ogg")
519    vt_map.SoundEvent.Create("crystal voice sound 6", "data/story/layna_forest/crystal_appearance/crystal-sentence6.ogg")
520
521    dialogue = vt_map.SpriteDialogue.Create();
522    dialogue:SetInputBlocked(true);
523    text = vt_system.Translate("Dear chosen one, the time has finally come.");
524    dialogue:AddLineTimedEvent(text, crystal, 5000, "crystal voice sound 1", "");
525    text = vt_system.Translate("For us, it will be but an instant.");
526    dialogue:AddLineTimedEvent(text, crystal, 5000, "crystal voice sound 2", "");
527    text = vt_system.Translate("For you, it might be decades.");
528    dialogue:AddLineTimedEvent(text, crystal, 5000, "crystal voice sound 3", "");
529    text = vt_system.Translate("May you bring a happy end to this foolish destiny of ours.");
530    dialogue:AddLineTimedEvent(text, crystal, 6800, "crystal voice sound 4", "");
531    text = vt_system.Translate("We're all anxiously awaiting your return.");
532    dialogue:AddLineTimedEvent(text, crystal, 5000, "crystal voice sound 5", "");
533    text = vt_system.Translate("Now, come. Become one with our holy hope.");
534    dialogue:AddLineTimedEvent(text, crystal, 5000, "crystal voice sound 6", "");
535    event = vt_map.DialogueEvent.Create("crystal dialogue part", dialogue);
536    event:AddEventLinkAtEnd("fourth dialogue part");
537
538    dialogue = vt_map.SpriteDialogue.Create();
539    text = vt_system.Translate("What does all of this mean?");
540    dialogue:AddLineEmote(text, kalya, "thinking dots");
541    text = vt_system.Translate("I shall become one with our only hope.");
542    dialogue:AddLine(text, orlinn);
543    text = vt_system.Translate("What! Orlinn, no!");
544    dialogue:AddLineEmote(text, bronann, "exclamation");
545    event = vt_map.DialogueEvent.Create("fourth dialogue part", dialogue);
546    event:AddEventLinkAtEnd("Orlinn comes even closer of the crystal");
547    event:AddEventLinkAtEnd("Bronann runs in front of Orlinn", 300);
548
549    vt_map.PathMoveSpriteEvent.Create("Orlinn comes even closer of the crystal", orlinn, 42, 50, false);
550
551    event = vt_map.PathMoveSpriteEvent.Create("Bronann runs in front of Orlinn", bronann, 42, 48, true);
552    event:AddEventLinkAtEnd("Bronann looks south");
553    event:AddEventLinkAtEnd("fifth dialogue part");
554
555    dialogue = vt_map.SpriteDialogue.Create();
556    text = vt_system.Translate("Bronann, the crystal! No!");
557    dialogue:AddLineEmote(text, kalya, "exclamation");
558    event = vt_map.DialogueEvent.Create("fifth dialogue part", dialogue);
559    event:AddEventLinkAtEnd("kalya:SetCollision(NONE)");
560    event:AddEventLinkAtEnd("Bronann is hurt");
561    event:AddEventLinkAtEnd("white flash");
562
563    vt_map.ScriptedSpriteEvent.Create("kalya:SetCollision(NONE)", kalya, "Sprite_Collision_off", "");
564
565    event = vt_map.AnimateSpriteEvent.Create("Bronann is hurt", bronann, "hurt", 1200);
566    event:AddEventLinkAtEnd("Bronann is sleeping");
567
568    vt_map.AnimateSpriteEvent.Create("Bronann is sleeping", bronann, "sleeping", 0); -- 0 means forever
569
570    event = vt_map.ScriptedEvent.Create("white flash", "white_flash", "white_flash_update");
571    event:AddEventLinkAtEnd("sixth dialogue part");
572
573    dialogue = vt_map.SpriteDialogue.Create();
574    text = vt_system.Translate("Bronann!");
575    dialogue:AddLineEmote(text, kalya, "exclamation");
576    event = vt_map.DialogueEvent.Create("sixth dialogue part", dialogue);
577    event:AddEventLinkAtEnd("Kalya runs to Bronann");
578
579    event = vt_map.PathMoveSpriteEvent.Create("Kalya runs to Bronann", kalya, 39, 47, true);
580    event:AddEventLinkAtEnd("Kalya looks east");
581    event:AddEventLinkAtEnd("Kalya kneels", 300);
582    event:AddEventLinkAtEnd("seventh dialogue part", 600);
583
584    vt_map.AnimateSpriteEvent.Create("Kalya kneels", kalya, "kneeling", 0); -- 0 means forever
585
586    -- Simply stop the custom animation
587    vt_map.ScriptedSpriteEvent.Create("Kalya gets up", kalya, "Terminate_all_events", "");
588
589    event = vt_map.ScriptedEvent.Create("Kalya and orlinn are surprised", "orlinn_kalya_exclamation", "");
590    event:AddEventLinkAtEnd("Kalya looks east");
591    event:AddEventLinkAtEnd("Bronann kneels");
592
593    vt_map.AnimateSpriteEvent.Create("Bronann kneels", bronann, "kneeling", 0); -- 0 means forever
594
595    -- Simply stop the custom animation
596    vt_map.ScriptedSpriteEvent.Create("Bronann gets up", bronann, "Terminate_all_events", "");
597
598    vt_map.ScriptedEvent.Create("Fade out music", "fade_out_music", "");
599
600    vt_map.ScriptedEvent.Create("Play funny music", "play_funny_music", "");
601
602    dialogue = vt_map.SpriteDialogue.Create();
603    text = vt_system.Translate("Bronann! Are you all right? Answer me!!");
604    dialogue:AddLineEventEmote(text, kalya, "", "Orlinn looks west", "exclamation");
605    text = vt_system.Translate("Bronann!");
606    dialogue:AddLineEventEmote(text, kalya, "", "Orlinn looks east", "exclamation");
607    text = vt_system.Translate("Woah, where am I?");
608    dialogue:AddLineEmote(text, orlinn, "interrogation");
609    text = vt_system.Translate("Bronann!");
610    dialogue:AddLine(text, kalya);
611    text = vt_system.Translate("Sis! What's the matter? What happened?");
612    dialogue:AddLineEventEmote(text, orlinn, "Orlinn looks north", "Kalya gets up", "interrogation");
613    text = vt_system.Translate("What happened? Orlinn, what have you done?");
614    dialogue:AddLineEventEmote(text, kalya, "Kalya looks south", "", "exclamation");
615    text = vt_system.Translate("... My head.");
616    dialogue:AddLineEvent(text, bronann, "", "Kalya and orlinn are surprised");
617    text = vt_system.Translate("Bronann! Are you alright?");
618    dialogue:AddLineEventEmote(text, kalya, "Kalya looks east", "", "exclamation");
619    text = vt_system.Translate("I, I guess so.");
620    dialogue:AddLine(text, bronann);
621    text = vt_system.Translate("The wolf! The crystal! Orlinn! Are you ok?");
622    dialogue:AddLineEventEmote(text, bronann, "Bronann gets up", "", "exclamation");
623    text = vt_system.Translate("Don't worry, I'm fine. Err, what crystal? What... wolf??");
624    dialogue:AddLine(text, orlinn);
625    text = vt_system.Translate("You won't be fine for long after I'm done with you!!");
626    dialogue:AddLineEventEmote(text, kalya, "Kalya looks south", "Fade out music", "thinking dots");
627    text = vt_system.Translate("Huh? Wait, I didn't do anything this time!");
628    dialogue:AddLineEmote(text, orlinn, "sweat drop");
629    text = vt_system.Translate("Oh? You didn't?");
630    dialogue:AddLineEventEmote(text, kalya, "Play funny music", "", "exclamation");
631    event = vt_map.DialogueEvent.Create("seventh dialogue part", dialogue);
632    event:AddEventLinkAtEnd("Kalya runs after Orlinn");
633    event:AddEventLinkAtEnd("Orlinn runs to point 3");
634    event:AddEventLinkAtEnd("Bronann sighs and think", 2000);
635
636    -- Kalya runs after Orlinn's loop
637    event = vt_map.PathMoveSpriteEvent.Create("Kalya runs after Orlinn", kalya, orlinn, true);
638    event:AddEventLinkAtEnd("Kalya runs after Orlinn");
639
640    event = vt_map.PathMoveSpriteEvent.Create("Orlinn runs to point 1", orlinn, 32, 38, true);
641    event:AddEventLinkAtEnd("Orlinn runs to point 2");
642
643    event = vt_map.PathMoveSpriteEvent.Create("Orlinn runs to point 2", orlinn, 32, 45, true);
644    event:AddEventLinkAtEnd("Orlinn runs to point 3");
645
646    event = vt_map.PathMoveSpriteEvent.Create("Orlinn runs to point 3", orlinn, 50, 45, true);
647    event:AddEventLinkAtEnd("Orlinn runs to point 4");
648
649    event = vt_map.PathMoveSpriteEvent.Create("Orlinn runs to point 4", orlinn, 50, 38, true);
650    event:AddEventLinkAtEnd("Orlinn runs to point 1");
651
652    vt_map.ScriptedSpriteEvent.Create("Kalya stops running", kalya, "Terminate_all_events", "");
653
654    vt_map.AnimateSpriteEvent.Create("Bronann sighs", bronann, "hero_stance", 6000);
655
656    event = vt_map.PathMoveSpriteEvent.Create("Kalya comes back next to Bronann", kalya, 44, 49, true);
657    event:AddEventLinkAtEnd("Kalya looks at Bronann");
658
659    dialogue = vt_map.SpriteDialogue.Create();
660    text = vt_system.Translate("When I catch you, I'll make you wish you were never born! Rahh!");
661    dialogue:AddLine(text, kalya);
662    text = vt_system.Translate("Yiek!");
663    dialogue:AddLine(text, orlinn);
664    text = vt_system.Translate("Come here, now!");
665    dialogue:AddLine(text, kalya);
666    text = vt_system.Translate("Yiek!");
667    dialogue:AddLine(text, orlinn);
668    text = vt_system.Translate("(Sigh)... I should have stayed home today.");
669    dialogue:AddLineEvent(text, bronann, "Bronann sighs", "");
670    text = vt_system.Translate("Ouch, why is my head hurting so much?");
671    dialogue:AddLineEvent(text, bronann, "", "Kalya stops running");
672    text = vt_system.Translate("Are you ok? We should head back to the village so Lilly can examine you.");
673    dialogue:AddLineEvent(text, kalya, "Kalya comes back next to Bronann", "");
674    text = vt_system.Translate("I still feel really dizzy, but I'll be ok.");
675    dialogue:AddLine(text, bronann);
676    text = vt_system.Translate("I'm relieved that Orlinn is fine as well. Speaking of that, Orlinn! Stop running and come here right now!");
677    dialogue:AddLine(text, kalya);
678    event = vt_map.DialogueEvent.Create("Bronann sighs and think", dialogue);
679    event:AddEventLinkAtEnd("Orlinn stops running");
680    event:AddEventLinkAtEnd("Last dialogue");
681
682    vt_map.ScriptedSpriteEvent.Create("Orlinn stops running", orlinn, "Terminate_all_events", "");
683
684    event = vt_map.PathMoveSpriteEvent.Create("Orlinn comes back next to Bronann", orlinn, 40, 49, true);
685    event:AddEventLinkAtEnd("Orlinn looks at Bronann");
686
687    vt_map.ScriptedEvent.Create("Play wind music", "play_wind_music", "");
688
689    dialogue = vt_map.SpriteDialogue.Create();
690    text = vt_system.Translate("Owww. Alright.");
691    dialogue:AddLineEventEmote(text, orlinn, "Fade out music", "Orlinn comes back next to Bronann", "sweat drop");
692    text = vt_system.Translate("Now, Orlinn, tell us. Why on earth did you go into the forest alone, and how did you get there so quickly?");
693    dialogue:AddLine(text, kalya);
694    text = vt_system.Translate("I don't know.");
695    dialogue:AddLineEmote(text, orlinn, "interrogation");
696    text = vt_system.Translate("Why was that giant wolf protecting you?");
697    dialogue:AddLine(text, bronann);
698    text = vt_system.Translate("What was that crystal? Why did you want to 'become one' with it?");
699    dialogue:AddLine(text, kalya);
700    text = vt_system.Translate("I, I, I sincerely don't know. I swear! It was like I was... dreaming.");
701    dialogue:AddLineEmote(text, orlinn, "sweat drop");
702    text = vt_system.Translate("I merely remember a voice in my head, telling me to come.");
703    dialogue:AddLineEmote(text, orlinn, "thinking dots");
704    text = vt_system.Translate("You know you won't get away with this. When you see Herth...");
705    dialogue:AddLineEmote(text, kalya, "thinking dots");
706    text = vt_system.Translate("I swear it's the truth!");
707    dialogue:AddLineEmote(text, orlinn, "exclamation");
708    text = vt_system.Translate("Making one with the crystal, huh?");
709    dialogue:AddLineEmote(text, bronann, "sweat drop");
710    text = vt_system.Translate("Let's not panic. Bronann, you look fine. Anyway, we'd better get back to the village and see the elders as soon as possible.");
711    dialogue:AddLineEventEmote(text, kalya, "", "Play wind music", "thinking dots");
712    event = vt_map.DialogueEvent.Create("Last dialogue", dialogue);
713    event:AddEventLinkAtEnd("kalya goes back to party");
714    event:AddEventLinkAtEnd("orlinn goes back to party");
715
716    event = vt_map.PathMoveSpriteEvent.Create("kalya goes back to party", kalya, bronann, false);
717    event:AddEventLinkAtEnd("end of crystal event");
718
719    event = vt_map.PathMoveSpriteEvent.Create("orlinn goes back to party", orlinn, bronann, false);
720
721    event = vt_map.ScriptedEvent.Create("end of crystal event", "end_of_crystal_event", "");
722    event:AddEventLinkAtEnd("Map:Popstate()");
723end
724
725-- zones
726local to_forest_cave2_zone = nil
727local wolf_battle_zone = nil
728
729-- Create the different map zones triggering events
730function _CreateZones()
731    -- N.B.: left, right, top, bottom
732    to_forest_cave2_zone = vt_map.CameraZone.Create(28, 33, 23, 25);
733    to_forest_cave2_zone:SetInteractionIcon("data/gui/map/exit_anim.lua")
734
735    wolf_battle_zone = vt_map.CameraZone.Create(38, 46, 63, 66);
736end
737
738-- Check whether the active camera has entered a zone. To be called within Update()
739function _CheckZones()
740    if (to_forest_cave2_zone:IsCameraEntering() == true) then
741        hero:SetMoving(false);
742        EventManager:StartEvent("to forest cave 2");
743    elseif (wolf_battle_zone:IsCameraEntering() == true) then
744        if (GlobalManager:GetGameEvents():DoesEventExist("story", "Fenrir beaten") == false) then
745            hero:SetMoving(false);
746            EventManager:StartEvent("Fenrir Battle");
747        end
748    end
749end
750
751-- Map Custom functions
752-- Used through scripted events
753
754-- Effect time used when applying the heal light effect
755local heal_effect_time = 0;
756local heal_color = vt_video.Color(0.0, 0.0, 1.0, 1.0);
757
758local flash_effect_time = 0;
759local flash_color = vt_video.Color(1.0, 1.0, 1.0, 1.0);
760
761local crystal_appearance_time = 0;
762local crystal_visible = false;
763local crystal_light_effect = nil
764
765map_functions = {
766
767    SetCamera = function(sprite)
768        Map:SetCamera(sprite, 800);
769    end,
770
771    Sprite_Collision_on = function(sprite)
772        if (sprite ~= nil) then
773            sprite:SetCollisionMask(vt_map.MapMode.ALL_COLLISION);
774        end
775    end,
776
777    Sprite_Collision_off = function(sprite)
778        if (sprite ~= nil) then
779            sprite:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
780        end
781    end,
782
783    Map_PopState = function()
784        Map:PopState();
785    end,
786
787    heal_party = function()
788        hero:SetMoving(false);
789        -- Should be sufficient to heal anybody
790        local character_handler = GlobalManager:GetCharacterHandler()
791        character_handler:GetActiveParty():AddHitPoints(10000)
792        character_handler:GetActiveParty():AddSkillPoints(10000)
793        Map:SetStamina(10000)
794        Map:RemoveNegativeActiveStatusEffects()
795        AudioManager:PlaySound("data/sounds/heal_spell.wav");
796        heal_effect:SetPosition(hero:GetXPosition(), hero:GetYPosition());
797        heal_effect:Start();
798        heal_effect_time = 0;
799    end,
800
801    heal_done = function()
802        heal_effect_time = heal_effect_time + SystemManager:GetUpdateTime();
803
804        if (heal_effect_time < 300.0) then
805            heal_color:SetAlpha(heal_effect_time / 300.0 / 3.0);
806            Map:GetEffectSupervisor():EnableLightingOverlay(heal_color);
807            return false;
808        end
809
810        if (heal_effect_time < 1000.0) then
811            heal_color:SetAlpha(((1000.0 - heal_effect_time) / 700.0) / 3.0);
812            Map:GetEffectSupervisor():EnableLightingOverlay(heal_color);
813            return false;
814        end
815
816        return true;
817    end,
818
819    make_wolf_invisible = function()
820        wolf:SetVisible(false);
821        wolf:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
822
823        GlobalManager:GetGameEvents():SetEventValue("story", "Fenrir beaten", 1);
824    end,
825
826    post_boss_dialogue_start = function()
827        Map:PushState(vt_map.MapMode.STATE_SCENE);
828        hero:SetMoving(false);
829        hero:SetDirection(vt_map.MapMode.NORTH);
830
831        bronann:SetDirection(hero:GetDirection())
832        bronann:SetPosition(hero:GetXPosition(), hero:GetYPosition())
833        bronann:SetVisible(true)
834        Map:SetCamera(bronann)
835
836        hero:SetVisible(false)
837        hero:SetPosition(0, 0)
838
839        kalya:SetPosition(bronann:GetXPosition(), bronann:GetYPosition());
840        kalya:SetVisible(true);
841        kalya:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
842
843        move_next_to_bronann_event:SetDestination(bronann:GetXPosition() + 2.0, bronann:GetYPosition(), false);
844    end,
845
846    first_tremor = function()
847        Map:GetEffectSupervisor():ShakeScreen(1.0, 2000, vt_mode_manager.EffectSupervisor.SHAKE_FALLOFF_SUDDEN);
848        AudioManager:PlaySound("data/sounds/rumble.wav");
849    end,
850
851    bronann_kalya_exclamation = function()
852        bronann:Emote("exclamation", vt_map.MapMode.ANIM_NORTH);
853        kalya:Emote("exclamation", vt_map.MapMode.ANIM_NORTH);
854        AudioManager:PlaySound("data/sounds/rumble.wav");
855    end,
856
857    make_crystal_appear = function()
858        GlobalManager:GetGameEvents():SetEventValue("story", "layna_forest_crystal_appearance", 1);
859    end,
860
861    make_crystal_appear_update = function()
862        if (GlobalManager:GetGameEvents():GetEventValue("story", "layna_forest_crystal_appearance") == 0) then
863            return true;
864        end
865
866        crystal_appearance_time = crystal_appearance_time + SystemManager:GetUpdateTime();
867
868        if (crystal_visible == false and crystal_appearance_time >= 10000) then
869            -- Add a light upon the crystal
870            crystal_light_effect = vt_map.Light.Create("data/visuals/lights/sun_flare_light_secondary.lua",
871                    "data/visuals/lights/sun_flare_light_secondary.lua",
872                    41.2, 43.0,
873                    vt_video.Color(0.8, 0.8, 1.0, 0.3),
874                    vt_video.Color(0.8, 0.8, 0.85, 0.2));
875
876            -- Set the  crystal to visible while the white flash
877            crystal:SetVisible(true);
878            crystal_effect:Start();
879            crystal_visible = true;
880        end
881        return false;
882    end,
883
884    white_flash = function()
885        flash_effect_time = 0;
886    end,
887
888    white_flash_update = function()
889        flash_effect_time = flash_effect_time + SystemManager:GetUpdateTime();
890
891        if (flash_effect_time < 300.0) then
892            flash_color:SetAlpha(flash_effect_time / 300.0);
893            Map:GetEffectSupervisor():EnableLightingOverlay(flash_color);
894            return false;
895        elseif (flash_effect_time >= 300.0 and flash_effect_time <= 1000.0) then
896            if (crystal_visible == true) then
897                -- hide the crystal and the effect
898                crystal_effect:Stop();
899                crystal:SetVisible(false);
900                crystal:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
901                crystal_light_effect:SetVisible(false);
902                AudioManager:PlaySound("data/sounds/crystal_chime.wav");
903                crystal_visible = false;
904            end
905            return false; -- do nothing
906        elseif (flash_effect_time > 1000.0 and flash_effect_time < 2500.0) then
907            flash_color:SetAlpha(1.0 - (flash_effect_time - 1000.0) / (2500.0 - 1000.0));
908            Map:GetEffectSupervisor():EnableLightingOverlay(flash_color);
909            return false;
910        end
911
912        return true;
913    end,
914
915    Terminate_all_events = function(sprite)
916        EventManager:EndAllEvents(sprite);
917    end,
918
919    orlinn_kalya_exclamation = function()
920        orlinn:Emote("exclamation", vt_map.MapMode.ANIM_NORTH);
921        kalya:Emote("exclamation", vt_map.MapMode.ANIM_NORTH);
922
923        -- Restore also their collision mask
924        orlinn:SetCollisionMask(vt_map.MapMode.ALL_COLLISION);
925        kalya:SetCollisionMask(vt_map.MapMode.ALL_COLLISION);
926        -- And prepare for the funny scene
927        orlinn:SetMovementSpeed(vt_map.MapMode.NORMAL_SPEED - 7.0);
928    end,
929
930    fade_out_music = function()
931        AudioManager:FadeOutActiveMusic(2000);
932    end,
933
934    play_funny_music = function()
935        AudioManager:PlayMusic("data/music/Zander Noriega - School of Quirks.ogg");
936    end,
937
938    play_wind_music = function()
939        AudioManager:PlayMusic("data/sounds/wind.ogg");
940    end,
941
942    end_of_crystal_event = function()
943        kalya:SetPosition(0, 0);
944        kalya:SetVisible(false);
945        kalya:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
946        orlinn:SetPosition(0, 0);
947        orlinn:SetVisible(false);
948        orlinn:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
949
950        -- Reset the hero
951        hero:SetPosition(bronann:GetXPosition(), bronann:GetYPosition());
952        hero:SetDirection(bronann:GetDirection())
953        hero:SetVisible(true)
954        bronann:SetVisible(false)
955        bronann:SetPosition(0, 0)
956        Map:SetCamera(hero, 800);
957
958        -- Set event as done
959        GlobalManager:GetGameEvents():SetEventValue("story", "layna_forest_crystal_event_done", 1);
960        -- Start the twilight
961        _HandleTwilight();
962    end
963}
964