Mercurial > hg > early-roguelike
comparison rogue4/fight.c @ 12:9535a08ddc39
Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author | edwarj4 |
---|---|
date | Sat, 24 Oct 2009 16:52:52 +0000 |
parents | |
children | 1b73a8641b37 |
comparison
equal
deleted
inserted
replaced
11:949d558c2162 | 12:9535a08ddc39 |
---|---|
1 /* | |
2 * All the fighting gets done here | |
3 * | |
4 * @(#)fight.c 4.30 (Berkeley) 4/6/82 | |
5 * | |
6 * Rogue: Exploring the Dungeons of Doom | |
7 * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman | |
8 * All rights reserved. | |
9 * | |
10 * See the file LICENSE.TXT for full copyright and licensing information. | |
11 */ | |
12 | |
13 #include <curses.h> | |
14 #include <ctype.h> | |
15 #include <string.h> | |
16 #include "rogue.h" | |
17 | |
18 long e_levels[] = { | |
19 10L,20L,40L,80L,160L,320L,640L,1280L,2560L,5120L,10240L,20480L, | |
20 40920L, 81920L, 163840L, 327680L, 655360L, 1310720L, 2621440L, 0L | |
21 }; | |
22 | |
23 /* | |
24 * fight: | |
25 * The player attacks the monster. | |
26 */ | |
27 fight(mp, mn, weap, thrown) | |
28 register coord *mp; | |
29 char mn; | |
30 register THING *weap; | |
31 bool thrown; | |
32 { | |
33 register THING *tp; | |
34 register bool did_hit = TRUE; | |
35 register const char *mname; | |
36 | |
37 /* | |
38 * Find the monster we want to fight | |
39 */ | |
40 #ifdef WIZARD | |
41 if ((tp = moat(mp->y, mp->x)) == NULL) | |
42 debug("Fight what @ %d,%d", mp->y, mp->x); | |
43 #else | |
44 tp = moat(mp->y, mp->x); | |
45 #endif | |
46 /* | |
47 * Since we are fighting, things are not quiet so no healing takes | |
48 * place. | |
49 */ | |
50 count = quiet = 0; | |
51 runto(mp, &hero); | |
52 /* | |
53 * Let him know it was really a mimic (if it was one). | |
54 */ | |
55 if (tp->t_type == 'M' && tp->t_disguise != 'M' && !on(player, ISBLIND)) | |
56 { | |
57 tp->t_disguise = 'M'; | |
58 if (!thrown) | |
59 return FALSE; | |
60 msg("wait! That's a mimic!"); | |
61 } | |
62 did_hit = FALSE; | |
63 if (on(player, ISBLIND)) | |
64 mname = "it"; | |
65 else | |
66 mname = monsters[mn-'A'].m_name; | |
67 if (roll_em(&player, tp, weap, thrown)) | |
68 { | |
69 did_hit = FALSE; | |
70 if (thrown) | |
71 thunk(weap, mname); | |
72 else | |
73 hit(NULL, mname); | |
74 if (on(player, CANHUH)) | |
75 { | |
76 did_hit = TRUE; | |
77 tp->t_flags |= ISHUH; | |
78 player.t_flags &= ~CANHUH; | |
79 msg("your hands stop glowing red"); | |
80 } | |
81 if (tp->t_stats.s_hpt <= 0) | |
82 killed(tp, TRUE); | |
83 else if (did_hit && !on(player, ISBLIND)) | |
84 msg("the %s appears confused", mname); | |
85 did_hit = TRUE; | |
86 } | |
87 else | |
88 if (thrown) | |
89 bounce(weap, mname); | |
90 else | |
91 miss(NULL, mname); | |
92 return did_hit; | |
93 } | |
94 | |
95 /* | |
96 * attack: | |
97 * The monster attacks the player | |
98 */ | |
99 attack(mp) | |
100 register THING *mp; | |
101 { | |
102 register const char *mname; | |
103 | |
104 /* | |
105 * Since this is an attack, stop running and any healing that was | |
106 * going on at the time. | |
107 */ | |
108 running = FALSE; | |
109 count = quiet = 0; | |
110 if (mp->t_type == 'M' && !on(player, ISBLIND)) | |
111 mp->t_disguise = 'M'; | |
112 if (on(player, ISBLIND)) | |
113 mname = "it"; | |
114 else | |
115 mname = monsters[mp->t_type-'A'].m_name; | |
116 if (roll_em(mp, &player, NULL, FALSE)) | |
117 { | |
118 if (mp->t_type != 'E') | |
119 hit(mname, NULL); | |
120 if (pstats.s_hpt <= 0) | |
121 death(mp->t_type); /* Bye bye life ... */ | |
122 if (!on(*mp, ISCANC)) | |
123 switch (mp->t_type) | |
124 { | |
125 case 'R': | |
126 /* | |
127 * If a rust monster hits, you lose armor, unless | |
128 * that armor is leather or there is a magic ring | |
129 */ | |
130 if (cur_armor != NULL && cur_armor->o_ac < 9 | |
131 && cur_armor->o_which != LEATHER) | |
132 if (ISWEARING(R_SUSTARM)) | |
133 msg("The rust vanishes instantly"); | |
134 else | |
135 { | |
136 cur_armor->o_ac++; | |
137 if (!terse) | |
138 msg("your armor appears to be weaker now. Oh my!"); | |
139 else | |
140 msg("your armor weakens"); | |
141 } | |
142 when 'E': | |
143 /* | |
144 * The gaze of the floating eye hypnotizes you | |
145 */ | |
146 if (on(player, ISBLIND)) | |
147 break; | |
148 player.t_flags &= ~ISRUN; | |
149 if (!no_command) | |
150 { | |
151 addmsg("you are transfixed"); | |
152 if (!terse) | |
153 addmsg(" by the gaze of the floating eye"); | |
154 endmsg(); | |
155 } | |
156 no_command += rnd(2) + 2; | |
157 when 'A': | |
158 /* | |
159 * Ants have poisonous bites | |
160 */ | |
161 if (!save(VS_POISON)) | |
162 if (!ISWEARING(R_SUSTSTR)) | |
163 { | |
164 chg_str(-1); | |
165 if (!terse) | |
166 msg("you feel a sting in your arm and now feel weaker"); | |
167 else | |
168 msg("a sting has weakened you"); | |
169 } | |
170 else | |
171 if (!terse) | |
172 msg("a sting momentarily weakens you"); | |
173 else | |
174 msg("sting has no effect"); | |
175 when 'W': | |
176 case 'V': | |
177 /* | |
178 * Wraiths might drain energy levels, and Vampires | |
179 * can steal max_hp | |
180 */ | |
181 if (rnd(100) < (mp->t_type == 'W' ? 15 : 30)) | |
182 { | |
183 register int fewer; | |
184 | |
185 if (mp->t_type == 'W') | |
186 { | |
187 if (pstats.s_exp == 0) | |
188 death('W'); /* All levels gone */ | |
189 if (--pstats.s_lvl == 0) | |
190 { | |
191 pstats.s_exp = 0; | |
192 pstats.s_lvl = 1; | |
193 } | |
194 else | |
195 pstats.s_exp = e_levels[pstats.s_lvl-1]+1; | |
196 fewer = roll(1, 10); | |
197 } | |
198 else | |
199 fewer = roll(1, 5); | |
200 pstats.s_hpt -= fewer; | |
201 max_hp -= fewer; | |
202 if (pstats.s_hpt < 1) | |
203 pstats.s_hpt = 1; | |
204 if (max_hp < 1) | |
205 death(mp->t_type); | |
206 msg("you suddenly feel weaker"); | |
207 } | |
208 when 'F': | |
209 /* | |
210 * Violet fungi stops the poor guy from moving | |
211 */ | |
212 player.t_flags |= ISHELD; | |
213 sprintf(monsters['F'-'A'].m_stats.s_dmg,"%dd1",++fung_hit); | |
214 when 'L': | |
215 { | |
216 /* | |
217 * Leperachaun steals some gold | |
218 */ | |
219 register long lastpurse; | |
220 | |
221 lastpurse = purse; | |
222 purse -= GOLDCALC; | |
223 if (!save(VS_MAGIC)) | |
224 purse -= GOLDCALC + GOLDCALC + GOLDCALC + GOLDCALC; | |
225 if (purse < 0) | |
226 purse = 0; | |
227 remove_monster(&mp->t_pos, mp, FALSE); | |
228 mp = NULL; | |
229 if (purse != lastpurse) | |
230 msg("your purse feels lighter"); | |
231 } | |
232 when 'N': | |
233 { | |
234 register THING *obj, *steal; | |
235 register int nobj; | |
236 | |
237 /* | |
238 * Nymph's steal a magic item, look through the pack | |
239 * and pick out one we like. | |
240 */ | |
241 steal = NULL; | |
242 for (nobj = 0, obj = pack; obj != NULL; obj = next(obj)) | |
243 if (obj != cur_armor && obj != cur_weapon | |
244 && obj != cur_ring[LEFT] && obj != cur_ring[RIGHT] | |
245 && is_magic(obj) && rnd(++nobj) == 0) | |
246 steal = obj; | |
247 if (steal != NULL) | |
248 { | |
249 remove_monster(&mp->t_pos, moat(mp->t_pos.y, mp->t_pos.x), FALSE); | |
250 mp = NULL; | |
251 inpack--; | |
252 if (steal->o_count > 1 && steal->o_group == 0) | |
253 { | |
254 register int oc; | |
255 | |
256 oc = steal->o_count--; | |
257 steal->o_count = 1; | |
258 msg("she stole %s!", inv_name(steal, TRUE)); | |
259 steal->o_count = oc; | |
260 } | |
261 else | |
262 { | |
263 detach(pack, steal); | |
264 msg("she stole %s!", inv_name(steal, TRUE)); | |
265 discard(steal); | |
266 } | |
267 } | |
268 } | |
269 otherwise: | |
270 break; | |
271 } | |
272 } | |
273 else if (mp->t_type != 'E') | |
274 { | |
275 if (mp->t_type == 'F') | |
276 { | |
277 pstats.s_hpt -= fung_hit; | |
278 if (pstats.s_hpt <= 0) | |
279 death(mp->t_type); /* Bye bye life ... */ | |
280 } | |
281 miss(mname, NULL); | |
282 } | |
283 if (fight_flush) | |
284 flush_type(); | |
285 count = 0; | |
286 status(); | |
287 | |
288 if (mp == NULL) | |
289 return(-1); | |
290 else | |
291 return(0); | |
292 } | |
293 | |
294 /* | |
295 * swing: | |
296 * Returns true if the swing hits | |
297 */ | |
298 swing(at_lvl, op_arm, wplus) | |
299 int at_lvl, op_arm, wplus; | |
300 { | |
301 register int res = rnd(20); | |
302 register int need = (20 - at_lvl) - op_arm; | |
303 | |
304 return (res + wplus >= need); | |
305 } | |
306 | |
307 /* | |
308 * check_level: | |
309 * Check to see if the guy has gone up a level. | |
310 */ | |
311 check_level() | |
312 { | |
313 register int i, add, olevel; | |
314 | |
315 for (i = 0; e_levels[i] != 0; i++) | |
316 if (e_levels[i] > pstats.s_exp) | |
317 break; | |
318 i++; | |
319 olevel = pstats.s_lvl; | |
320 pstats.s_lvl = i; | |
321 if (i > olevel) | |
322 { | |
323 add = roll(i - olevel, 10); | |
324 max_hp += add; | |
325 if ((pstats.s_hpt += add) > max_hp) | |
326 pstats.s_hpt = max_hp; | |
327 msg("welcome to level %d", i); | |
328 } | |
329 } | |
330 | |
331 /* | |
332 * roll_em: | |
333 * Roll several attacks | |
334 */ | |
335 roll_em(thatt, thdef, weap, hurl) | |
336 THING *thatt, *thdef, *weap; | |
337 bool hurl; | |
338 { | |
339 register struct stats *att, *def; | |
340 register char *cp; | |
341 register int ndice, nsides, def_arm; | |
342 register bool did_hit = FALSE; | |
343 register int hplus; | |
344 register int dplus; | |
345 register int damage; | |
346 | |
347 att = &thatt->t_stats; | |
348 def = &thdef->t_stats; | |
349 if (weap == NULL) | |
350 { | |
351 cp = att->s_dmg; | |
352 dplus = 0; | |
353 hplus = 0; | |
354 } | |
355 else | |
356 { | |
357 hplus = (weap == NULL ? 0 : weap->o_hplus); | |
358 dplus = (weap == NULL ? 0 : weap->o_dplus); | |
359 if (weap == cur_weapon) | |
360 { | |
361 if (ISRING(LEFT, R_ADDDAM)) | |
362 dplus += cur_ring[LEFT]->o_ac; | |
363 else if (ISRING(LEFT, R_ADDHIT)) | |
364 hplus += cur_ring[LEFT]->o_ac; | |
365 if (ISRING(RIGHT, R_ADDDAM)) | |
366 dplus += cur_ring[RIGHT]->o_ac; | |
367 else if (ISRING(RIGHT, R_ADDHIT)) | |
368 hplus += cur_ring[RIGHT]->o_ac; | |
369 } | |
370 if (hurl) | |
371 if ((weap->o_flags&ISMISL) && cur_weapon != NULL && | |
372 cur_weapon->o_which == weap->o_launch) | |
373 { | |
374 cp = weap->o_hurldmg; | |
375 hplus += cur_weapon->o_hplus; | |
376 dplus += cur_weapon->o_dplus; | |
377 } | |
378 else | |
379 cp = weap->o_hurldmg; | |
380 else | |
381 { | |
382 cp = weap->o_damage; | |
383 /* | |
384 * Drain a staff of striking | |
385 */ | |
386 if (weap->o_type == STICK && weap->o_which == WS_HIT | |
387 && --weap->o_charges < 0) | |
388 { | |
389 strcpy(weap->o_damage,"0d0"); | |
390 cp = weap->o_damage; | |
391 weap->o_hplus = weap->o_dplus = 0; | |
392 weap->o_charges = 0; | |
393 } | |
394 } | |
395 } | |
396 /* | |
397 * If the creature being attacked is not running (alseep or held) | |
398 * then the attacker gets a plus four bonus to hit. | |
399 */ | |
400 if (!on(*thdef, ISRUN)) | |
401 hplus += 4; | |
402 def_arm = def->s_arm; | |
403 if (def == &pstats) | |
404 { | |
405 if (cur_armor != NULL) | |
406 def_arm = cur_armor->o_ac; | |
407 if (ISRING(LEFT, R_PROTECT)) | |
408 def_arm -= cur_ring[LEFT]->o_ac; | |
409 if (ISRING(RIGHT, R_PROTECT)) | |
410 def_arm -= cur_ring[RIGHT]->o_ac; | |
411 } | |
412 for (;;) | |
413 { | |
414 ndice = atoi(cp); | |
415 if ((cp = strchr(cp, 'd')) == NULL) | |
416 break; | |
417 nsides = atoi(++cp); | |
418 if (swing(att->s_lvl, def_arm, hplus + str_plus(att->s_str))) | |
419 { | |
420 register int proll; | |
421 | |
422 proll = roll(ndice, nsides); | |
423 #ifdef WIZARD | |
424 if (ndice + nsides > 0 && proll < 1) | |
425 debug("Damage for %dd%d came out %d, dplus = %d, add_dam = %d, def_arm = %d", ndice, nsides, proll, dplus, add_dam(att->s_str), def_arm); | |
426 #endif | |
427 damage = dplus + proll + add_dam(att->s_str); | |
428 def->s_hpt -= max(0, damage); | |
429 did_hit = TRUE; | |
430 } | |
431 if ((cp = strchr(cp, '/')) == NULL) | |
432 break; | |
433 cp++; | |
434 } | |
435 return did_hit; | |
436 } | |
437 | |
438 /* | |
439 * prname: | |
440 * The print name of a combatant | |
441 */ | |
442 char * | |
443 prname(who, upper) | |
444 register char *who; | |
445 bool upper; | |
446 { | |
447 static char tbuf[MAXSTR]; | |
448 | |
449 *tbuf = '\0'; | |
450 if (who == 0) | |
451 strcpy(tbuf, "you"); | |
452 else if (on(player, ISBLIND)) | |
453 strcpy(tbuf, "it"); | |
454 else | |
455 { | |
456 strcpy(tbuf, "the "); | |
457 strcat(tbuf, who); | |
458 } | |
459 if (upper) | |
460 *tbuf = toupper(*tbuf); | |
461 return tbuf; | |
462 } | |
463 | |
464 /* | |
465 * hit: | |
466 * Print a message to indicate a succesful hit | |
467 */ | |
468 hit(er, ee) | |
469 register char *er, *ee; | |
470 { | |
471 register char *s = ""; | |
472 | |
473 addmsg(prname(er, TRUE)); | |
474 if (terse) | |
475 s = " hit"; | |
476 else | |
477 switch (rnd(4)) | |
478 { | |
479 case 0: s = " scored an excellent hit on "; | |
480 when 1: s = " hit "; | |
481 when 2: s = (er == 0 ? " have injured " : " has injured "); | |
482 when 3: s = (er == 0 ? " swing and hit " : " swings and hits "); | |
483 } | |
484 addmsg(s); | |
485 if (!terse) | |
486 addmsg(prname(ee, FALSE)); | |
487 endmsg(); | |
488 } | |
489 | |
490 /* | |
491 * miss: | |
492 * Print a message to indicate a poor swing | |
493 */ | |
494 miss(er, ee) | |
495 register char *er, *ee; | |
496 { | |
497 register char *s = ""; | |
498 | |
499 addmsg(prname(er, TRUE)); | |
500 switch (terse ? 0 : rnd(4)) | |
501 { | |
502 case 0: s = (er == 0 ? " miss" : " misses"); | |
503 when 1: s = (er == 0 ? " swing and miss" : " swings and misses"); | |
504 when 2: s = (er == 0 ? " barely miss" : " barely misses"); | |
505 when 3: s = (er == 0 ? " don't hit" : " doesn't hit"); | |
506 } | |
507 addmsg(s); | |
508 if (!terse) | |
509 addmsg(" %s", prname(ee, FALSE)); | |
510 endmsg(); | |
511 } | |
512 | |
513 /* | |
514 * save_throw: | |
515 * See if a creature save against something | |
516 */ | |
517 save_throw(which, tp) | |
518 int which; | |
519 THING *tp; | |
520 { | |
521 register int need; | |
522 | |
523 need = 14 + which - tp->t_stats.s_lvl / 2; | |
524 return (roll(1, 20) >= need); | |
525 } | |
526 | |
527 /* | |
528 * save: | |
529 * See if he saves against various nasty things | |
530 */ | |
531 save(which) | |
532 register int which; | |
533 { | |
534 if (which == VS_MAGIC) | |
535 { | |
536 if (ISRING(LEFT, R_PROTECT)) | |
537 which -= cur_ring[LEFT]->o_ac; | |
538 if (ISRING(RIGHT, R_PROTECT)) | |
539 which -= cur_ring[RIGHT]->o_ac; | |
540 } | |
541 return save_throw(which, &player); | |
542 } | |
543 | |
544 /* | |
545 * str_plus: | |
546 * Compute bonus/penalties for strength on the "to hit" roll | |
547 */ | |
548 str_plus(str) | |
549 register str_t str; | |
550 { | |
551 if (str == 31) | |
552 return 3; | |
553 if (str > 20) | |
554 return 2; | |
555 if (str > 16) | |
556 return 1; | |
557 if (str > 6) | |
558 return 0; | |
559 return str - 7; | |
560 } | |
561 | |
562 /* | |
563 * add_dam: | |
564 * Compute additional damage done for exceptionally high or low strength | |
565 */ | |
566 add_dam(str) | |
567 register str_t str; | |
568 { | |
569 if (str == 31) | |
570 return 6; | |
571 if (str > 21) | |
572 return 5; | |
573 if (str == 21) | |
574 return 4; | |
575 if (str > 18) | |
576 return 3; | |
577 if (str == 18) | |
578 return 2; | |
579 if (str > 15) | |
580 return 1; | |
581 if (str > 6) | |
582 return 0; | |
583 return str - 7; | |
584 } | |
585 | |
586 /* | |
587 * raise_level: | |
588 * The guy just magically went up a level. | |
589 */ | |
590 raise_level() | |
591 { | |
592 pstats.s_exp = e_levels[pstats.s_lvl-1] + 1L; | |
593 check_level(); | |
594 } | |
595 | |
596 /* | |
597 * thunk: | |
598 * A missile hits a monster | |
599 */ | |
600 thunk(weap, mname) | |
601 register THING *weap; | |
602 register const char *mname; | |
603 { | |
604 if (weap->o_type == WEAPON) | |
605 addmsg("the %s hits ", w_names[weap->o_which]); | |
606 else | |
607 addmsg("you hit "); | |
608 if (on(player, ISBLIND)) | |
609 msg("it"); | |
610 else | |
611 msg("the %s", mname); | |
612 } | |
613 | |
614 /* | |
615 * bounce: | |
616 * A missile misses a monster | |
617 */ | |
618 bounce(weap, mname) | |
619 register THING *weap; | |
620 register const char *mname; | |
621 { | |
622 if (weap->o_type == WEAPON) | |
623 addmsg("the %s misses ", w_names[weap->o_which]); | |
624 else | |
625 addmsg("you missed "); | |
626 if (on(player, ISBLIND)) | |
627 msg("it"); | |
628 else | |
629 msg("the %s", mname); | |
630 } | |
631 | |
632 /* | |
633 * remove: | |
634 * Remove a monster from the screen | |
635 */ | |
636 remove_monster(mp, tp, waskill) | |
637 register coord *mp; | |
638 register THING *tp; | |
639 bool waskill; | |
640 { | |
641 register THING *obj, *nexti; | |
642 | |
643 for (obj = tp->t_pack; obj != NULL; obj = nexti) | |
644 { | |
645 nexti = next(obj); | |
646 obj->o_pos = tp->t_pos; | |
647 detach(tp->t_pack, obj); | |
648 if (waskill) | |
649 fall(obj, FALSE); | |
650 else | |
651 discard(obj); | |
652 } | |
653 moat(mp->y, mp->x) = NULL; | |
654 mvaddch(mp->y, mp->x, tp->t_oldch); | |
655 detach(mlist, tp); | |
656 discard(tp); | |
657 } | |
658 | |
659 /* | |
660 * is_magic: | |
661 * Returns true if an object radiates magic | |
662 */ | |
663 is_magic(obj) | |
664 register THING *obj; | |
665 { | |
666 switch (obj->o_type) | |
667 { | |
668 case ARMOR: | |
669 return obj->o_ac != a_class[obj->o_which]; | |
670 case WEAPON: | |
671 return obj->o_hplus != 0 || obj->o_dplus != 0; | |
672 case POTION: | |
673 case SCROLL: | |
674 case STICK: | |
675 case RING: | |
676 case AMULET: | |
677 return TRUE; | |
678 } | |
679 return FALSE; | |
680 } | |
681 | |
682 /* | |
683 * killed: | |
684 * Called to put a monster to death | |
685 */ | |
686 killed(tp, pr) | |
687 register THING *tp; | |
688 bool pr; | |
689 { | |
690 pstats.s_exp += tp->t_stats.s_exp; | |
691 /* | |
692 * If the monster was a violet fungi, un-hold him | |
693 */ | |
694 switch (tp->t_type) | |
695 { | |
696 case 'F': | |
697 player.t_flags &= ~ISHELD; | |
698 fung_hit = 0; | |
699 strcpy(monsters['F'-'A'].m_stats.s_dmg, "000d0"); | |
700 when 'L': | |
701 { | |
702 register THING *gold; | |
703 | |
704 if (fallpos(&tp->t_pos, &tp->t_room->r_gold, TRUE)) | |
705 { | |
706 gold = new_item(); | |
707 gold->o_type = GOLD; | |
708 gold->o_goldval = GOLDCALC; | |
709 if (save(VS_MAGIC)) | |
710 gold->o_goldval += GOLDCALC + GOLDCALC | |
711 + GOLDCALC + GOLDCALC; | |
712 attach(tp->t_pack, gold); | |
713 } | |
714 } | |
715 } | |
716 /* | |
717 * Get rid of the monster. | |
718 */ | |
719 if (pr) | |
720 { | |
721 if (!terse) | |
722 addmsg("you have "); | |
723 addmsg("defeated "); | |
724 if (on(player, ISBLIND)) | |
725 msg("it"); | |
726 else | |
727 { | |
728 if (!terse) | |
729 addmsg("the "); | |
730 msg("%s", monsters[tp->t_type-'A'].m_name); | |
731 } | |
732 } | |
733 remove_monster(&tp->t_pos, tp, TRUE); | |
734 /* | |
735 * Do adjustments if he went up a level | |
736 */ | |
737 check_level(); | |
738 } |