1 #include "std.h"
2 #include "tune.h"
3
4 #undef EXTRA_RESET
5 #define EXTRA_RESET extra_reset(arg);
6
extra_reset(arg)7 extra_reset(arg) {
8 object ob;
9 if (arg)
10 return;
11 move_object("obj/book", this_object());
12 move_object(clone_object("obj/bull_board"), this_object());
13 ob = clone_object("obj/quest_obj");
14 call_other(ob, "set_name", "orc_slayer");
15 call_other(ob, "set_hint",
16 "Retrieve the Orc slayer from the evil orc shaman, and give it to Leo.\n");
17 move_object(ob, "room/quest_room");
18 }
19
20 #undef EXTRA_INIT
21 #define EXTRA_INIT\
22 add_action("cost_for_level", "cost");\
23 add_action("advance", "advance");\
24 add_action("south", "south");\
25 add_action("banish", "banish");\
26 add_action("list_quests", "list");
27
28 ONE_EXIT("room/vill_road2", "north",
29 "The adventurers guild",
30 "You have to come here when you want to advance your level.\n" +
31 "You can also buy points for a new level.\n" +
32 "Commands: cost, advance [level, str, dex, int, con], list (number).\n" +
33 "There is an opening to the south, and some shimmering\n" +
34 "blue light in the doorway.\n", 1)
35
36 int next_level;
37 int next_exp;
38 int level;
39 int exp;
40 string title; /* now with arrays. :) */
41 object player_ob;
42 string banished_by;
43
44 /* some minor changes by Iggy. */
45 /* get level asks get_next_exp() and get_next_title() */
46
get_level(str)47 get_level(str)
48 {
49 level = str;
50
51 next_exp = get_next_exp(level);
52 next_level = level + 1 ;
53 title = get_new_title(level);
54 }
55
56 string male_title_str, fem_title_str, neut_title_str;
57 /*xxx return title */
get_new_title(str)58 get_new_title(str)
59 {
60 if (!male_title_str){
61 male_title_str = allocate(20);
62
63 male_title_str[19] ="the apprentice Wizard";
64 male_title_str[18] ="the grand master sorcerer";
65 male_title_str[17] ="the master sorcerer";
66 male_title_str[16] ="the apprentice sorcerer";
67 male_title_str[15] ="the warlock";
68 male_title_str[14] ="the enchanter";
69 male_title_str[13] ="the magician";
70 male_title_str[12] ="the apprentice magician";
71 male_title_str[11] ="the conjurer";
72 male_title_str[10] ="the champion";
73 male_title_str[9] ="the warrior";
74 male_title_str[8] ="the great adventurer";
75 male_title_str[7] ="the experienced adventurer";
76 male_title_str[6] ="the small adventurer";
77 male_title_str[5] ="the experienced fighter";
78 male_title_str[4] ="the small fighter";
79 male_title_str[3] ="the master ranger";
80 male_title_str[2] ="the lowrank ranger";
81 male_title_str[1] ="the simple wanderer";
82 male_title_str[0] ="the utter novice";
83
84 fem_title_str = allocate(20);
85
86 fem_title_str[19] ="the apprentice Wizard";
87 fem_title_str[18] ="the grand master sorceress";
88 fem_title_str[17] ="the master sorceress";
89 fem_title_str[16] ="the apprentice sorceress";
90 fem_title_str[15] ="the witch";
91 fem_title_str[14] ="the enchantress";
92 fem_title_str[13] ="the magicienne";
93 fem_title_str[12] ="the apprentice magicienne";
94 fem_title_str[11] ="the conjuress";
95 fem_title_str[10] ="the deadly amazon";
96 fem_title_str[9] ="the amazon";
97 fem_title_str[8] ="the great adventuress";
98 fem_title_str[7] ="the experienced adventuress";
99 fem_title_str[6] ="the small adventuress";
100 fem_title_str[5] ="the charming siren";
101 fem_title_str[4] ="the siren";
102 fem_title_str[3] ="the master ranger";
103 fem_title_str[2] ="the lowrank ranger";
104 fem_title_str[1] ="the simple wanderer";
105 fem_title_str[0] ="the utter novice";
106
107 neut_title_str = allocate(20);
108
109 neut_title_str[19] ="the apprentice Wizard";
110 neut_title_str[18] ="the ferocious tyrannosaur";
111 neut_title_str[17] ="the small tyrannosaur";
112 neut_title_str[16] ="the vicious dragon";
113 neut_title_str[15] ="the devious dragon";
114 neut_title_str[14] ="the small dragon";
115 neut_title_str[13] ="the powerful demon";
116 neut_title_str[12] ="the small demon";
117 neut_title_str[11] ="the beholder";
118 neut_title_str[10] ="the great monster";
119 neut_title_str[9] ="the experienced monster";
120 neut_title_str[8] ="the medium monster";
121 neut_title_str[7] ="the small monster";
122 neut_title_str[6] ="the threatening shadow";
123 neut_title_str[5] ="the shadow";
124 neut_title_str[4] ="the wraith";
125 neut_title_str[3] ="the bugbear";
126 neut_title_str[2] ="the furry creature";
127 neut_title_str[1] ="the simple creature";
128 neut_title_str[0] ="the utter creature";
129 }
130 if (!player_ob || !player_ob->query_gender())
131 return neut_title_str[str];
132 else if (player_ob->query_gender() == 1)
133 return male_title_str[str];
134 else
135 return fem_title_str[str];
136 }
137
138
139 int exp_str;
140
141 /* returns the next_exp. */
get_next_exp(str)142 get_next_exp(str) {
143 if(!exp_str){
144 exp_str = allocate(20);
145
146 exp_str[19] = 1000000;
147 exp_str[18] = 666666;
148 exp_str[17] = 444444;
149 exp_str[16] = 296296;
150 exp_str[15] = 197530;
151 exp_str[14] = 131687;
152 exp_str[13] = 97791;
153 exp_str[12] = 77791;
154 exp_str[11] = 58527;
155 exp_str[10] = 39018;
156 exp_str[9] = 26012;
157 exp_str[8] = 17341;
158 exp_str[7] = 11561;
159 exp_str[6] = 7707;
160 exp_str[5] = 5138;
161 exp_str[4] = 3425;
162 exp_str[3] = 2283;
163 exp_str[2] = 1522;
164 exp_str[1] = 1014;
165 exp_str[0] = 676;
166 }
167 return exp_str[str];
168 }
169
170 /*
171 * This routine is called by monster, to calculate how much they are worth.
172 * This value should not depend on the tuning.
173 */
query_cost(l)174 query_cost(l) {
175 player_ob = this_player();
176 level = l;
177 if (level >= 20)
178 return 1000000;
179 get_level(level);
180 return next_exp;
181 }
182
183 /*
184 * Special function for other guilds to call. Arguments are current level
185 * and experience points.
186 */
query_cost_for_level(l,e)187 query_cost_for_level(l, e) {
188 level = l;
189 exp = e;
190 get_level(0);
191 if (next_exp <= exp)
192 return 0;
193 return (next_exp - exp) * 1000 / EXP_COST;
194 }
195
cost_for_level()196 cost_for_level()
197 {
198 int cost;
199
200 player_ob = this_player();
201 level = call_other(player_ob, "query_level", 0);
202
203 cost = raise_cost(player_ob->query_str(), 0);
204 if (cost)
205 write("Str: " + cost + " experience points.\n");
206 else
207 write("Str: Not possible.\n");
208
209 cost = raise_cost(player_ob->query_con(), 0);
210 if (cost)
211 write("Con: " + cost + " experience points.\n");
212 else
213 write("Con: Not possible.\n");
214
215 cost = raise_cost(player_ob->query_dex(), 0);
216 if (cost)
217 write("Dex: " + cost + " experience points.\n");
218 else
219 write("Dex: Not possible.\n");
220
221 cost = raise_cost(player_ob->query_int(), 0);
222 if (cost)
223 write("Int: " + cost + " experience points.\n");
224 else
225 write("Int: Not possible.\n");
226
227 if (level >= 20) {
228 write("You will have to seek other ways.\n");
229 return 1;
230 }
231 exp = call_other(player_ob, "query_exp", 0);
232 get_level(level);
233 if (next_exp <= exp) {
234 write("It will cost you nothing to be promoted.\n");
235 return 1;
236 }
237 write("It will cost you "); write((next_exp - exp) * 1000 / EXP_COST);
238 write(" gold coins to advance to level "); write(next_level);
239 write(".\n");
240 return 1;
241 }
242
advance(arg)243 advance(arg)
244 {
245 string name_of_player;
246 int cost;
247
248 if (arg == "con")
249 {
250 raise_con();
251 return 1;
252 }
253
254 if (arg == "dex")
255 {
256 raise_dex();
257 return 1;
258 }
259
260 if (arg == "int")
261 {
262 raise_int();
263 return 1;
264 }
265
266 if (arg == "str")
267 {
268 raise_str();
269 return 1;
270 }
271
272 if (arg && arg != "level")
273 return 0;
274
275 player_ob = this_player();
276 name_of_player = call_other(player_ob, "query_name", 0);
277 level = call_other(player_ob, "query_level", 0);
278 if (level == -1)
279 level = 0;
280 exp = call_other(player_ob, "query_exp", 0);
281 title = call_other(player_ob, "query_title", 0);
282 if (level >= 20) {
283 write("You are still "); write(title); write("\n");
284 return 1;
285 }
286 get_level(level);
287 if (next_level == 20 && call_other("room/quest_room", "count", 0))
288 return 1;
289 if (level == 0)
290 next_exp = exp;
291 cost = (next_exp - exp) * 1000 / EXP_COST;
292 if (next_exp > exp) {
293 if (call_other(player_ob, "query_money", 0) < cost) {
294 write("You don't have enough gold coins.\n");
295 return 1;
296 }
297 call_other(player_ob, "add_money", - cost);
298 }
299 say(call_other(player_ob, "query_name", 0) + " is now level " +
300 next_level + ".\n");
301 call_other(player_ob, "set_level", next_level);
302 call_other(player_ob, "set_title", title);
303 if (exp < next_exp)
304 call_other(player_ob, "add_exp", next_exp - exp);
305 if (next_level < 7) {
306 write("You are now " + name_of_player + " " + title +
307 " (level " + next_level + ").\n");
308 return 1;
309 }
310 if (next_level < 14) {
311 write("Well done, " + name_of_player + " " + title +
312 " (level " + next_level + ").\n");
313 return 1;
314 }
315 if (next_level < 20) {
316 write("Welcome to your new class, mighty one.\n" +
317 "You are now " + title + " (level " + next_level + ").\n");
318 }
319 if (next_level == 20) {
320 write("A new Wizard has been born.\n");
321 shout("A new Wizard has been born.\n");
322 return 1;
323 }
324 return 1;
325 }
326
raise_con()327 raise_con()
328 {
329 int lvl;
330
331 if (too_high_average())
332 return;
333 lvl = this_player()->query_con();
334 if (lvl >= 20) {
335 alas("tough and endurable");
336 return;
337 }
338 if (raise_cost(lvl, 1))
339 {
340 this_player()->set_con(lvl + 1);
341 write("Ok.\n");
342 }
343 else
344 write("You don't have enough experience.\n");
345 }
346
raise_dex()347 raise_dex()
348 {
349 int lvl;
350
351 if (too_high_average())
352 return;
353 lvl = this_player()->query_dex();
354 if (lvl >= 20) {
355 alas("skilled and vigorous");
356 return;
357 }
358 if (raise_cost(lvl, 1))
359 {
360 this_player()->set_dex(lvl + 1);
361 write("Ok.\n");
362 }
363 else
364 write("You don't have enough experience.\n");
365 }
366
raise_int()367 raise_int()
368 {
369 int lvl;
370
371 if (too_high_average())
372 return;
373 lvl = this_player()->query_int();
374 if (lvl >= 20) {
375 alas("knowledgeable and wise");
376 return;
377 }
378 if (raise_cost(lvl, 1))
379 {
380 this_player()->set_int(lvl + 1);
381 write("Ok.\n");
382 }
383 else
384 write("You don't have enough experience.\n");
385 }
386
raise_str()387 raise_str()
388 {
389 int lvl;
390
391 if (too_high_average())
392 return;
393 lvl = this_player()->query_str();
394 if (lvl >= 20) {
395 alas("strong and powerful");
396 return;
397 }
398 if (raise_cost(lvl, 1))
399 {
400 this_player()->set_str(lvl + 1);
401 write("Ok.\n");
402 }
403 else
404 write("You don't have enough experience.\n");
405 }
406
407 /*
408 * Compute cost for raising a stat one level. 'base' is the level that
409 * you have now, but never less than 1.
410 */
raise_cost(base,action)411 raise_cost(base, action)
412 {
413 int cost, saldo;
414
415 if (base >= 20)
416 return 0;
417 cost = (get_next_exp(base) - get_next_exp(base - 1)) / STAT_COST;
418 saldo = this_player()->query_exp() -
419 get_next_exp(this_player()->query_level()- 1);
420 if (action == 0)
421 return cost;
422 if (saldo < cost)
423 return 0;
424 this_player()->add_exp(-cost);
425 return cost;
426 }
427
428 /*
429 * Banish a monster name from being used.
430 */
banish(who)431 banish(who) {
432 level = call_other(this_player(), "query_level");
433 if (level < 21)
434 return 0;
435 if (!who) {
436 write("Who ?\n");
437 return 1;
438 }
439 if (!call_other(this_player(), "valid_name", who))
440 return 1;
441 if (restore_object("players/" + who)) {
442 write("That name is already used.\n");
443 return 1;
444 }
445 if (restore_object("banish/" + who)) {
446 write("That name is already banished.\n");
447 return 1;
448 }
449 banished_by = call_other(this_player(), "query_name");
450 title = call_other(this_player(), "query_title");
451 if (banished_by == "Someone") {
452 write("You must not be invisible!\n");
453 return 1;
454 }
455 save_object("banish/" + who);
456 return 1;
457 }
458
south()459 south() {
460 if (call_other(this_player(), "query_level", 0) < 20) {
461 write("A strong magic force stops you.\n");
462 say(call_other(this_player(), "query_name", 0) +
463 " tries to go through the field, but fails.\n");
464 return 1;
465 }
466 write("You wriggle through the force field...\n");
467 call_other(this_player(), "move_player", "south#room/adv_inner");
468 return 1;
469 }
470
list_quests(num)471 list_quests(num)
472 {
473 int qnumber;
474 if (num && (sscanf(num, "%d", qnumber) == 1))
475 call_other("room/quest_room", "list", qnumber);
476 else
477 call_other("room/quest_room", "count", 0);
478 return 1;
479 }
480
query_drop_castle()481 query_drop_castle() {
482 return 1;
483 }
484
alas(what)485 alas(what) {
486 write("Sorry " + gnd_prn() + ", but you are already as " + what +
487 "\nas any");
488 if (this_player()->query_gender() == 0)
489 write("thing could possibly hope to get.\n");
490 else
491 write("one could possibly hope to get.\n");
492 }
493
494 /*
495 * Check that the player does not have too high average of the stats.
496 */
too_high_average()497 too_high_average() {
498 if ((this_player()->query_con() + this_player()->query_str() +
499 this_player()->query_int() + this_player()->query_dex()) / 4 >=
500 this_player()->query_level() + 3) {
501 write("Sorry " + gnd_prn() +
502 ", but you are not of high enough level.\n");
503 return 1;
504 }
505 return 0;
506 }
507
gnd_prn()508 gnd_prn() {
509 int gnd;
510
511 gnd = this_player()->query_gender();
512 if (gnd == 1)
513 return "sir";
514 else if (gnd == 2)
515 return "madam";
516 else
517 return "best creature";
518 }
519