Branch data Line data Source code
1 : : /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
2 : : /* mmelee */
3 : : /* various functions to do with monster melee */
4 : :
5 : : #include "glob.h"
6 : :
7 : :
8 : 2 : void m_hit(pmt m, int dtype)
9 : : {
10 [ + - ]: 2 : if (m->uniqueness == COMMON) {
11 : 2 : strcpy(Str3,"a ");
12 : 2 : strcat(Str3,m->monstring);
13 : : }
14 : 0 : else strcpy(Str3,m->monstring);
15 [ - + ][ # # ]: 2 : if ((Player.status[DISPLACED] > 0) && (random_range(2) == 1))
16 : 0 : mprint("The attack was displaced!");
17 : 2 : else p_damage(random_range(m->dmg),dtype,Str3);
18 : 2 : }
19 : :
20 : :
21 : :
22 : : /* execute monster attacks versus player */
23 : 8 : void tacmonster(pmt m)
24 : : {
25 : 8 : int i=0;
26 : 8 : drawvision(Player.x,Player.y);
27 : 8 : transcribe_monster_actions(m);
28 [ + + ][ + - ]: 36 : while ((i < strlen(m->meleestr)) && (m->hp > 0)) {
29 [ + - ]: 28 : if (m->uniqueness == COMMON) {
30 : 28 : strcpy(Str4,"The ");
31 : 28 : strcat(Str4,m->monstring);
32 : : }
33 : 0 : else strcpy(Str4,m->monstring);
34 [ + + ]: 28 : if (m->meleestr[i] == 'A') {
35 : 10 : strcat(Str4," attacks ");
36 : 10 : strcat(Str4,actionlocstr(m->meleestr[i+1]));
37 [ + - ]: 10 : if (Verbosity == VERBOSE) mprint(Str4);
38 : 10 : monster_melee(m,m->meleestr[i+1],0);
39 : : }
40 [ - + ]: 18 : else if (m->meleestr[i] == 'L') {
41 : 0 : strcat(Str4," lunges ");
42 : 0 : strcat(Str4,actionlocstr(m->meleestr[i+1]));
43 [ # # ]: 0 : if (Verbosity == VERBOSE) mprint(Str4);
44 : 0 : monster_melee(m,m->meleestr[i+1],m->level);
45 : : }
46 : 28 : i+=2;
47 : : }
48 : 8 : }
49 : :
50 : :
51 : :
52 : 10 : void monster_melee(pmt m, char hitloc, int bonus)
53 : : {
54 [ - + ]: 10 : if (player_on_sanctuary())
55 : 0 : print1("The aegis of your deity protects you!");
56 : : else {
57 : : /* being attacked wakes you up/stops fast move */
58 : 10 : resetgamestatus(FAST_MOVE);
59 : :
60 : : /* It's lawful to wait to be attacked */
61 [ + + ]: 10 : if (m->attacked==0) Player.alignment++;
62 : 10 : m->attacked++;
63 [ + - ]: 10 : if (m->uniqueness == COMMON) {
64 : 10 : strcpy(Str2,"The ");
65 : 10 : strcat(Str2,m->monstring);
66 : : }
67 : 0 : else strcpy(Str2,m->monstring);
68 [ + + ]: 10 : if (monster_hit(m,hitloc,bonus))
69 [ + + - - : 3 : switch(m->meleef) {
- - - - -
- - - - ]
70 : : case M_NO_OP:
71 : 1 : strcat(Str2," touches you.");
72 : 1 : mprint(Str2);
73 : 1 : break;
74 : : case M_MELEE_NORMAL:
75 : 2 : strcat(Str2," hits you.");
76 : 2 : mprint(Str2);
77 : 2 : m_hit(m,NORMAL_DAMAGE);
78 : 2 : break;
79 : : case M_MELEE_NG:
80 : 0 : strcat(Str2," hits you.");
81 : 0 : mprint(Str2);
82 : 0 : m_hit(m,NORMAL_DAMAGE);
83 [ # # ]: 0 : if (random_range(5)==3) m_sp_ng(m);
84 : 0 : break;
85 : : case M_MELEE_FIRE:
86 : 0 : strcat(Str2," blasts you with fire.");
87 : 0 : mprint(Str2);
88 : 0 : m_hit(m,FLAME);
89 : 0 : break;
90 : : case M_MELEE_DRAGON:
91 : 0 : strcat(Str2," hits you and blasts you with fire.");
92 : 0 : mprint(Str2);
93 : 0 : m_hit(m,NORMAL_DAMAGE);
94 : 0 : m_hit(m,FLAME);
95 : 0 : break;
96 : : case M_MELEE_ELEC:
97 : 0 : strcat(Str2," lashes you with electricity.");
98 : 0 : mprint(Str2);
99 : 0 : m_hit(m,ELECTRICITY);
100 : 0 : break;
101 : : case M_MELEE_COLD:
102 : 0 : strcat(Str2," freezes you with cold.");
103 : 0 : mprint(Str2);
104 : 0 : m_hit(m,ELECTRICITY);
105 : 0 : break;
106 : : case M_MELEE_POISON:
107 : 0 : strcat(Str2," hits you.");
108 : 0 : mprint(Str2);
109 : 0 : m_hit(m,NORMAL_DAMAGE);
110 [ # # ]: 0 : if (random_range(10) < m->level) {
111 : 0 : mprint("You've been poisoned!");
112 : 0 : p_poison(m->dmg);
113 : : }
114 : 0 : break;
115 : : case M_MELEE_GRAPPLE:
116 : 0 : strcat(Str2," grabs you.");
117 : 0 : mprint(Str2);
118 : 0 : m_hit(m,NORMAL_DAMAGE);
119 : 0 : Player.status[IMMOBILE]++;
120 : 0 : break;
121 : : case M_MELEE_SPIRIT:
122 : 0 : strcat(Str2," touches you.");
123 : 0 : mprint(Str2);
124 : 0 : m_hit(m,NORMAL_DAMAGE);
125 : 0 : drain_life(m->level);
126 : 0 : break;
127 : : case M_MELEE_DISEASE:
128 : 0 : strcat(Str2," hits you.");
129 : 0 : mprint(Str2);
130 : 0 : m_hit(m,NORMAL_DAMAGE);
131 [ # # ]: 0 : if (random_range(10) < m->level) {
132 : 0 : mprint("You've been infected!");
133 : 0 : disease(m->level);
134 : : }
135 : 0 : break;
136 : : case M_MELEE_SLEEP:
137 : 0 : strcat(Str2," hit you.");
138 : 0 : mprint(Str2);
139 : 0 : m_hit(m,NORMAL_DAMAGE);
140 [ # # ]: 0 : if (random_range(10) < m->level) {
141 : 0 : mprint("You feel drowsy");
142 : 0 : sleep_player(m->level);
143 : : }
144 : 3 : break;
145 : : }
146 : : else {
147 [ + + ]: 7 : if (random_range(10)) strcat(Str2," missed you.");
148 : : else {
149 [ - + ]: 2 : if (Verbosity == TERSE) {
150 [ # # # # ]: 0 : switch(random_range(10)) {
151 : : case 0:
152 : 0 : strcat(Str2," blundered severely.");
153 : 0 : m_damage(m,m->dmg,UNSTOPPABLE); break;
154 : : case 1:
155 : 0 : strcat(Str2," tripped while attacking.");m_dropstuff(m);break;
156 : : case 2:
157 : 0 : strcat(Str2," seems seriously confused.");
158 : 0 : m->speed = min(30,m->speed*2); break;
159 : : default:
160 : 0 : strcat(Str2," missed you.");
161 : : }
162 : : }
163 [ - + - - : 2 : switch(random_range(10)) {
- + - - -
- - ]
164 : 0 : case 0: strcat(Str2," flailed stupidly at you."); break;
165 : 1 : case 1: strcat(Str2," made you laugh."); break;
166 : 0 : case 2: strcat(Str2," blundered severely.");
167 : 0 : m_damage(m,m->dmg,UNSTOPPABLE); break;
168 : 0 : case 3: strcat(Str2," tripped while attacking.");m_dropstuff(m);break;
169 : 0 : case 4: strcat(Str2," seems seriously confused.");
170 : 0 : m->speed = min(30,m->speed*2); break;
171 : 1 : case 5: strcat(Str2," is seriously ashamed."); break;
172 : 0 : case 6: strcat(Str2," made a boo-boo."); break;
173 : 0 : case 7: strcat(Str2," blundered."); break;
174 : 0 : case 8: strcat(Str2," cries out in anger and frustration."); break;
175 : 0 : case 9: strcat(Str2," curses your ancestry."); break;
176 : : }
177 : : }
178 : 7 : mprint(Str2);
179 : : }
180 : : }
181 : 10 : }
182 : :
183 : :
184 : :
185 : : /* checks to see if player hits with hitmod vs. monster m at location hitloc */
186 : 10 : int monster_hit(pmt m, char hitloc, int bonus)
187 : : {
188 : 10 : int i=0,blocks=FALSE,goodblocks=0,hit,riposte=FALSE;
189 [ + + ]: 28 : while (i<strlen(Player.meleestr)) {
190 [ + + ][ - + ]: 18 : if ((Player.meleestr[i] == 'B') || (Player.meleestr[i] == 'R')) {
191 : 8 : blocks = TRUE;
192 [ + + ]: 8 : if (hitloc == Player.meleestr[i+1]) {
193 : 5 : goodblocks++;
194 [ - + ]: 5 : if (Player.meleestr[i] == 'R') riposte = TRUE;
195 : : }
196 : : }
197 : 18 : i+=2;
198 : : }
199 [ + + ]: 10 : if (! blocks) goodblocks = -1;
200 : 10 : hit = hitp(m->hit+bonus,Player.defense+goodblocks*10);
201 [ + + ][ + + ]: 10 : if ((! hit) && (goodblocks > 0)) {
202 [ + - ]: 4 : if (Verbosity == VERBOSE) mprint("You blocked it!");
203 [ - + ]: 4 : if (riposte) {
204 [ # # ]: 0 : if (Verbosity != TERSE) mprint("You got a riposte!");
205 [ # # ]: 0 : if (hitp(Player.hit,m->ac)) {
206 : 0 : mprint("You hit!");
207 : 0 : weapon_use(0,Player.possessions[O_WEAPON_HAND],m);
208 : : }
209 : 0 : else mprint("You missed.");
210 : : }
211 : : }
212 : 10 : return(hit);
213 : : }
214 : :
215 : :
216 : :
217 : : /* decide monster actions in tactical combat mode */
218 : : /* if monster is skilled, it can try see the player's attacks coming and
219 : : try to block appropriately. */
220 : :
221 : 15 : void transcribe_monster_actions(pmt m)
222 : : {
223 : : int i;
224 : : char attack_loc,block_loc;
225 : : static char mmstr[80];
226 : :
227 : : int p_blocks[3];
228 : : int p_attacks[3];
229 : :
230 [ + + ]: 60 : for(i=0;i<3;i++)p_blocks[i] = p_attacks[i] = 0;
231 : :
232 : : /* Find which area player blocks and attacks least in */
233 : 15 : i = 0;
234 [ + + ]: 41 : while (i<strlen(Player.meleestr)) {
235 [ + + ][ - + ]: 26 : if ((Player.meleestr[i] == 'B') ||
236 : 15 : (Player.meleestr[i] == 'R')) {
237 [ - + ]: 11 : if (Player.meleestr[i+1] == 'H') p_blocks[0]++;
238 [ + - ]: 11 : if (Player.meleestr[i+1] == 'C') p_blocks[1]++;
239 [ - + ]: 11 : if (Player.meleestr[i+1] == 'L') p_blocks[2]++;
240 : : }
241 [ + - ][ + + ]: 15 : else if ((Player.meleestr[i] == 'A') ||
242 : 15 : (Player.meleestr[i] == 'L')) {
243 [ - + ]: 4 : if (Player.meleestr[i+1] == 'H') p_attacks[0]++;
244 [ + - ]: 4 : if (Player.meleestr[i+1] == 'C') p_attacks[1]++;
245 [ - + ]: 4 : if (Player.meleestr[i+1] == 'L') p_attacks[2]++;
246 : : }
247 : 26 : i+=2;
248 : : }
249 : :
250 [ + - ][ + - ]: 15 : if ((p_blocks[2] <= p_blocks[1]) &&
251 : 15 : (p_blocks[2] <= p_blocks[0]))
252 : 15 : attack_loc = 'L';
253 [ # # ][ # # ]: 0 : else if ((p_blocks[1] <= p_blocks[2]) &&
254 : 0 : (p_blocks[1] <= p_blocks[0]))
255 : 0 : attack_loc = 'C'; /* DG 12/31/98 */
256 : 0 : else attack_loc = 'H';
257 [ + - ][ + - ]: 15 : if ((p_attacks[2] <= p_attacks[1]) &&
258 : 15 : (p_attacks[2] <= p_attacks[0]))
259 : 15 : block_loc = 'L';
260 [ # # ][ # # ]: 0 : else if ((p_attacks[1] <= p_attacks[2]) &&
261 : 0 : (p_attacks[1] <= p_attacks[0]))
262 : 0 : block_loc = 'C';
263 : 0 : else block_loc = 'H';
264 : :
265 : 15 : m->meleestr = mmstr;
266 : :
267 [ + - ]: 15 : if (m->id != NPC)
268 : 15 : strcpy(m->meleestr,Monsters[m->id].meleestr);
269 : : else {
270 : 0 : strcpy(m->meleestr,"");
271 [ # # ]: 0 : for(i=0;i<m->level;i+=2)
272 : 0 : strcat(m->meleestr,"L?R?");
273 : : }
274 : :
275 : 15 : i = 0;
276 [ + + ]: 65 : while (i<strlen(m->meleestr)) {
277 [ + + ][ - + ]: 50 : if ((m->meleestr[i] == 'A') || (m->meleestr[i] == 'L')) {
278 [ - + ]: 40 : if (m->meleestr[i+1] == '?') {
279 [ # # ]: 0 : if (m->level+random_range(30) > Player.level+random_range(20))
280 : 0 : m->meleestr[i+1] = attack_loc;
281 : 0 : else m->meleestr[i+1] = random_loc();
282 : : }
283 [ + + ]: 20 : else if (m->meleestr[i+1] == 'X') m->meleestr[i+1] = random_loc();
284 : : }
285 [ - + ][ # # ]: 30 : else if ((m->meleestr[i] == 'B') || (m->meleestr[i] == 'R')) {
286 [ + - ]: 30 : if (m->meleestr[i+1] == '?') {
287 [ + + ]: 30 : if (m->level+random_range(30) > Player.level+random_range(20))
288 : 26 : m->meleestr[i+1] = block_loc;
289 : 30 : else m->meleestr[i+1] = random_loc();
290 : : }
291 [ # # ]: 0 : else if (m->meleestr[i+1] == 'X') m->meleestr[i+1] = random_loc();
292 : : }
293 : 50 : i+=2;
294 : : }
295 : 15 : }
296 : :
297 : 14 : char random_loc(void)
298 : : {
299 [ + + + ]: 14 : switch(random_range(3)) {
300 : 7 : case 0:return('H');
301 : 3 : case 1:return('C');
302 : 4 : default:return('L');
303 : : }
304 : : }
|