summaryrefslogtreecommitdiff
path: root/npc/012-1/gwendolyn.txt
blob: 42953ddf19ef99f505d9b7113ab1b00d6afc0a16 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
// TMW2 Script
// Author:
//    The Mana World Team
// Edited by:
//    Jesusalva
// Description:
//    Archery Trainer

012-1,88,52,0	script	Gwendolyn	NPC_BOWMASTER,{
    .@q=getq(HurnscaldQuest_HarkEye);
    .@fbow=getq(HurnscaldQuest_ForestBow);

    if (.@q == 6) goto L_State6;
    if (.@q == 5) goto L_State5;
    if (.@q == 4) goto L_State4;
    if (.@q == 3) goto L_State3;
    if (.@q == 2) goto L_State2;
    if (.@q == 1) goto L_State1;

    mesn l("Gwendolyn Bowmaker");
    mesq l("Hey there. My name is Gwendolyn Bowmaker; I'm the granddaughter of the famous Glinda Bowmaker.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("She and her husband Simon Bowmaker, vowed to teach the ways of archery to those with willpower, and allow everyone to use a bow.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("I intend to continue with my family's tradition, by teaching the Way of Archery.");
    setq HurnscaldQuest_HarkEye, 1;
    next;

L_State1:
    mesn l("Gwendolyn Bowmaker");
    mesq l("Are you interested in becoming a student of Archery?");
    next;
    menu
        l("I want to become an archer!"),L_Fee,
        l("I'm not interested right now."),L_Abort;

L_Fee:
    mes "";
    mesn l("Gwendolyn Bowmaker");
    mesq l("Wonderful! My fee is @@. This fee is the first step in separating those with willpower, from those without.", .SCHOOLFEE);
    next;
    menu
        l("That's a lot, but I think it will be worth it."),L_Next,
        l("I'm not sure I want to spend that much."),L_Abort;

L_Next:
    mes "";
    if (Zeny < .SCHOOLFEE)
        goto L_No_Money;

    Zeny = Zeny - .SCHOOLFEE;
    setq HurnscaldQuest_HarkEye, 2;

    mesn l("Gwendolyn Bowmaker");
    mesq l("Great! The first thing you need is, obviously, a bow. You should not use any you come across, but a high quality one.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("Inside this house is my brother Alan. He knows how to make Forest Bows of exquisite quality.");
    next;

    if (countitem("ForestBow") < 1) {
        goto L_Close;
    }
    select
        l("I already have a Forest Bow.");
    mes "";

L_State2:
    mesn l("Gwendolyn Bowmaker");
    mesq l("Let me see your bow.");
    next;

    if (countitem("ForestBow") < 1)
        goto L_NoBow;
    if (.@fbow < 2)
        goto L_FakeBow;

    setq HurnscaldQuest_HarkEye, 3;
    mesn l("Gwendolyn Bowmaker");
    mesq l("Very well, this looks fine. It is time for your first lesson.");
    next;
    goto L_Lesson;

L_Lesson:
    mesn l("Gwendolyn Bowmaker");
    mesq l("The advantage of fighting with a ranged weapon is that you can stay out of the enemy's range. So there is no need to spend training on your resistance.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("But remember: This makes you much more vulnerable, and you usually cannot hit from too close, so watch your step and don't stumble into your enemy's attack.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("Also your strength doesn't matter much. It helps you to carry more arrows with you, but nothing a few trips to the store won't do.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("The most important thing to improve is your dexterity. When you use a bow, it is your dexterity that determines if you are able to hit your enemy where it hurts most.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("Also worth mentioning is how to improve your ability to shoot fast. You need to be agile to grab a new arrow from your quiver and aim for the next shot before your enemy has recovered from your last.");
    next;

L_State3:
    mesn l("Gwendolyn Bowmaker");
    mesq l("To demonstrate that you understood what I'm trying to teach you, you should go and fight against some snakes. I know they're strong, but that's not important to an archer.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("To prove me your results, bring me @@ @@, @@ @@ and @@ @@.",
            .CAVE_EGGS_AMOUNT, getitemlink(CaveSnakeEgg),
            .SNAKE_EGGS_AMOUNT, getitemlink(SnakeEgg),
            .MOUNTAIN_EGGS_AMOUNT, getitemlink(MountainSnakeEgg));
    next;
    menu
        l("Can you please repeat your lesson?"),L_Lesson,
        l("I will go and hunt some snakes."),L_Close,
        l("I have what you want."),L_Next1;

L_Next1:
    mes "";
    if (countitem("CaveSnakeEgg") < .CAVE_EGGS_AMOUNT
        ||countitem("SnakeEgg") < .SNAKE_EGGS_AMOUNT
        ||countitem("MountainSnakeEgg") < .MOUNTAIN_EGGS_AMOUNT)
            goto L_Insufficient;

    delitem "CaveSnakeEgg", .CAVE_EGGS_AMOUNT;
    delitem "SnakeEgg", .SNAKE_EGGS_AMOUNT;
    delitem "MountainSnakeEgg", .MOUNTAIN_EGGS_AMOUNT;

    getexp .QUEST_EGG_EXP, 100;

    setq HurnscaldQuest_HarkEye, 4;

    mesn l("Gwendolyn Bowmaker");
    mesq l("Very well. That will make a great meal. You pass!");
    next;

L_State4:
    if (BaseLevel < .BASELEVEL_GAME)
        goto L_NotReady;
    if (!MAGIC_LVL)
        goto L_NotReady;
    mesc l("Gwendolyn takes an analyzing look at you. Then she nods.");
    next;
    setq HurnscaldQuest_HarkEye, 5;
    mesn l("Gwendolyn Bowmaker");
    mesq l("Ok. You have made great progress. I think you are ready for further tasks.");
    next;
    goto L_Explain;

L_Explain:
    mes "";
    mesn l("Gwendolyn Bowmaker");
    mesq l("As you might have noticed, it depends on many circumstances if your arrow finds its target. Your shot may be too powerful or too weak, so the arrow goes far beyond your target or hits the ground before it reaches its destination.");
    next;
    mesq l("The greater the distance to your target is, the more important is the strength and direction of the wind. Even if you are exploring a cave, there might be air flow caused by the corners in the cave.");
    next;
    mesq l("Ok, you can see that target over there? I will tell you how strong the wind blows and from which direction. Then you will try to hit the target by moving right or left and decide how powerful you want to shoot.");
    next;
    goto L_State5;

L_State5:
    // needed for the minigame:
    .@wdX = 0; // wind direction x-coordinate, rand
    .@wdY = 0; // wind direction y-coordinate, rand
    // set .@wp, 0; // windpower
    .@spX = 0; // start position x-coordinate, player decision
    // set .@spY, 0; // start position y-coordinate, const
    .@sp = 0; // shotpower, player decision
    //set .@targetX, 0; // target position, const
    //set .@targetY, 20; // target position, const
    .@pointX = 0; // point the player hits, x-coordinate
    .@pointY = 0; // point the player hits, y-coordinate
    .@wdIndex = 0;
    //
    mesn l("Gwendolyn Bowmaker");
    mesq l("Show me what you can!");
    next;
    menu
        l("Can you please explain the task again?"),L_Explain,
        l("I'm ready, let's start!"),L_Game,
        l("I'm sorry, I will come back later."),L_Close;

L_Game:
    mes "";
    if (countitem(ForestBow) < 1)
        goto L_NoBow;
    if (countitem(TrainingArrow) < 1)
        goto L_Arrows;
    delitem TrainingArrow, 1;
    mesc l("You go to the training field and stand exactly on the same level with the target. The target is located about 13 meters north of you. You take one arrow and look at Gwendolyn.");
    next;

    // possibility for wdX and wdY to become zero is reduced, so windless status is less often
    .@wdX = rand(9) - 4;
    if (.@wdX != 2 && .@wdX !=-2)  .@wdX = rand(9) - 4;
    if (.@wdX == 0)  .@wdX = rand(9) - 4;

    .@wdY = rand(9) - 4;
    if (.@wdY != 2 && .@wdY !=-2)  .@wdY = rand(9) - 4;
    if (.@wdY == 0)  .@wdY = rand(9) - 4;

    // wind direction array, where the wind blows to:
    // 123
    // 456
    // 789
    //here is where the wind comes from, that's why it is the opposite.
    setarray .@wd$,"error1, please report", l("southeast"), l("south"), l("southwest"), l("east"),
                   "error2, please report", l("west"), l("northeast"), l("north"), l("northwest");
    @paramX = .@wdX;
    @paramY = .@wdY;
    callsub S_getDirection;
    .@wdIndex = @returnIndex;

    // Cheat
    if (is_admin() && debug)
        dispbottom l("Wind: @@, @@",.@wdX,.@wdY);

    .@wp_sq = (.@wdX * .@wdX) + (.@wdY * .@wdY);

    if (.@wp_sq == 0)
        goto L_wp0;
    if (.@wp_sq < 3)
        goto L_wp1;
    if (.@wp_sq < 9)
        goto L_wp2;
    if (.@wp_sq < 19)
        goto L_wp3;
    goto L_wp4;


L_wp0:
    mesn l("Gwendolyn Bowmaker");
    mesq lg("You're lucky. It is windless now.");
    next;
    goto L_Start;

L_wp1:
    mesn l("Gwendolyn Bowmaker");
    mesq l("There is a slight breeze coming from @@.", .@wd$[.@wdIndex]);
    next;
    goto L_Start;

L_wp2:
    mesn l("Gwendolyn Bowmaker");
    mesq l("The wind is blowing from @@.", .@wd$[.@wdIndex]);
    next;
    goto L_Start;

L_wp3:
    mesn l("Gwendolyn Bowmaker");
    mesq l("Right now, there is a strong wind blowing from @@.", .@wd$[.@wdIndex]);
    next;
    goto L_Start;

L_wp4:
    mesn l("Gwendolyn Bowmaker");
    mesq l("Here we have a squall from @@.", .@wd$[.@wdIndex]);
    next;
    goto L_Start;

L_Start:
    mesc l("Do you want to go to the left, the right or stay where you are?");
    next;
    menu
        l("I want to move left."),L_Left,
        l("I go right."),L_Right,
        l("I stay."),L_Stay,
        l("I will try it later."),L_Close;

L_Stay:
    .@spX = 0;
    mesc l("You stay where you are..");
    next;
    goto L_Power;

L_Left:
    mesc l("How many steps?");
    next;
    menu
        "1",L_Left1,
        "2",L_Left2,
        "3",L_Left3,
        "4",L_Left4;

L_Left1:
    .@spX = -1;
    mesc l("You take one step to the left.");
    next;
    goto L_Power;

L_Left2:
    .@spX = -2;
    mesc l("You take two steps to the left.");
    next;
    goto L_Power;

L_Left3:
    .@spX = -3;
    mesc l("You take three steps to the left.");
    next;
    goto L_Power;

L_Left4:
    .@spX = -4;
    mesc l("You take four steps to the left.");
    next;
    goto L_Power;

L_Right:
    mesc l("How many steps?");
    next;
    menu
        "1",L_Right1,
        "2",L_Right2,
        "3",L_Right3,
        "4",L_Right4;

L_Right1:
    .@spX = 1;
    mesc l("You take one step to the right.");
    next;
    goto L_Power;

L_Right2:
    .@spX = 2;
    mesc l("You take two steps to the right.");
    next;
    goto L_Power;

L_Right3:
    .@spX = 3;
    mesc l("You take three steps to the right.");
    next;
    goto L_Power;

L_Right4:
    .@spX = 4;
    mesc l("You take four steps to the right.");
    next;
    goto L_Power;

L_Power:
    mes "";
    mesc l("How powerfully do you want to shoot?");
    next;
    select
        l("very weak shot"),
        l("rather weak shot"),
        l("weak shot"),
        l("somewhat weak shot"),
        l("medium shot"),
        l("somewhat powerful shot"),
        l("powerful shot"),
        l("rather powerful shot"),
        l("very powerful shot");

    // we have 9 menu entries, so scale @menu, which is in range 1-9, to a scale in -4 to +4
    .@sp = @menu - 5;
    // calculate where you hit. You range is in [-8, 8] in X and Y as well
    .@pointX = .@wdX + .@spX;
    .@pointY = .@wdY + .@sp;

    // Debug information. If you move wind info to above, you CHEAT.
    if (is_admin()) {
        dispbottom l("Wind: @@, @@",.@wdX,.@wdY);
        dispbottom l("You: @@, @@",.@spX,.@sp);
        dispbottom l("Final: @@, @@",.@pointX,.@pointY);

    }

    if( .@pointX==0 && .@pointY==0 )
        goto L_Success;

    //set .@targethit to these numbers:
    //1,2,3 for left above, above, right above,
    //4,5,6 for left, hit, right
    //7,8,9 for lower left,  below, lower right;
    setarray .@target_direction$, "error3, please report", l("left above"), l("above"), l("right above"), l("left"),
                                  "error4, please report", l("right"), l("lower left"), l("below"), l("lower right");

    @paramX  = .@pointX;
    @paramY  = .@pointY;
    callsub S_getDirection;
    .@targethit = @returnIndex;

    //now check how close
    //get the distance squared:
    // so it is in range 0 - 64:
    // 0 is hit
    // < 5 is very close
    // <17 is close
    // rest is a quite bad shot
    .@target_dist_sq = (.@pointX * .@pointX) + (.@pointY*.@pointY);

    if (.@target_dist_sq < 5)
        goto L_Quite;
    if (.@target_dist_sq < 17)
        goto L_Almost;

    //here are bad shots:
    mesn l("Gwendolyn Bowmaker");
    mesq l("D'oh, what a terrible shot!");
    next;
    mesq l("Do you even know what a bow is?");
    next;
    mesq l("That was far @@.", .@target_direction$[.@targethit]);
    next;
    goto L_Game;

L_Almost:
    mesn l("Gwendolyn Bowmaker");
    mesq l("That was @@.", .@target_direction$[.@targethit]);
    next;
    mesq l("I suggest some training.");
    next;
    goto L_Game;

L_Quite:
    mesn l("Gwendolyn Bowmaker");
    mesq l("That was quite close. Impressive!");
    next;
    mesq l("It was a little @@.", .@target_direction$[.@targethit]);
    next;
    mesq l("But you did not hit... have another try.");
    next;
    // You might get unlucky and the wind may change
    if(rand(5) == 2) goto L_Game;
    mesq l("Hurry up, before the wind changes.");
    next;
    goto L_Start;

L_Success:
    mesn l("Gwendolyn Bowmaker");
    mesq l("Wonderful! That was great! Directly hit the bull's eye!"); // TRANSLATORS: manner of speak, "to hit exactly on the target"
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("Maybe you did it, after all!");
    next;
    mesq l("Let me inspect it...");
    mesc l("She walks to the target.");
    next;
    if( rand2(400) > (2*readparam2(bDex) + readparam2(bAgi)))
        goto L_Miss;

    setq HurnscaldQuest_HarkEye, 6;

    skill TMW2_CHARGEDARROW, 1, 0;
    getexp .QUEST_HAWK_EXP, 0;
    mesn l("Gwendolyn Bowmaker");
    mesq l("Perfect indeed! Congratulations!");
    next;

    mesq l("Remember, there is always something new to learn. And you should not let your training down in order to keep and improve your abilities.");
    next;
    goto L_Close;

L_Miss:
    mesn l("Gwendolyn Bowmaker");
    mesq l("Ohh! A fingernail aside.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("That is quite impressive, but you can perform better with more training.");
    next;
    goto L_Game;

L_State6:
    mesn l("Gwendolyn Bowmaker");
    mesq l("You really have a reason to be proud.");
    next;
    goto L_Close;

L_Abort:
    mes "";
    mesn l("Gwendolyn Bowmaker");
    mesq l("That's a pity. Well, if you change your mind, come back any time.");
    next;
    goto L_Close;

L_No_Money:
    mes "";
    mesn l("Gwendolyn Bowmaker");
    mesq l("I am sorry, but it seems that you don't have enough money. Come back when you have reorganized your finances.");
    next;
    goto L_Close;

L_NoBow:
    mesq l("As an archer, you should always carry your bow with you. Doesn't warriors carry those heavy swords without complaining? Go and get it.");
    next;
    mesq l("Also, I don't care if you don't like the @@. That's the weapon a true archer should use!", getitemlink(ForestBow));
    goto L_Close;

L_FakeBow:
    mesn l("Gwendolyn Bowmaker");
    mesq l("You just bought it? You won't learn anything from that.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("To understand the nature of this bow, you have to collect the needed material by yourself. Only this way will you get a feeling of what it means to use such a weapon.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("The best thing would be to let you make the bow by yourself. But I guess, that would go to far. And it would take ages to get a high quality bow.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("Do as I told you, and talk to Alan for the bow!");
    next;
    goto L_Close;

L_Insufficient:
    mesn l("Gwendolyn Bowmaker");
    mesq l("Maybe I should also give you a lesson in how to count? You don't have enough.");
    next;
    goto L_Close;

L_NotReady:
    mesn l("Gwendolyn Bowmaker");
    mesq l("I am pleased about your progress, but you are not ready for the next step yet. Go and do some more training, before you come back.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("Remember also: It is wise to speak with people you meet on your journey, there is always something new to learn.");
    next;
    goto L_Close;

L_Arrows:
    mesc l("Gwendolyn sighs and shake her head.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("Another lecture: Take always enough arrows with you. Go and come back when you are equipped adequately.");
    next;
    mesn l("Gwendolyn Bowmaker");
    mesq l("For this training, I need @@, not the usual arrow you use.", getitemlink(TrainingArrow));
    next;
    goto L_Close;

L_Close:
    @paramX=0;
    @paramY=0;
    @returnIndex=0;
    closedialog;
    goodbye;
    close;

S_getDirection:
    // get @paramX @paramY  as parameters
    // returns an index where these parameters are in relation to origin
    // 123
    // 456  whereas 5 is the origin. (3,6,9 there is paramX>0);  (1,2,3 there is paramY>0)
    // 789
    //first check the quadrants and after check more precisely
    if(@paramX>0 && @paramY>0) @returnIndex = 3;
    if(@paramX>0 && @paramY<0) @returnIndex = 9;
    if(@paramX<0 && @paramY>0) @returnIndex = 1;
    if(@paramX<0 && @paramY<0) @returnIndex = 7;

    //straight left
    if ( (@paramX < 0) && (@paramY >= @paramX/2) && (-@paramY >= @paramX/2) ) @returnIndex = 4;

    //straight right
    if ( (@paramX > 0) && (@paramY <= @paramX/2) && (-@paramY <= @paramX/2) ) @returnIndex = 6;

    //straight above
    if ( (@paramY > 0) && (@paramX <= @paramY/2) && (-@paramX <= @paramY/2) ) @returnIndex = 2;

    //straight below
    if ( (@paramY < 0) && (@paramX >= @paramY/2) && (-@paramX >= @paramY/2) ) @returnIndex = 8;

    //check the origin, because the origin is found by the "straight" lines as well. (should not, but is.. maybe a bug?)
    if( @paramX==0 && @paramY==0 ) @returnIndex = 5;
    return;

OnInit:
    // schoolfee in gp
    .SCHOOLFEE = 2500;

    // how many eggs do you need of each kind?
    .CAVE_EGGS_AMOUNT = 21;
    .SNAKE_EGGS_AMOUNT = 15;
    .MOUNTAIN_EGGS_AMOUNT = 7;

    // experience for eggs
    .QUEST_EGG_EXP = 7500;

    // The needed level for the minigame:
    .BASELEVEL_GAME = 45;

    // experience gained for hitting the bullseye:
    .QUEST_HAWK_EXP = 12000;

    .sex = G_FEMALE;
    .distance = 7;
    end;
}