1-- Set the namespace according to the map name.
2local ns = {};
3setmetatable(ns, {__index = _G});
4layna_village_kalya_house_script = ns;
5setfenv(1, ns);
6
7-- The map name, subname and location image
8map_name = "Mountain Village of Layna"
9map_image_filename = "data/story/common/locations/mountain_village.png"
10map_subname = "Basement"
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/music/Welcome to Com-Mecha-Mattew_Pablo_OGA.ogg"
15
16-- c++ objects instances
17local Map = nil
18local EventManager = nil
19local Effects = nil
20
21-- the main character handler
22local bronann = nil
23local kalya = nil
24local orlinn = nil
25
26-- A moveable wall hiding the exit
27local fake_wall = nil
28local exit_light = nil
29
30-- the main map loading code
31function Load(m)
32
33    Map = m;
34    Effects = Map:GetEffectSupervisor();
35    EventManager = Map:GetEventSupervisor();
36
37    Map:SetUnlimitedStamina(true);
38
39    _CreateCharacters();
40    _CreateObjects();
41
42    -- Set the camera focus on bronann
43    Map:SetCamera(bronann);
44
45    _CreateEvents();
46    _CreateZones();
47
48    -- Preloads the sad music
49    AudioManager:LoadMusic("data/music/sad_moment.ogg", Map);
50
51    -- If the scene hasn't happened, start it
52    if (GlobalManager:GetGameEvents():GetEventValue("story", "kalya_basement_scene") == 0) then
53        Map:PushState(vt_map.MapMode.STATE_SCENE);
54        EventManager:StartEvent("Orlinn goes out of the stairs");
55    else
56        -- Set the sad music
57        EventManager:StartEvent("Sad music start", 100);
58    end
59end
60
61-- the map update function handles checks done on each game tick.
62function Update()
63    -- Check whether the character is in one of the zones
64    _CheckZones();
65end
66
67-- Character creation
68function _CreateCharacters()
69    bronann = CreateSprite(Map, "Bronann", 40, 21.5, vt_map.MapMode.GROUND_OBJECT);
70    bronann:SetVisible(false);
71    bronann:SetDirection(vt_map.MapMode.NORTH);
72    bronann:SetMovementSpeed(vt_map.MapMode.NORMAL_SPEED);
73
74    kalya = CreateSprite(Map, "Kalya", 40, 21.5, vt_map.MapMode.GROUND_OBJECT);
75    kalya:SetDirection(vt_map.MapMode.NORTH);
76    kalya:SetMovementSpeed(vt_map.MapMode.NORMAL_SPEED);
77    kalya:SetVisible(false);
78
79    orlinn = CreateSprite(Map, "Orlinn", 40, 21.5, vt_map.MapMode.GROUND_OBJECT);
80    orlinn:SetDirection(vt_map.MapMode.NORTH);
81    orlinn:SetMovementSpeed(vt_map.MapMode.NORMAL_SPEED);
82
83    -- Create the fake wall  out of the object catalog as it is used once,
84    fake_wall = vt_map.PhysicalObject.Create(vt_map.MapMode.GROUND_OBJECT);
85    fake_wall:SetPosition(32.0, 14.0);
86    fake_wall:SetCollPixelHalfWidth(4.0 * 16);
87    fake_wall:SetCollPixelHeight(10.0 * 16);
88    fake_wall:SetImgPixelHalfWidth(4.0 * 16);
89    fake_wall:SetImgPixelHeight(10.0 * 16);
90    fake_wall:AddStillFrame("data/story/layna_village/kalya_house_fake_wall.png");
91
92    exit_light = CreateObject(Map, "Left Window Light", 34, 2, vt_map.MapMode.GROUND_OBJECT);
93    exit_light:SetCollisionMask(vt_map.MapMode.NO_COLLISION);
94    exit_light:SetVisible(false);
95
96    -- Place the characters according to the scene needs
97    if (GlobalManager:GetGameEvents():GetEventValue("story", "kalya_basement_scene") == 1) then
98        bronann:SetVisible(true);
99
100        kalya:SetVisible(true);
101        kalya:SetPosition(28.0, 15.1);
102        kalya:SetDirection(vt_map.MapMode.SOUTH);
103
104        orlinn:SetVisible(true);
105        orlinn:SetPosition(28.0, 17.0);
106        orlinn:SetDirection(vt_map.MapMode.EAST);
107
108        fake_wall:SetVisible(false);
109        fake_wall:SetPosition(0, 0);
110        exit_light:SetVisible(true);
111    else
112        return;
113    end
114
115    -- Load potential previous save point data
116    local x_position = GlobalManager:GetMapData():GetSaveLocationX();
117    local y_position = GlobalManager:GetMapData():GetSaveLocationY();
118    if (x_position ~= 0 and y_position ~= 0) then
119        -- Make the character look at us in that case
120        bronann:SetDirection(vt_map.MapMode.SOUTH);
121        bronann:SetPosition(x_position, y_position);
122    end
123end
124
125function _CreateObjects()
126    vt_map.SavePoint.Create(29.5, 29.0);
127
128    CreateObject(Map, "Barrel1", 25, 19, vt_map.MapMode.GROUND_OBJECT);
129    CreateObject(Map, "Box1", 23, 20, vt_map.MapMode.GROUND_OBJECT);
130    CreateObject(Map, "Box1", 22, 22, vt_map.MapMode.GROUND_OBJECT);
131    CreateObject(Map, "Box1", 23, 24, vt_map.MapMode.GROUND_OBJECT);
132    CreateObject(Map, "Box1", 23.5, 27, vt_map.MapMode.GROUND_OBJECT);
133    CreateObject(Map, "Box1", 21, 19, vt_map.MapMode.GROUND_OBJECT);
134    CreateObject(Map, "Small Wooden Table", 22, 17, vt_map.MapMode.GROUND_OBJECT);
135    CreateObject(Map, "Barrel1", 21, 36, vt_map.MapMode.GROUND_OBJECT);
136    CreateObject(Map, "Barrel1", 22, 37, vt_map.MapMode.GROUND_OBJECT);
137    CreateObject(Map, "Barrel1", 24, 33, vt_map.MapMode.GROUND_OBJECT);
138    CreateObject(Map, "Barrel1", 27, 34, vt_map.MapMode.GROUND_OBJECT);
139    CreateObject(Map, "Barrel1", 29, 33, vt_map.MapMode.GROUND_OBJECT);
140    CreateObject(Map, "Box1", 28, 21, vt_map.MapMode.GROUND_OBJECT);
141
142    -- Chests
143    local chest = CreateTreasure(Map, "kalya_house_basement_chest1", "Wood_Chest1", 25, 22, vt_map.MapMode.GROUND_OBJECT);
144    chest:AddItem(50002, 1); -- Sturdy boots
145
146    chest = CreateTreasure(Map, "kalya_house_basement_chest2", "Wood_Chest1", 21, 28, vt_map.MapMode.GROUND_OBJECT);
147    chest:AddItem(1003, 1); -- 1 Elixir
148
149    chest = CreateTreasure(Map, "kalya_house_basement_chest3", "Wood_Chest1", 24, 35, vt_map.MapMode.GROUND_OBJECT);
150    chest:AddItem(3001, 1); -- 1 Copper Ore
151end
152
153
154-- Creates all events and sets up the entire event sequence chain
155function _CreateEvents()
156    local event = nil
157    local dialogue = nil
158    local text = nil
159
160    -- Triggered events
161    vt_map.MapTransitionEvent.Create("to Mt Elbrus", "data/story/mt_elbrus/mt_elbrus_path1_map.lua",
162                                    "data/story/mt_elbrus/mt_elbrus_path1_script.lua", "from_kalya_house_basement");
163
164    -- Generic events
165    vt_map.ChangeDirectionSpriteEvent.Create("Orlinn looks east", orlinn, vt_map.MapMode.EAST);
166    vt_map.ChangeDirectionSpriteEvent.Create("Kalya looks east", kalya, vt_map.MapMode.EAST);
167    vt_map.ChangeDirectionSpriteEvent.Create("Kalya looks south", kalya, vt_map.MapMode.SOUTH);
168    vt_map.ChangeDirectionSpriteEvent.Create("Kalya looks west", kalya, vt_map.MapMode.WEST);
169    vt_map.ChangeDirectionSpriteEvent.Create("Bronann looks north", bronann, vt_map.MapMode.NORTH);
170    vt_map.LookAtSpriteEvent.Create("Kalya looks at Orlinn", kalya, orlinn);
171    vt_map.LookAtSpriteEvent.Create("Bronann looks at Orlinn", bronann, orlinn);
172    vt_map.LookAtSpriteEvent.Create("Kalya looks at Bronann", kalya, bronann);
173    vt_map.LookAtSpriteEvent.Create("Bronann looks at Kalya", bronann, kalya);
174
175    -- The scene before going outside
176    event = vt_map.PathMoveSpriteEvent.Create("Orlinn goes out of the stairs", orlinn, 28.0, 18.0, false);
177    event:AddEventLinkAtEnd("Orlinn looks east");
178    event:AddEventLinkAtEnd("Make Kalya visible", 300);
179
180    event = vt_map.ScriptedEvent.Create("Make Kalya visible", "make_kalya_visible", "");
181    event:AddEventLinkAtEnd("Kalya goes out of the stairs");
182
183    event = vt_map.PathMoveSpriteEvent.Create("Kalya goes out of the stairs", kalya, 30.3, 20.0, false);
184    event:AddEventLinkAtEnd("Kalya looks east");
185    event:AddEventLinkAtEnd("Make Bronann visible");
186
187    event = vt_map.ScriptedEvent.Create("Make Bronann visible", "make_bronann_visible", "");
188    event:AddEventLinkAtEnd("Bronann goes in front of Kalya");
189
190    event = vt_map.PathMoveSpriteEvent.Create("Bronann goes in front of Kalya", bronann, 35.0, 20.0, false);
191    event:AddEventLinkAtEnd("Dialogue part 1");
192
193    dialogue = vt_map.SpriteDialogue.Create();
194    text = vt_system.Translate("Bronann, how do you feel?");
195    dialogue:AddLine(text, kalya);
196    text = vt_system.Translate("Better. Somehow, the pain faded away the second I entered here.");
197    dialogue:AddLineEmote(text, bronann, "thinking dots");
198    text = vt_system.Translate("By the way, where are we?");
199    dialogue:AddLineEmote(text, bronann, "interrogation");
200    text = vt_system.Translate("In our basement. The other stairs there are leading to my room. This house is an ancient sanctuary, so it might explain why you're feeling better.");
201    dialogue:AddLineEvent(text, kalya, "Kalya looks south", "Kalya looks east");
202    text = vt_system.Translate("Orlinn. Go get our packings. We're leaving.");
203    dialogue:AddLineEvent(text, kalya, "Kalya looks at Orlinn", "");
204    text = vt_system.Translate("Ok.");
205    dialogue:AddLineEmote(text, orlinn, "sweat drop");
206    event = vt_map.DialogueEvent.Create("Dialogue part 1", dialogue);
207    event:AddEventLinkAtEnd("Orlinn goes upstairs");
208    event:AddEventLinkAtEnd("Kalya looks at Orlinn", 500);
209    event:AddEventLinkAtEnd("Kalya looks at Orlinn", 800);
210    event:AddEventLinkAtEnd("Bronann looks at Orlinn", 800);
211    event:AddEventLinkAtEnd("Kalya looks south", 1500);
212    event:AddEventLinkAtEnd("Bronann looks at Orlinn", 1500);
213
214    event = vt_map.PathMoveSpriteEvent.Create("Orlinn goes upstairs", orlinn, 40.0, 27.5, false);
215    event:AddEventLinkAtEnd("Make Orlinn invisible");
216
217    event = vt_map.ScriptedEvent.Create("Make Orlinn invisible", "make_orlinn_invisible", "");
218    event:AddEventLinkAtEnd("Dialogue part 2");
219
220    vt_map.AnimateSpriteEvent.Create("Bronann looks angry", bronann, "hero_stance", 0); -- 0 means forever
221
222    vt_map.ScriptedEvent.Create("Stop Bronann looks angry", "terminate_bronann_events", "");
223
224    vt_map.ScriptedEvent.Create("Sad music start", "sad_music_start", "");
225
226    vt_map.ScriptedEvent.Create("FadeOutActiveMusic", "fade_out_music", "");
227
228    dialogue = vt_map.SpriteDialogue.Create();
229    text = vt_system.Translate("We're leaving the village now.");
230    dialogue:AddLine(text, kalya);
231    text = vt_system.Translate("I feel dizzy. So many things have happened in such little time.");
232    dialogue:AddLineEventEmote(text, bronann, "Bronann looks at Kalya", "", "sweat drop");
233    text = vt_system.Translate("The soldiers will be here any minute. We'll leave to the north and cross the north-west plain up to...");
234    dialogue:AddLine(text, kalya);
235    text = vt_system.Translate("No.");
236    dialogue:AddLineEvent(text, bronann, "FadeOutActiveMusic", "");
237    text = vt_system.Translate("No?!");
238    dialogue:AddLineEventEmote(text, kalya, "Kalya looks at Bronann", "", "exclamation");
239    text = vt_system.Translate("No, I won't follow you anymore.");
240    dialogue:AddLine(text, bronann);
241    text = vt_system.Translate("Look, I...");
242    dialogue:AddLineEmote(text, kalya, "sweat drop");
243    text = vt_system.Translate("Enough!");
244    dialogue:AddLineEventEmote(text, bronann, "Bronann looks angry", "", "exclamation");
245    text = vt_system.Translate("Nobody told me what was happening. Herth and the Lord seemed to know each other. And now you...");
246    dialogue:AddLine(text, bronann);
247    text = vt_system.Translate("You seem so calm, ready, and prepared.");
248    dialogue:AddLine(text, bronann);
249    text = vt_system.Translate("Bronann, I ...");
250    dialogue:AddLine(text, kalya);
251    text = vt_system.Translate("Enough! You hid everything from me just like everyone else. You're a liar! I won't be manipulated anymore!");
252    dialogue:AddLineEmote(text, bronann, "exclamation");
253    text = vt_system.Translate("Bronann, you'll get everything explained in time, I...");
254    dialogue:AddLineEmote(text, kalya, "sweat drop");
255    text = vt_system.Translate("No! I won't go unless you tell me the truth now!");
256    dialogue:AddLineEmote(text, bronann, "exclamation");
257    text = vt_system.Translate("... Fine.");
258    dialogue:AddLineEventEmote(text, kalya, "Kalya looks south", "", "sweat drop");
259    text = vt_system.Translate("...");
260    dialogue:AddLineEvent(text, bronann, "", "Sad music start");
261    text = vt_system.Translate("I knew the crystal would appear.");
262    dialogue:AddLineEvent(text, kalya, "Kalya looks west", "");
263    text = vt_system.Translate("What?");
264    dialogue:AddLineEventEmote(text, bronann, "Stop Bronann looks angry", "", "exclamation");
265    text = vt_system.Translate("But I didn't know who it would choose.");
266    dialogue:AddLineEvent(text, kalya, "Kalya looks east", "");
267    text = vt_system.Translate("Herth prepared me all my life for this very day.");
268    dialogue:AddLine(text, kalya);
269    text = vt_system.Translate("He trained me, taught me magic, and told me the crystal would appear one day.");
270    dialogue:AddLine(text, kalya);
271    text = vt_system.Translate("He thought that I would be the one to be chosen by the crystal. However, it seems he was wrong. Now, I am to look after you.");
272    dialogue:AddLineEvent(text, kalya, "Kalya looks west", "");
273    text = vt_system.Translate("You must believe me Bronann.");
274    dialogue:AddLineEvent(text, kalya, "Kalya looks south", "");
275    text = vt_system.Translate("The crystal chose me? But I'm just...");
276    dialogue:AddLineEmote(text, bronann, "sweat drop");
277    text = vt_system.Translate("Someone brave enough to jump between it and my brother.");
278    dialogue:AddLineEvent(text, kalya, "Kalya looks east", "");
279    text = vt_system.Translate("It should have been me. But I couldn't move. And now, I have to fix my mistake.");
280    dialogue:AddLineEvent(text, kalya, "Kalya looks east", "");
281    text = vt_system.Translate("How?");
282    dialogue:AddLineEmote(text, bronann, "interrogation");
283    text = vt_system.Translate("I...");
284    dialogue:AddLine(text, kalya);
285    text = vt_system.Translate("Sis!");
286    dialogue:AddLine(text, orlinn);
287    event = vt_map.DialogueEvent.Create("Dialogue part 2", dialogue);
288    event:AddEventLinkAtEnd("Make Orlinn visible");
289
290    event = vt_map.ScriptedEvent.Create("Make Orlinn visible", "make_orlinn_visible", "");
291    event:AddEventLinkAtEnd("Orlinn comes back to them");
292    event:AddEventLinkAtEnd("Kalya looks at Orlinn");
293    event:AddEventLinkAtEnd("Bronann looks at Orlinn");
294
295    event = vt_map.PathMoveSpriteEvent.Create("Orlinn comes back to them", orlinn, 33.0, 23.0, true);
296    event:AddEventLinkAtEnd("Kalya looks at Orlinn");
297    event:AddEventLinkAtEnd("Bronann looks at Orlinn");
298    event:AddEventLinkAtEnd("Dialogue part 3");
299
300    dialogue = vt_map.SpriteDialogue.Create();
301    text = vt_system.Translate("Sis! They're in front of the house!");
302    dialogue:AddLine(text, orlinn);
303    text = vt_system.Translate("Quick, we must go now!");
304    dialogue:AddLineEventEmote(text, kalya, "Bronann looks at Kalya", "", "exclamation");
305    text = vt_system.Translate("We won't be able to come back here once we leave. So feel free to pick up everything you need and prepare yourself.");
306    dialogue:AddLineEvent(text, kalya, "Kalya looks at Bronann", "");
307    text = vt_system.Translate("Wait! There is one more thing. Why are you calling your own father by his actual name?");
308    dialogue:AddLineEmote(text, bronann, "thinking dots");
309    text = vt_system.Translate("That's because he's not our father.");
310    dialogue:AddLine(text, orlinn);
311    text = vt_system.Translate("Our parents were killed a long time ago.");
312    dialogue:AddLineEventEmote(text, orlinn, "Bronann looks at Orlinn", "", "sweat drop");
313    text = vt_system.Translate("Orlinn...");
314    dialogue:AddLineEvent(text, kalya, "Kalya looks at Orlinn", "");
315    text = vt_system.Translate("Don't worry, sis. It's fine, we can tell him.");
316    dialogue:AddLine(text, orlinn);
317    text = vt_system.Translate("I also left my parents behind.");
318    dialogue:AddLineEmote(text, bronann, "sweat drop");
319    text = vt_system.Translate("They'll be fine, Bronann. We must prevent Banesore from obtaining the crystal.");
320    dialogue:AddLineEvent(text, kalya, "Kalya looks at Bronann", "");
321    text = vt_system.Translate("Anyway, let's go now.");
322    dialogue:AddLine(text, kalya);
323    event = vt_map.DialogueEvent.Create("Dialogue part 3", dialogue);
324    event:AddEventLinkAtEnd("Kalya goes triggering the secret path");
325
326    vt_map.ScriptedEvent.Create("Click sound", "click_sound", "");
327
328    vt_map.ScriptedEvent.Create("Wall sound", "wall_sound", "");
329
330    event = vt_map.PathMoveSpriteEvent.Create("Kalya goes triggering the secret path", kalya, 28.0, 15.1, false);
331    event:AddEventLinkAtEnd("Bronann looks north");
332    event:AddEventLinkAtEnd("Click sound");
333    event:AddEventLinkAtEnd("Wall sound", 700);
334    event:AddEventLinkAtEnd("Kalya triggers the secret path", 1000);
335
336    event = vt_map.ScriptedEvent.Create("Kalya triggers the secret path", "kalya_triggers_the_secret_path", "");
337    event:AddEventLinkAtEnd("Kalya looks south", 300);
338    event:AddEventLinkAtEnd("Orlinn goes near his sister", 700);
339
340    event = vt_map.PathMoveSpriteEvent.Create("Orlinn goes near his sister", orlinn, 28.0, 17.0, false);
341    event:AddEventLinkAtEnd("Orlinn looks east");
342    event:AddEventLinkAtEnd("Dialogue part 4");
343
344    dialogue = vt_map.SpriteDialogue.Create();
345    text = vt_system.Translate("Wow!");
346    dialogue:AddLineEmote(text, bronann, "exclamation");
347    text = vt_system.Translate("It's time.");
348    dialogue:AddLine(text, kalya);
349    event = vt_map.DialogueEvent.Create("Dialogue part 4", dialogue);
350    event:AddEventLinkAtEnd("End of basement dialogue");
351
352    vt_map.ScriptedEvent.Create("End of basement dialogue", "end_of_basement_dialogue", "");
353
354    -- Can't go downstairs
355    dialogue = vt_map.SpriteDialogue.Create();
356    text = vt_system.Translate("We can't go back now.");
357    dialogue:AddLine(text, bronann);
358    vt_map.DialogueEvent.Create("Can't go downstairs", dialogue);
359
360    dialogue = vt_map.SpriteDialogue.Create();
361    text = vt_system.Translate("It's my room upstairs. Don't even think about it!");
362    dialogue:AddLine(text, kalya);
363    vt_map.DialogueEvent.Create("Can't go upstairs", dialogue);
364
365    -- Dialogues for after the scene
366    dialogue = vt_map.SpriteDialogue.Create("ep1_layna_village_kalya_tells_its_time");
367    text = vt_system.Translate("It's time.");
368    dialogue:AddLine(text, kalya);
369    kalya:AddDialogueReference(dialogue);
370
371    dialogue = vt_map.SpriteDialogue.Create("ep1_layna_village_orlinn_is_sad");
372    text = vt_system.Translate("...");
373    dialogue:AddLine(text, orlinn);
374    orlinn:AddDialogueReference(dialogue);
375end
376
377-- zones
378local downstairs_zone = nil
379local upstairs_zone = nil
380local to_mt_elbrus_zone = nil
381
382-- Create the different map zones triggering events
383function _CreateZones()
384    -- N.B.: left, right, top, bottom
385    downstairs_zone = vt_map.CameraZone.Create(38, 42, 20, 22);
386    upstairs_zone = vt_map.CameraZone.Create(38, 42, 26, 28);
387    to_mt_elbrus_zone = vt_map.CameraZone.Create(30, 36, 12, 14);
388end
389
390-- Check whether the active camera has entered a zone. To be called within Update()
391function _CheckZones()
392    if (Map:CurrentState() ~= vt_map.MapMode.STATE_EXPLORE) then
393        return;
394    end
395
396    if (downstairs_zone:IsCameraEntering() == true) then
397        bronann:SetMoving(false);
398        EventManager:StartEvent("Can't go downstairs");
399    elseif (upstairs_zone:IsCameraEntering() == true) then
400        bronann:SetMoving(false);
401        EventManager:StartEvent("Can't go upstairs");
402    elseif (to_mt_elbrus_zone:IsCameraEntering() == true) then
403        bronann:SetMoving(false);
404        EventManager:StartEvent("to Mt Elbrus");
405    end
406end
407
408-- Map Custom functions
409-- Used through scripted events
410map_functions = {
411    make_kalya_visible =  function()
412        kalya:SetVisible(true);
413    end,
414
415    make_bronann_visible =  function()
416        bronann:SetVisible(true);
417    end,
418
419    make_orlinn_invisible =  function()
420        orlinn:SetVisible(false);
421    end,
422
423    fade_out_music = function()
424        AudioManager:FadeOutActiveMusic(1000);
425    end,
426
427    sad_music_start = function()
428        AudioManager:PlayMusic("data/music/sad_moment.ogg");
429    end,
430
431    terminate_bronann_events = function()
432        EventManager:EndAllEvents(bronann);
433    end,
434
435    make_orlinn_visible = function()
436        orlinn:SetVisible(true);
437    end,
438
439    click_sound = function()
440        AudioManager:PlaySound("data/sounds/menu_click_01.wav");
441    end,
442
443    wall_sound = function()
444        AudioManager:PlaySound("data/sounds/cave-in.ogg");
445    end,
446
447    kalya_triggers_the_secret_path =  function()
448        Effects:ShakeScreen(0.6, 1000, vt_mode_manager.EffectSupervisor.SHAKE_FALLOFF_GRADUAL);
449        fake_wall:SetVisible(false);
450        fake_wall:SetPosition(0, 0);
451        exit_light:SetVisible(true);
452    end,
453
454    end_of_basement_dialogue = function()
455        Map:PopState();
456        GlobalManager:GetGameEvents():SetEventValue("story", "kalya_basement_scene", 1);
457        GlobalManager:GetGameQuests():AddQuestLog("flee_from_the_dark_soldiers");
458    end,
459}
460