comparison xrogue/bolt.c @ 133:e6179860cb76

Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 21 Apr 2015 08:55:20 -0400
parents
children f54901b9c39b
comparison
equal deleted inserted replaced
124:d10fc4a065ac 133:e6179860cb76
1 /*
2 bolt.c - functions shooting an object across the room
3
4 XRogue: Expeditions into the Dungeons of Doom
5 Copyright (C) 1991 Robert Pietkivitch
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <curses.h>
20 #include <ctype.h>
21 #include "rogue.h"
22
23 /*
24 * shoot_bolt fires a bolt from the given starting point in the
25 * given direction
26 */
27
28 shoot_bolt(shooter, start, dir, get_points, reason, name, damage)
29 struct thing *shooter;
30 coord start, dir;
31 bool get_points;
32 short reason;
33 char *name;
34 int damage;
35 {
36 unsigned char dirch = 0, ch;
37 bool used, change, see_him;
38 short y, x, bounces;
39 coord pos;
40 struct linked_list *target=NULL;
41 struct {
42 coord place;
43 char oldch;
44 } spotpos[BOLT_LENGTH];
45
46 switch (dir.y + dir.x) {
47 case 0: dirch = '/';
48 when 1: case -1: dirch = (dir.y == 0 ? '-' : '|');
49 when 2: case -2: dirch = '\\';
50 }
51 pos.y = start.y + dir.y;
52 pos.x = start.x + dir.x;
53 used = FALSE;
54 change = FALSE;
55
56 bounces = 0; /* No bounces yet */
57 nofont(cw);
58 for (y = 0; y < BOLT_LENGTH && !used; y++) {
59 ch = winat(pos.y, pos.x);
60 spotpos[y].place = pos;
61 spotpos[y].oldch = mvwinch(cw, pos.y, pos.x);
62
63 /* Are we at hero? */
64 if (ce(pos, hero)) goto at_hero;
65
66 switch (ch) {
67 case SECRETDOOR:
68 case VERTWALL:
69 case HORZWALL:
70 case ' ':
71 if (dirch == '-' || dirch == '|') {
72 dir.y = -dir.y;
73 dir.x = -dir.x;
74 }
75 else {
76 unsigned char chx = mvinch(pos.y-dir.y, pos.x),
77 chy = mvinch(pos.y, pos.x-dir.x);
78 bool anychange = FALSE; /* Did we change anthing */
79
80 if (chy == WALL || chy == SECRETDOOR ||
81 chy == HORZWALL || chy == VERTWALL) {
82 dir.y = -dir.y;
83 change ^= TRUE; /* Change at least one direction */
84 anychange = TRUE;
85 }
86 if (chx == WALL || chx == SECRETDOOR ||
87 chx == HORZWALL || chx == VERTWALL) {
88 dir.x = -dir.x;
89 change ^= TRUE; /* Change at least one direction */
90 anychange = TRUE;
91 }
92
93 /* If we didn't make any change, make both changes */
94 if (!anychange) {
95 dir.x = -dir.x;
96 dir.y = -dir.y;
97 }
98 }
99
100 /* Do we change how the bolt looks? */
101 if (change) {
102 change = FALSE;
103 if (dirch == '\\') dirch = '/';
104 else if (dirch == '/') dirch = '\\';
105 }
106
107 y--; /* The bounce doesn't count as using up the bolt */
108
109 /* Make sure we aren't in an infinite bounce */
110 if (++bounces > BOLT_LENGTH) used = TRUE;
111 msg("The %s bounces", name);
112 break;
113 default:
114 if (isalpha(ch)) {
115 register struct linked_list *item;
116 struct thing *tp;
117 register char *mname;
118 bool see_monster = cansee(pos.y, pos.x);
119
120 item = find_mons(unc(pos));
121 assert(item != NULL);
122 tp = THINGPTR(item);
123 mname = monster_name(tp);
124
125 /*
126 * If our prey shot this, let's record the fact that
127 * he can shoot, regardless of whether he hits us.
128 */
129 if (tp->t_dest != NULL && ce(*tp->t_dest, shooter->t_pos))
130 tp->t_wasshot = TRUE;
131
132 if (!save(VS_BREATH, tp, -(shooter->t_stats.s_lvl/10))) {
133 if (see_monster) {
134 if (on(*tp, ISDISGUISE) &&
135 (tp->t_type != tp->t_disguise)) {
136 msg("Wait! That's a %s!", mname);
137 turn_off(*tp, ISDISGUISE);
138 }
139
140 turn_off(*tp, CANSURPRISE);
141 msg("The %s hits %s", name, prname(mname, FALSE));
142 }
143
144 /* Should we start to chase the shooter? */
145 if (shooter != &player &&
146 shooter != tp &&
147 shooter->t_index != tp->t_index &&
148 (tp->t_dest == NULL || rnd(100) < 25)) {
149 /*
150 * If we're intelligent enough to realize that this
151 * is a friendly monster, we will attack the hero
152 * instead.
153 */
154 if (on(*shooter, ISFRIENDLY) &&
155 roll(3,6) < tp->t_stats.s_intel)
156 runto(tp, &hero);
157
158 /* Otherwise, let's chase the monster */
159 else runto(tp, &shooter->t_pos);
160 }
161 else if (shooter == &player) {
162 runto(tp, &hero);
163
164 /*
165 * If the player shot a charmed monster, it may