14 extern current_town_type far c_town
;
15 extern party_record_type far party
;
16 extern piles_of_stuff_dumping_type
*data_store
;
17 extern piles_of_stuff_dumping_type2
*data_store2
;
18 extern talking_record_type far talking
;
19 extern scenario_data_type far scenario
;
21 extern short overall_mode
;
22 extern outdoor_record_type far outdoors
[2][2];
23 extern unsigned char far out
[96][96];
24 extern unsigned char far out_e
[96][96];
25 extern unsigned char far combat_terrain
[64][64];
26 extern short which_combat_type
;
27 extern pc_record_type far adven
[6];
28 extern big_tr_type far t_d
;
29 extern short monst_target
[T_M
]; // 0-5 target that pc 6 - no target 100 + x - target monster x
30 extern short spell_caster
, missile_firer
,current_monst_tactic
;
31 extern short far hit_chance
[21];
32 extern unsigned char far misc_i
[64][64];
33 extern location monster_targs
[T_M
];
35 extern location pc_pos
[6],center
;
36 extern short boom_gr
[8],futzing
;
37 extern Boolean processing_fields
,monsters_going
;
38 extern town_item_list far t_i
;
42 short charm_odds
[20] = {90,90,85,80,78, 75,73,60,40,30, 20,10,5,2,1, 0,0,0,0,0};
44 creature_start_type null_start_type
= {0,0,{80,80},1,0,0,0,0,0,0,0, 0,-1,-1,-1};
46 monster_record_type
return_monster_template(unsigned char store
)
47 { monster_record_type monst
;
51 monst
= scenario
.scen_monsters
[store
];
52 if (monst
.spec_skill
== 11)
53 monst
.picture_num
= 0;
56 monst
.health
= (PSD
[306][7] == 0) ? monst
.health
: monst
.health
/ 2;
58 // now adjust for difficulty
59 monst
.health
= monst
.health
* difficulty_adjust();
61 monst
.m_health
= monst
.health
; // in scenario file, health is stored in health field
63 monst
.mp
= monst
.max_mp
;
67 if ((monst
.mu
> 0) || (monst
.cl
> 0))
68 monst
.max_mp
= monst
.mp
= 12 * monst
.level
;
70 monst
.m_morale
= 10 * monst
.level
;
71 if (monst
.level
>= 20)
72 monst
.m_morale
+= 10 * (monst
.level
- 20);
74 monst
.morale
= monst
.m_morale
;
76 for (i
= 0; i
< 15; i
++)
82 short difficulty_adjust()
87 for (i
= 0; i
< 6; i
++)
88 if (adven
[i
].main_status
== 1)
91 if ((scenario
.difficulty
<= 0) && (j
>= 60))
93 if ((scenario
.difficulty
<= 1) && (j
>= 130))
95 if ((scenario
.difficulty
<= 2) && (j
>= 210))
100 short out_enc_lev_tot(short which
)
103 monster_record_type store_m
;
104 short num
[7] = {22,8,4,4,3,2,1};
106 if (party
.out_c
[which
].what_monst
.cant_flee
== TRUE
)
109 for (i
= 0; i
< 7; i
++)
110 if (party
.out_c
[which
].what_monst
.monst
[i
] != 0) {
111 store_m
= return_monster_template(party
.out_c
[which
].what_monst
.monst
[i
]);
112 count
+= store_m
.level
* num
[i
];
121 for (i
= 0; i
< T_M
; i
++)
122 if (c_town
.monst
.dudes
[i
].active
> 0)
127 void create_wand_monst()
129 short r1
,r2
,i
= 0,num_tries
= 0;
133 if (overall_mode
== 0)
134 if (is_null_out_wand_entry(outdoors
[party
.i_w_c
.x
][party
.i_w_c
.y
].wandering
[r1
]) == 0) {
136 while ((point_onscreen(outdoors
[party
.i_w_c
.x
][party
.i_w_c
.y
].wandering_locs
[r2
],global_to_local(party
.p_loc
)) == TRUE
)
137 && (num_tries
++ < 100))
139 if (is_blocked(outdoors
[party
.i_w_c
.x
][party
.i_w_c
.y
].wandering_locs
[r2
]) == FALSE
)
140 place_outd_wand_monst(outdoors
[party
.i_w_c
.x
][party
.i_w_c
.y
].wandering_locs
[r2
],
141 outdoors
[party
.i_w_c
.x
][party
.i_w_c
.y
].wandering
[r1
],0);
146 if (overall_mode
!= 0) // won't place wandering is more than 50 monsters
147 if ((is_null_wand_entry(c_town
.town
.wandering
[r1
]) == 0) && (count_monst() <= 50)
148 && (party
.m_killed
[c_town
.town_num
] < c_town
.town
.max_num_monst
)) {
150 while ((point_onscreen(c_town
.town
.wandering_locs
[r2
],c_town
.p_loc
) == TRUE
) &&
151 (loc_off_act_area(c_town
.town
.wandering_locs
[r2
]) == FALSE
) && (num_tries
++ < 100))
153 for (i
= 0; i
< 4; i
++) {
154 if (c_town
.town
.wandering
[r1
].monst
[i
] != 0) { // place a monster
155 p_loc
= c_town
.town
.wandering_locs
[r2
];
156 p_loc
.x
+= get_ran(1,0,4) - 2;
157 p_loc
.y
+= get_ran(1,0,4) - 2;
158 if (is_blocked(p_loc
) == FALSE
)
159 place_monster(c_town
.town
.wandering
[r1
].monst
[i
],p_loc
);
160 p_loc
= c_town
.town
.wandering_locs
[r2
];
161 p_loc
.x
+= get_ran(1,0,4) - 2;
162 p_loc
.y
+= get_ran(1,0,4) - 2;
163 if ((r1
>= 2) && (i
== 0) && (is_blocked(p_loc
) == FALSE
)) // place extra monsters?
164 place_monster(c_town
.town
.wandering
[r1
].monst
[i
],p_loc
);
165 p_loc
= c_town
.town
.wandering_locs
[r2
];
166 p_loc
.x
+= get_ran(1,0,4) - 2;
167 p_loc
.y
+= get_ran(1,0,4) - 2;
168 if ((r1
== 3) && (i
== 1) && (is_blocked(p_loc
) == FALSE
))
169 place_monster(c_town
.town
.wandering
[r1
].monst
[i
],p_loc
);
175 void place_outd_wand_monst(location where
,out_wandering_type group
,short forced
)
183 if ((party
.out_c
[i
].exists
== FALSE
) || ((i
== 9) && (forced
> 0))) {
184 if ((sd_legit(group
.end_spec1
,group
.end_spec2
) == TRUE
) && (PSD
[group
.end_spec1
][group
.end_spec2
] > 0))
186 party
.out_c
[i
].exists
= TRUE
;
187 party
.out_c
[i
].direction
= 0;
188 party
.out_c
[i
].what_monst
= group
;
189 party
.out_c
[i
].which_sector
= party
.i_w_c
;
190 party
.out_c
[i
].m_loc
= where
;
191 if (party
.out_c
[i
].which_sector
.x
== 1)
192 party
.out_c
[i
].m_loc
.x
+= 48;
193 if (party
.out_c
[i
].which_sector
.y
== 1)
194 party
.out_c
[i
].m_loc
.y
+= 48;
195 l
= party
.out_c
[i
].m_loc
;
196 while ((forced
== TRUE
) && (is_blocked(l
)) && (j
< 50)) {
197 l
= party
.out_c
[i
].m_loc
;
198 l
.x
+= get_ran(1,0,2) - 1;
199 l
.y
+= get_ran(1,0,2) - 1;
202 party
.out_c
[i
].m_loc
= l
;
210 short is_null_wand_entry(wandering_type wand_entry
)
215 if (wand_entry
.monst
[i
] != 0)
222 short is_null_out_wand_entry(out_wandering_type wand_entry
)
227 if (wand_entry
.monst
[i
] != 0)
234 location
get_monst_head(short m_num
)
238 l
= c_town
.monst
.dudes
[m_num
].m_loc
;
239 if ((c_town
.monst
.dudes
[m_num
].m_d
.direction
< 4) &&
240 (c_town
.monst
.dudes
[m_num
].m_d
.x_width
> 1))
246 short get_monst_picnum(unsigned char monst
)
248 return scenario
.scen_monsters
[monst
].picture_num
;
251 void get_monst_dims(unsigned char monst
,short *width
, short *height
)
254 *width
= scenario
.scen_monsters
[monst
].x_width
;
255 *height
= scenario
.scen_monsters
[monst
].y_width
;
258 // Used to set up monsters for outdoor wandering encounters.
259 void set_up_monst(short mode
,unsigned char m_num
)
260 //mode; // 0 - unfriendly 1 - friendly & fightin'
264 for (which
= 0; which
< T_M
; which
++)
265 if (c_town
.monst
.dudes
[which
].active
== 0) {
266 c_town
.monst
.dudes
[which
].active
= 2;
267 c_town
.monst
.dudes
[which
].summoned
= 0;
268 c_town
.monst
.dudes
[which
].attitude
= mode
+ 1;
269 c_town
.monst
.dudes
[which
].number
= m_num
;
270 c_town
.monst
.dudes
[which
].m_d
= return_monster_template(m_num
);
271 c_town
.monst
.dudes
[which
].mobile
= TRUE
;
272 c_town
.monst
.dudes
[which
].monst_start
= null_start_type
;
280 location dest
,l1
,l2
, dummy_loc
= {0,0},store_loc
;
281 Boolean acted_yet
= FALSE
;
284 if (overall_mode
== 1)
285 for (i
= 0; i
< T_M
; i
++)
286 if ((c_town
.monst
.dudes
[i
].active
!= 0) && (c_town
.monst
.dudes
[i
].m_d
.status
[11] <= 0)
287 && (c_town
.monst
.dudes
[i
].m_d
.status
[12] <= 0)) {
288 // have to pick targets
289 if (c_town
.monst
.dudes
[i
].active
== 1)
292 target
= monst_pick_target(i
); // will return 0 if target party
293 target
= switch_target_to_adjacent(i
,target
);
295 if (dist(c_town
.monst
.dudes
[i
].m_loc
,c_town
.p_loc
) > 8)
297 else target
= select_active_pc();
299 if ((c_town
.monst
.dudes
[i
].attitude
% 2 != 1) && (target
< 6))
302 monst_target
[i
] = target
;
303 // sprintf((char *)debug," t: %d targets %d.",i,monst_target[i]);
304 // add_string_to_buf((char *) debug);
306 if ((c_town
.monst
.dudes
[i
].active
== 2)
307 || ((c_town
.monst
.dudes
[i
].active
!= 0) && (c_town
.monst
.dudes
[i
].attitude
% 2 != 1))) {
309 if (((c_town
.monst
.dudes
[i
].attitude
== 0) || (monst_target
[i
] == 6)) && (c_town
.hostile
== 0)) {
310 if (c_town
.monst
.dudes
[i
].mobile
== TRUE
) { // OK, it doesn't see the party or
311 // isn't nasty, and the town isn't totally hostile.
312 if ((c_town
.monst
.dudes
[i
].attitude
% 2 != 1) || (get_ran(1,0,1) == 0)) {
313 acted_yet
= rand_move(i
);
315 else acted_yet
= seek_party(i
,c_town
.monst
.dudes
[i
].m_loc
,c_town
.p_loc
);
318 if ((c_town
.monst
.dudes
[i
].attitude
> 0) || (c_town
.hostile
== 1)) {
319 if ((c_town
.monst
.dudes
[i
].mobile
== TRUE
) && (monst_target
[i
] != 6)) {
320 l1
= c_town
.monst
.dudes
[i
].m_loc
;
321 l2
= (monst_target
[i
] <= 6) ? c_town
.p_loc
: c_town
.monst
.dudes
[target
- 100].m_loc
;
323 if ((c_town
.monst
.dudes
[i
].m_d
.morale
< 0) && (c_town
.monst
.dudes
[i
].m_d
.spec_skill
!= 13)
324 && (c_town
.monst
.dudes
[i
].m_d
.m_type
!= 8)) {
325 acted_yet
= flee_party(i
,l1
,l2
);
326 if (get_ran(1,0,10) < 6)
327 c_town
.monst
.dudes
[i
].m_d
.morale
++;
329 else if (monst_hate_spot(i
,&l2
) == TRUE
)
330 acted_yet
= seek_party(i
,l1
,l2
);
331 else if (((c_town
.monst
.dudes
[i
].m_d
.mu
== 0) && (c_town
.monst
.dudes
[i
].m_d
.mu
== 0))
332 || (can_see(l1
,l2
,0) > 3))
333 acted_yet
= seek_party(i
,l1
,l2
);
339 // Make hostile monsters active
340 if ((c_town
.monst
.dudes
[i
].active
== 1) && (c_town
.monst
.dudes
[i
].attitude
% 2 == 1)
341 && (dist(c_town
.monst
.dudes
[i
].m_loc
,c_town
.p_loc
) <= 8)) {
342 r1
= get_ran(1,1,100);
343 r1
+= (party
.stuff_done
[305][0] > 0) ? 46 : 0;
344 r1
+= can_see(c_town
.monst
.dudes
[i
].m_loc
,c_town
.p_loc
,0) * 10;
346 c_town
.monst
.dudes
[i
].active
= 2;
347 add_string_to_buf("Monster saw you!");
348 // play go active sound
349 switch (c_town
.monst
.dudes
[i
].m_d
.m_type
) {
350 case 0: case 3: case 4: case 5: case 6: case 9:
351 play_sound(18); break;
352 default: play_sound(46); break;
355 for (j
= 0; j
< T_M
; j
++)
356 if ((c_town
.monst
.dudes
[j
].active
== 2)
357 && ((dist(c_town
.monst
.dudes
[i
].m_loc
,c_town
.monst
.dudes
[j
].m_loc
) <= 5) == TRUE
))
358 c_town
.monst
.dudes
[i
].active
= 2;
362 if (overall_mode
== 0) {
363 for (i
= 0; i
< 10; i
++)
364 if (party
.out_c
[i
].exists
== TRUE
) {
366 l1
= party
.out_c
[i
].m_loc
;
371 acted_yet
= rand_move(i
);
372 else acted_yet
= seek_party(i
,l1
,l2
);
377 Boolean
monst_hate_spot(short which_m
,location
*good_loc
)
379 location prospect
,loc
;
381 loc
= c_town
.monst
.dudes
[which_m
].m_loc
;
382 if ((misc_i
[loc
.x
][loc
.y
] & 224)
383 || (c_town
.explored
[loc
.x
][loc
.y
] & 64) // hate regular fields
384 || ((c_town
.explored
[loc
.x
][loc
.y
] & 32) && (c_town
.monst
.dudes
[which_m
].m_d
.radiate_1
!= 2)
385 && (c_town
.monst
.dudes
[which_m
].m_d
.immunities
& 32 == 0)) // hate ice wall?
386 || ((c_town
.explored
[loc
.x
][loc
.y
] & 4) && (c_town
.monst
.dudes
[which_m
].m_d
.radiate_1
!= 1)
387 && (c_town
.monst
.dudes
[which_m
].m_d
.immunities
& 8 == 0)) // hate fire wall?
388 || ((c_town
.explored
[loc
.x
][loc
.y
] & 16) && (c_town
.monst
.dudes
[which_m
].m_d
.radiate_1
!= 6)
389 && (c_town
.monst
.dudes
[which_m
].m_d
.immunities
& 3 == 0)) // hate stink cloud?
390 || ((c_town
.explored
[loc
.x
][loc
.y
] & 128) && (c_town
.monst
.dudes
[which_m
].m_d
.radiate_1
!= 5)
391 && (c_town
.monst
.dudes
[which_m
].m_d
.immunities
& 3 == 0)) // hate sleep cloud?
392 || ((c_town
.explored
[loc
.x
][loc
.y
] & 2) && (c_town
.monst
.dudes
[which_m
].m_d
.radiate_1
!= 3)
393 && (c_town
.monst
.dudes
[which_m
].m_d
.immunities
& 3 == 0)) // hate shock cloud?
394 || (((c_town
.monst
.dudes
[which_m
].m_d
.mu
> 0) || (c_town
.monst
.dudes
[which_m
].m_d
.cl
> 0))
395 && (c_town
.explored
[loc
.x
][loc
.y
] & 8))) // hate antimagic
397 prospect
= find_clear_spot(loc
,1);
398 if (prospect
.x
> 0) {
399 *good_loc
= prospect
;
407 short monst_pick_target(short which_m
)
409 creature_data_type
*cur_monst
;
410 short r1
,targ_pc
,targ_m
,a
,b
;
412 cur_monst
= &c_town
.monst
.dudes
[which_m
];
414 // First, any chance target is screwed?
415 if (monst_target
[which_m
] >= 100) {
416 if (((cur_monst
->attitude
% 2 == 1) &&
417 (c_town
.monst
.dudes
[monst_target
[which_m
] - 100].attitude
== cur_monst
->attitude
)) ||
418 ((cur_monst
->attitude
% 2 == 0) && (c_town
.monst
.dudes
[monst_target
[which_m
] - 100].attitude
% 2 == 0)))
419 monst_target
[which_m
] = 6;
420 else if (c_town
.monst
.dudes
[monst_target
[which_m
] - 100].active
== 0)
421 monst_target
[which_m
] = 6;
423 if (monst_target
[which_m
] < 6)
424 if (adven
[monst_target
[which_m
]].main_status
!= 1)
425 monst_target
[which_m
] = 6;
427 if ((is_combat()) && (cur_monst
->attitude
% 2 == 1)) {
428 if (spell_caster
< 6)
429 if ((get_ran(1,1,5) < 5) && (monst_can_see(which_m
,pc_pos
[spell_caster
]) == TRUE
)
430 && (adven
[spell_caster
].main_status
== 1))
432 if (missile_firer
< 6)
433 if ((get_ran(1,1,5) < 3) && (monst_can_see(which_m
,pc_pos
[missile_firer
]) == TRUE
)
434 && (adven
[missile_firer
].main_status
== 1))
435 return missile_firer
;
436 if (monst_target
[which_m
] < 6)
437 if ((monst_can_see(which_m
,pc_pos
[monst_target
[which_m
]]) == TRUE
)
438 && (adven
[monst_target
[which_m
]].main_status
== 1))
439 return monst_target
[which_m
];
442 // if (monst_target[which_m] >= 100) {
443 // if ((can_see(cur_monst->m_loc,c_town.monst.dudes[monst_target[which_m] - 100].m_loc,0) < 4)
444 // && (c_town.monst.dudes[monst_target[which_m] - 100].active > 0))
445 // return monst_target[which_m];
448 // Now pick a target pc and a target monst and see which is more attractive
449 targ_pc
= monst_pick_target_pc(which_m
,cur_monst
);
450 targ_m
= monst_pick_target_monst(cur_monst
);
452 if ((targ_pc
!= 6) && (targ_m
== 6))
454 if ((targ_pc
== 6) && (targ_m
!= 6))
456 if ((targ_pc
== 6) && (targ_m
== 6))
460 if (cur_monst
->attitude
% 2 == 0) {
463 if ((targ_m
== 6) && (cur_monst
->attitude
% 2 == 1))
465 if (dist(cur_monst
->m_loc
,c_town
.monst
.dudes
[targ_m
- 100].m_loc
) <
466 dist(cur_monst
->m_loc
,c_town
.p_loc
))
470 // Otherwise we're in combat
471 if ((dist(cur_monst
->m_loc
,c_town
.monst
.dudes
[targ_m
- 100].m_loc
) ==
472 dist(cur_monst
->m_loc
,pc_pos
[targ_pc
])) && (get_ran(1,0,6) < 3))
475 if (dist(cur_monst
->m_loc
,c_town
.monst
.dudes
[targ_m
- 100].m_loc
) <
476 dist(cur_monst
->m_loc
,pc_pos
[targ_pc
]))
482 short monst_pick_target_monst(creature_data_type
*which_m
)
484 short min_dist
= 1000,i
,cur_targ
= 6;
486 for (i
= 0; i
< T_M
; i
++) {
487 if ((c_town
.monst
.dudes
[i
].active
> 0) && // alive
488 (((which_m
->attitude
% 2 == 1) && (c_town
.monst
.dudes
[i
].attitude
% 2 == 0)) ||
489 ((which_m
->attitude
% 2 == 0) && (c_town
.monst
.dudes
[i
].attitude
% 2 == 1)) ||
490 ((which_m
->attitude
% 2 == 1) && (c_town
.monst
.dudes
[i
].attitude
!= which_m
->attitude
))) && // they hate each other
491 ((dist(which_m
->m_loc
,c_town
.monst
.dudes
[i
].m_loc
) < min_dist
) ||
492 ((dist(which_m
->m_loc
,c_town
.monst
.dudes
[i
].m_loc
) == min_dist
) && (get_ran(1,0,7) < 4))) &&
493 (monst_can_see(i
,c_town
.monst
.dudes
[i
].m_loc
) == TRUE
) ) {
494 min_dist
= dist(which_m
->m_loc
,c_town
.monst
.dudes
[i
].m_loc
);
502 short monst_pick_target_pc(short m_num
,creature_data_type
*which_m
)
504 short num_tries
= 0,r1
,store_targ
= 6;
506 if (which_m
->attitude
% 2 == 0)
511 // First pick any visible, nearby PC
513 while ((num_tries
< 6) && ((adven
[r1
].main_status
!= 1) ||
514 (monst_can_see(m_num
,pc_pos
[r1
]) == FALSE
))) {
521 // Then, see if target can be replaced with someone nice and close
523 while ((num_tries
< 4) && ((adven
[r1
].main_status
!= 1) ||
524 (dist(which_m
->m_loc
,pc_pos
[r1
]) > 4) ||
525 (monst_can_see(m_num
,pc_pos
[r1
]) == FALSE
))) {
532 else return store_targ
;
536 short select_active_pc()
538 short r1
, num_tries
= 0;
541 while ((adven
[r1
].main_status
!= 1) && (num_tries
++ < 50))
547 short closest_pc(location where
)
549 short how_close
= 200,i
,store
= 6;
551 for (i
= 0; i
< 6; i
++)
552 if ((adven
[i
].main_status
== 1) && (dist(where
,pc_pos
[i
]) < how_close
)) {
554 how_close
= dist(where
,pc_pos
[i
]);
559 short closest_monst(location where
,short mode
)
560 //mode; // 1 - closest hostile to PCs 2 - closest friendly to PCs
562 short how_close
= 200,i
,store
= 6;
564 for (i
= 0; i
< T_M
; i
++)
565 if ((((c_town
.monst
.dudes
[i
].attitude
% 2 == 1) && (mode
== 1)) ||
566 ((c_town
.monst
.dudes
[i
].attitude
% 2 == 0) && (mode
== 2)))
567 && (dist(where
,c_town
.monst
.dudes
[i
].m_loc
) < how_close
)) {
569 how_close
= dist(where
,c_town
.monst
.dudes
[i
].m_loc
);
574 short switch_target_to_adjacent(short which_m
,short orig_target
)
577 short i
,num_adj
= 0,targ_pc
= 6, targ_m
= 6;
579 monst_loc
= c_town
.monst
.dudes
[which_m
].m_loc
;
581 // First, take care of friendly monsters.
582 if (c_town
.monst
.dudes
[which_m
].attitude
% 2 == 0) {
583 if (orig_target
>= 100)
584 if ((c_town
.monst
.dudes
[orig_target
- 100].active
> 0) &&
585 (monst_adjacent(c_town
.monst
.dudes
[orig_target
- 100].m_loc
,which_m
) == TRUE
))
587 for (i
= 0; i
< T_M
; i
++)
588 if ((c_town
.monst
.dudes
[i
].active
> 0) &&
589 (c_town
.monst
.dudes
[i
].attitude
% 2 == 1) &&
590 (monst_adjacent(c_town
.monst
.dudes
[i
].m_loc
,which_m
) == TRUE
))
595 // If we get here while in town, just need to check if switch to pc
596 if ((is_town()) && (monst_adjacent(c_town
.p_loc
,which_m
) == TRUE
))
601 // If target is already adjacent, we're done here.
602 if ((is_combat()) && (orig_target
< 6))
603 if ((adven
[orig_target
].main_status
== 1) && (monst_adjacent(pc_pos
[orig_target
],which_m
) == TRUE
))
605 if (orig_target
>= 100)
606 if ((c_town
.monst
.dudes
[orig_target
- 100].active
> 0) &&
607 (monst_adjacent(c_town
.monst
.dudes
[orig_target
- 100].m_loc
,which_m
) == TRUE
))
610 // Anyone unarmored? Heh heh heh...
612 for (i
= 0; i
< 6; i
++)
613 if ((adven
[i
].main_status
== 1) && (monst_adjacent(pc_pos
[i
],which_m
) == TRUE
) &&
614 (get_encumberance(i
) < 2))
617 // Check for a nice, adjacent, friendly monster and maybe attack
618 for (i
= 0; i
< T_M
; i
++)
619 if ((c_town
.monst
.dudes
[i
].active
> 0) &&
620 (c_town
.monst
.dudes
[i
].attitude
% 2 == 0) &&
621 (monst_adjacent(c_town
.monst
.dudes
[i
].m_loc
,which_m
) == TRUE
) &&
622 (get_ran(1,0,2) < 2))
625 // OK. Now if this monster has PCs adjacent, pick one at randomn and hack. Otherwise,
626 // stick with orig. target.
627 for (i
= 0; i
< 6; i
++)
628 if ((adven
[i
].main_status
== 1) && (monst_adjacent(pc_pos
[i
],which_m
) == TRUE
))
635 num_adj
= get_ran(1,1,num_adj
);
636 while ((num_adj
> 1) || (adven
[i
].main_status
!= 1) || (monst_adjacent(pc_pos
[i
],which_m
) == FALSE
)) {
637 if ((adven
[i
].main_status
== 1) && (monst_adjacent(pc_pos
[i
],which_m
) == TRUE
))
645 Boolean
rand_move(char i
)
647 Boolean acted_yet
= FALSE
;
651 // first, if outdoor, just roam.
653 store_loc
= random_shift(party
.out_c
[i
].m_loc
);
654 return outdoor_move_monster(i
,store_loc
);
657 if (same_point(monster_targs
[i
],c_town
.monst
.dudes
[i
].m_loc
) == TRUE
)
658 monster_targs
[i
].x
= 0;
660 // FIrst, try to move to monst_targs. If it don't work, then we'll shift.
661 if (monster_targs
[i
].x
> 0)
662 acted_yet
= seek_party(i
,c_town
.monst
.dudes
[i
].m_loc
,monster_targs
[i
]);
664 if (acted_yet
== FALSE
) {
665 monster_targs
[i
].x
= 0;
666 for (j
= 0; j
< 3; j
++) {
667 store_loc
= c_town
.monst
.dudes
[i
].m_loc
;
668 store_loc
.x
+= get_ran(1,0,24) - 12;
669 store_loc
.y
+= get_ran(1,0,24) - 12;
670 if ((loc_off_act_area(store_loc
) == FALSE
) && (can_see(c_town
.monst
.dudes
[i
].m_loc
,store_loc
,0) < 5)) {
671 monster_targs
[i
] = store_loc
; j
= 3;
675 if (monster_targs
[i
].x
== 0) {
676 // maybe pick a wand loc, else juist pick a loc
678 store_loc
= c_town
.town
.wandering_locs
[j
];
680 if ((loc_off_act_area(store_loc
) == FALSE
) && (get_ran(1,0,1) == 1))
681 monster_targs
[i
] = store_loc
;
683 store_loc
= c_town
.monst
.dudes
[i
].m_loc
;
684 store_loc
.x
+= get_ran(1,0,20) - 10;
685 store_loc
.y
+= get_ran(1,0,20) - 10;
686 if (loc_off_act_area(store_loc
) == FALSE
)
687 monster_targs
[i
] = store_loc
;
690 if (monster_targs
[i
].x
> 0)
691 acted_yet
= seek_party(i
,c_town
.monst
.dudes
[i
].m_loc
,monster_targs
[i
]);
701 Boolean
seek_party(short i
,location l1
,location l2
)
703 Boolean acted_yet
= FALSE
;
705 if ((l1
.x
> l2
.x
) && (l1
.y
> l2
.y
))
706 acted_yet
= try_move(i
,l1
,-1,-1);
707 if ((l1
.x
< l2
.x
) & (l1
.y
< l2
.y
) & (acted_yet
== FALSE
))
708 acted_yet
= try_move(i
,l1
,1,1);
709 if ((l1
.x
> l2
.x
) & (l1
.y
< l2
.y
) & (acted_yet
== FALSE
))
710 acted_yet
= try_move(i
,l1
,-1,1);
711 if ((l1
.x
< l2
.x
) & (l1
.y
> l2
.y
) & (acted_yet
== FALSE
))
712 acted_yet
= try_move(i
,l1
,1,-1);
713 if ((l1
.x
> l2
.x
) & (acted_yet
== FALSE
))
714 acted_yet
= try_move(i
,l1
,-1,0);
715 if ((l1
.x
< l2
.x
) & (acted_yet
== FALSE
))
716 acted_yet
= try_move(i
,l1
,1,0);
717 if ( (l1
.y
< l2
.y
) & (acted_yet
== FALSE
))
718 acted_yet
= try_move(i
,l1
,0,1);
719 if ( (l1
.y
> l2
.y
) & (acted_yet
== FALSE
))
720 acted_yet
= try_move(i
,l1
,0,-1);
721 if (acted_yet
== FALSE
) {
723 m
= get_ran(1,0,2) - 1;
724 n
= get_ran(1,0,2) - 1;
725 acted_yet
= try_move(i
,l1
,m
,n
);
730 Boolean
flee_party(short i
,location l1
,location l2
)
732 Boolean acted_yet
= FALSE
;
734 if ((l1
.x
> l2
.x
) & (l1
.y
> l2
.y
))
735 acted_yet
= try_move(i
,l1
,1,1);
736 if ((l1
.x
< l2
.x
) & (l1
.y
< l2
.y
) & (acted_yet
== FALSE
))
737 acted_yet
= try_move(i
,l1
,-1,-1);
738 if ((l1
.x
> l2
.x
) & (l1
.y
< l2
.y
) & (acted_yet
== FALSE
))
739 acted_yet
= try_move(i
,l1
,1,-1);
740 if ((l1
.x
< l2
.x
) & (l1
.y
> l2
.y
) & (acted_yet
== FALSE
))
741 acted_yet
= try_move(i
,l1
,-1,+1);
742 if ((l1
.x
> l2
.x
) & (acted_yet
== FALSE
))
743 acted_yet
= try_move(i
,l1
,1,0);
744 if ((l1
.x
< l2
.x
) & (acted_yet
== FALSE
))
745 acted_yet
= try_move(i
,l1
,-1,0);
746 if ( (l1
.y
< l2
.y
) & (acted_yet
== FALSE
))
747 acted_yet
= try_move(i
,l1
,0,-1);
748 if ( (l1
.y
> l2
.y
) & (acted_yet
== FALSE
))
749 acted_yet
= try_move(i
,l1
,0,1);
750 if (acted_yet
== FALSE
) {
752 acted_yet
= rand_move(i
);
757 Boolean
try_move(short i
,location start
,short x
,short y
)
766 if (overall_mode
== 1)
767 return town_move_monster(i
,dest
);
768 if (overall_mode
== 0)
769 return outdoor_move_monster(i
,dest
);
770 if (overall_mode
== 10)
771 return combat_move_monster((short) i
,dest
);
775 Boolean
combat_move_monster(short which
,location destination
)
780 if (monst_can_be_there(destination
,which
) == FALSE
)
782 else if (monst_check_special_terrain(destination
,2,which
) == FALSE
)
785 //if (point_onscreen(destination,center) == TRUE) {
786 // print_nums(999, c_town.monst.dudes[which].m_loc.x,c_town.monst.dudes[which].m_loc.y);
787 // print_nums(monst_target[which],destination.x,destination.y);
789 c_town
.monst
.dudes
[which
].m_d
.direction
=
790 set_direction(c_town
.monst
.dudes
[which
].m_loc
, destination
);
791 c_town
.monst
.dudes
[which
].m_loc
= destination
;
792 monst_inflict_fields(which
);
794 if ((monst_target
[which
] != 6) && (point_onscreen(destination
,center
) == TRUE
)) {
796 move_sound(combat_terrain
[destination
.x
][destination
.y
],
797 (short) c_town
.monst
.dudes
[which
].m_d
.ap
);
798 else move_sound(t_d
.terrain
[destination
.x
][destination
.y
],
799 (short) c_town
.monst
.dudes
[which
].m_d
.ap
);
807 // Looks at all spaces within 2, looking for a spot which is clear of nastiness and beings
808 // returns {0,0} if none found
809 // THIS MAKES NO ADJUSTMENTS FOR BIG MONSTERS!!!
810 location
find_clear_spot(location from_where
,short mode
)
811 //mode; // 0 - normal 1 - prefer adjacent space
813 location loc
,store_loc
= {0,0};
814 short num_tries
= 0,r1
;
816 while (num_tries
< 75) {
819 r1
= get_ran(1,-2,2);
821 r1
= get_ran(1,-2,2);
823 if ((loc_off_act_area(loc
) == FALSE
) && (is_blocked(loc
) == FALSE
)
824 && (can_see(from_where
,loc
,1) == 0)
825 && (!(is_combat()) || (pc_there(loc
) == 6))
826 && (!(is_town()) || (same_point(loc
,c_town
.p_loc
) == FALSE
))
827 && (!(misc_i
[loc
.x
][loc
.y
] & 248)) &&
828 (!(c_town
.explored
[loc
.x
][loc
.y
] & 254))) {
829 if ((mode
== 0) || ((mode
== 1) && (adjacent(from_where
,loc
) == TRUE
)))
831 else store_loc
= loc
;
837 short pc_there(location where
)
841 for (i
= 0; i
< 6; i
++)
842 if ((same_point(where
,pc_pos
[i
]) == TRUE
) && (adven
[i
].main_status
== 1))
847 location
random_shift(location start
)
852 store
.x
= store
.x
+ get_ran(1,0,2) - 1;
853 store
.y
= store
.y
+ get_ran(1,0,2) - 1;
858 Boolean
outdoor_move_monster(short num
,location dest
)
861 if ((outd_is_blocked(dest
) == FALSE
) && (outd_is_special(dest
) == FALSE
) &&
862 (same_point(dest
, party
.p_loc
) != TRUE
) &&
863 ((out
[dest
.x
][dest
.y
] > 21) || (out
[dest
.x
][dest
.y
] < 5))) {
864 party
.out_c
[num
].direction
=
865 set_direction(party
.out_c
[num
].m_loc
, dest
);
866 party
.out_c
[num
].m_loc
= dest
;
872 Boolean
town_move_monster(short num
,location dest
)
874 if (monst_check_special_terrain(dest
,1,num
) == FALSE
)
877 if (monst_can_be_there(dest
,num
) == TRUE
) {
878 c_town
.monst
.dudes
[num
].m_d
.direction
=
879 set_direction(c_town
.monst
.dudes
[num
].m_loc
, dest
);
880 c_town
.monst
.dudes
[num
].m_loc
= dest
;
881 monst_inflict_fields(num
);
887 Boolean
monster_placid(short m_num
)
889 if ((c_town
.monst
.dudes
[m_num
].attitude
== 0) ||
890 ((c_town
.monst
.dudes
[m_num
].attitude
== 2) && (party
.stuff_done
[305][9] == 0)))
892 else { return FALSE
;}
895 // This damages a monster by any fields it's in, and destroys any barrels or crates
897 void monst_inflict_fields(short which_monst
)
900 location where_check
;
901 creature_data_type
*which_m
;
903 if (c_town
.monst
.dudes
[which_monst
].active
== 0)
906 which_m
= &c_town
.monst
.dudes
[which_monst
];
907 for (i
= 0; i
< c_town
.monst
.dudes
[which_monst
].m_d
.x_width
; i
++)
908 for (j
= 0; j
< c_town
.monst
.dudes
[which_monst
].m_d
.y_width
; j
++)
909 if (c_town
.monst
.dudes
[which_monst
].active
> 0) {
910 where_check
.x
= c_town
.monst
.dudes
[which_monst
].m_loc
.x
+ i
;
911 where_check
.y
= c_town
.monst
.dudes
[which_monst
].m_loc
.y
+ j
;
912 if (is_quickfire(where_check
.x
,where_check
.y
)) {
914 damage_monst(which_monst
,7,r1
,0,1);
917 if (is_blade_wall(where_check
.x
,where_check
.y
)) {
919 damage_monst(which_monst
,7,r1
,0,0);
922 if (is_force_wall(where_check
.x
,where_check
.y
)) {
924 damage_monst(which_monst
,7,r1
,0,3);
927 if (is_sleep_cloud(where_check
.x
,where_check
.y
)) {
928 charm_monst(which_m
,0,11,3);
931 if (is_ice_wall(where_check
.x
,where_check
.y
)) {
933 if (c_town
.monst
.dudes
[which_monst
].m_d
.spec_skill
!= 23)
934 damage_monst(which_monst
,7,r1
,0,5);
937 if (is_scloud(where_check
.x
,where_check
.y
)) {
939 curse_monst(which_m
,r1
);
942 if ((is_web(where_check
.x
,where_check
.y
)) && (which_m
->m_d
.m_type
!= 12)) {
943 monst_spell_note(which_m
->number
,19);
945 web_monst(which_m
,r1
);
946 take_web(where_check
.x
,where_check
.y
);
949 if (is_fire_wall(where_check
.x
,where_check
.y
)) {
951 if (c_town
.monst
.dudes
[which_monst
].m_d
.spec_skill
!= 22)
952 damage_monst(which_monst
,7,r1
,0,1);
956 if (c_town
.monst
.dudes
[which_monst
].active
> 0)
957 for (i
= 0; i
< c_town
.monst
.dudes
[which_monst
].m_d
.x_width
; i
++)
958 for (j
= 0; j
< c_town
.monst
.dudes
[which_monst
].m_d
.y_width
; j
++) {
959 where_check
.x
= c_town
.monst
.dudes
[which_monst
].m_loc
.x
+ i
;
960 where_check
.y
= c_town
.monst
.dudes
[which_monst
].m_loc
.y
+ j
;
961 if ((is_crate(where_check
.x
,where_check
.y
)) ||
962 (is_barrel(where_check
.x
,where_check
.y
)) )
963 for (k
= 0; k
< NUM_TOWN_ITEMS
; k
++)
964 if ((t_i
.items
[k
].variety
> 0) && (is_contained(t_i
.items
[k
]) == TRUE
)
965 && (same_point(t_i
.items
[k
].item_loc
,where_check
) == TRUE
))
966 t_i
.items
[k
].item_properties
= t_i
.items
[k
].item_properties
& 247;
967 take_crate(where_check
.x
,where_check
.y
);
968 take_barrel(where_check
.x
,where_check
.y
);
969 if (is_fire_barrier(where_check
.x
,where_check
.y
)) {
970 r1
= get_ran(2,1,10);
971 damage_monst(which_monst
,7,r1
,0,1);
977 Boolean
monst_check_special_terrain(location where_check
,short mode
,short which_monst
)
978 //mode; // 1 - town 2 - combat
982 short r1
,i
,j
,choice
,door_pc
,guts
= 0;
983 Boolean can_enter
= TRUE
,mage
= FALSE
;
984 location out_where
,from_loc
,to_loc
;
985 Boolean do_look
= FALSE
; // If becomes true, terrain changed, so need to update what party sees
986 creature_data_type
*which_m
;
989 from_loc
= c_town
.monst
.dudes
[which_monst
].m_loc
;
992 ter
= t_d
.terrain
[where_check
.x
][where_check
.y
];
995 ter
= combat_terrain
[where_check
.x
][where_check
.y
];
998 which_m
= &c_town
.monst
.dudes
[which_monst
];
999 ter_abil
= scenario
.ter_types
[ter
].special
;
1001 if ((mode
> 0) && (ter_abil
>= 16) &&
1004 ((ter_abil
== 16) && (where_check
.y
> from_loc
.y
)) ||
1005 ((ter_abil
== 17) && (where_check
.x
< from_loc
.x
)) ||
1006 ((ter_abil
== 18) && (where_check
.y
< from_loc
.y
)) ||
1007 ((ter_abil
== 19) && (where_check
.x
> from_loc
.x
)) ) {
1012 // begin determining guts, which determines how enthused the monst is about entering
1014 if ((which_m
->m_d
.mu
> 0) || (which_m
->m_d
.cl
> 0))
1016 if (which_m
->m_d
.spec_skill
== 13)
1018 else guts
= get_ran(1,1,(which_m
->m_d
.level
/ 2));
1019 guts
+= which_m
->m_d
.health
/ 20;
1022 if (which_m
->attitude
== 0)
1025 if ((is_antimagic(where_check
.x
,where_check
.y
)) && (mage
== TRUE
))
1027 if ((is_fire_wall(where_check
.x
,where_check
.y
)) && (which_m
->m_d
.spec_skill
!= 22)) {
1028 if (guts
< 3) return FALSE
;
1030 if (is_force_wall(where_check
.x
,where_check
.y
)) {
1031 if (guts
< 4) return FALSE
;
1033 if ((is_ice_wall(where_check
.x
,where_check
.y
)) && (which_m
->m_d
.spec_skill
!= 23)) {
1034 if (guts
< 5) return FALSE
;
1036 if (is_sleep_cloud(where_check
.x
,where_check
.y
)) {
1037 if (guts
< 8) return FALSE
;
1039 if (is_blade_wall(where_check
.x
,where_check
.y
)) {
1040 if (guts
< 8) return FALSE
;
1042 if (is_quickfire(where_check
.x
,where_check
.y
)) {
1043 if (guts
< 8) return FALSE
;
1045 if (is_scloud(where_check
.x
,where_check
.y
)) {
1046 if (guts
< 4) return FALSE
;
1048 if ((is_web(where_check
.x
,where_check
.y
)) && (which_m
->m_d
.m_type
!= 12)) {
1049 if (guts
< 3) return FALSE
;
1051 if (is_fire_barrier(where_check
.x
,where_check
.y
)) {
1052 if ((which_m
->attitude
% 2 == 1) && (get_ran(1,0,100) < (which_m
->m_d
.mu
* 10 + which_m
->m_d
.cl
* 4))) {
1054 add_string_to_buf("Monster breaks barrier.");
1055 take_fire_barrier(where_check
.x
,where_check
.y
);
1058 if (guts
< 6) return FALSE
;
1059 r1
= get_ran(1,0,10);
1060 if ((r1
< 8) || (monster_placid(which_monst
)))
1064 if (is_force_barrier(where_check
.x
,where_check
.y
)) { /// Not in big towns
1065 if ((which_m
->attitude
% 2 == 1) && (get_ran(1,0,100) < (which_m
->m_d
.mu
* 10 + which_m
->m_d
.cl
* 4))
1066 && (c_town
.town_num
>= 20)) {
1068 add_string_to_buf("Monster breaks barrier.");
1069 take_force_barrier(where_check
.x
,where_check
.y
);
1071 else can_enter
= FALSE
;
1073 if (is_crate(where_check
.x
,where_check
.y
)) {
1074 if (monster_placid(which_monst
))
1077 to_loc
= push_loc(from_loc
,where_check
);
1078 take_crate((short) where_check
.x
,(short) where_check
.y
);
1080 make_crate((short) to_loc
.x
,(short) to_loc
.y
);
1081 for (i
= 0; i
< NUM_TOWN_ITEMS
; i
++)
1082 if ((t_i
.items
[i
].variety
> 0) && (same_point(t_i
.items
[i
].item_loc
,where_check
))
1083 && (is_contained(t_i
.items
[i
]) == TRUE
))
1084 t_i
.items
[i
].item_loc
= to_loc
;
1087 if (is_barrel(where_check
.x
,where_check
.y
)) {
1088 if (monster_placid(which_monst
))
1091 to_loc
= push_loc(from_loc
,where_check
);
1092 take_barrel((short) where_check
.x
,(short) where_check
.y
);
1094 make_barrel((short) to_loc
.x
,(short) to_loc
.y
);
1095 for (i
= 0; i
< NUM_TOWN_ITEMS
; i
++)
1096 if ((t_i
.items
[i
].variety
> 0) && (same_point(t_i
.items
[i
].item_loc
,where_check
))
1097 && (is_contained(t_i
.items
[i
]) == TRUE
))
1098 t_i
.items
[i
].item_loc
= to_loc
;
1102 if (monster_placid(which_monst
) && // monstyers don't hop into bed when things are calm
1103 (scenario
.ter_types
[ter
].picture
== 143))
1105 if ((scenario
.ter_types
[ter
].picture
<= 212) && (scenario
.ter_types
[ter
].picture
>= 207))
1108 if ((is_combat()) && (which_combat_type
== 0)) {
1109 c_town
.monst
.dudes
[which_monst
].active
= 0;
1110 add_string_to_buf("Monster escaped! ");
1118 if (!(monster_placid(which_monst
))) {
1119 t_d
.terrain
[where_check
.x
][where_check
.y
] = scenario
.ter_types
[ter
].flag1
;
1120 combat_terrain
[where_check
.x
][where_check
.y
] = scenario
.ter_types
[ter
].flag1
;
1122 if (point_onscreen(center
,where_check
))
1123 play_sound(scenario
.ter_types
[ter
].flag2
);
1127 case 20: case 21: case 15:
1132 if (c_town
.monst
.dudes
[which_monst
].m_d
.immunities
& 8)
1138 // Action may change terrain, so update what's been seen
1139 if (do_look
== TRUE
) {
1141 update_explored(c_town
.p_loc
);
1143 for (i
= 0; i
< 6; i
++)
1144 if (adven
[i
].main_status
== 1)
1145 update_explored(pc_pos
[i
]);
1151 void forced_place_monster(unsigned char which
,location where
)
1153 Boolean free_spot
= FALSE
;
1156 while ((free_spot
== FALSE
) && (i
< T_M
)) {
1157 if (c_town
.monst
.dudes
[i
].active
== 0)
1162 r1
= get_ran(1,0,59);
1163 while ((c_town
.monst
.dudes
[r1
].monst_start
.spec1
!= 0) || (c_town
.monst
.dudes
[r1
].monst_start
.spec2
!= 0));
1164 if (free_spot
== FALSE
)
1165 c_town
.monst
.dudes
[r1
].active
= 0;
1166 place_monster(which
,where
);
1169 void magic_adjust(creature_data_type
*which_m
,short *how_much
)
1171 if (which_m
->m_d
.spec_skill
== 26) {
1173 which_m
->m_d
.health
+= 3;
1175 if (which_m
->m_d
.immunities
& 1)
1176 *how_much
= *how_much
/ 2;
1177 if (which_m
->m_d
.immunities
& 2)
1178 *how_much
= 0; /* crash!! */
1181 void poison_monst(creature_data_type
*which_m
,short how_much
)
1183 if (which_m
->m_d
.immunities
& 64)
1184 how_much
= how_much
/ 2;
1185 if (which_m
->m_d
.immunities
& 128) {
1186 monst_spell_note(which_m
->number
,10);
1189 which_m
->m_d
.status
[2] = min(8, which_m
->m_d
.status
[2] + how_much
);
1190 monst_spell_note(which_m
->number
,(how_much
== 0) ? 10 : 4);
1193 void acid_monst(creature_data_type
*which_m
,short how_much
)
1198 magic_adjust(which_m
,&i
);
1200 which_m
->m_d
.status
[13] = minmax(-8,8, which_m
->m_d
.status
[13] + how_much
);
1201 monst_spell_note(which_m
->number
,31);
1205 void slow_monst(creature_data_type
*which_m
,short how_much
)
1210 magic_adjust(which_m
,&i
);
1212 which_m
->m_d
.status
[3] = minmax(-8,8, which_m
->m_d
.status
[3] - how_much
);
1213 monst_spell_note(which_m
->number
,(how_much
== 0) ? 10 : 2);
1216 void curse_monst(creature_data_type
*which_m
,short how_much
)
1221 magic_adjust(which_m
,&i
);
1225 which_m
->m_d
.status
[1] = minmax(-8,8, which_m
->m_d
.status
[1] - how_much
);
1226 monst_spell_note(which_m
->number
,(how_much
== 0) ? 10 : 5);
1229 void web_monst(creature_data_type
*which_m
,short how_much
)
1234 magic_adjust(which_m
,&i
);
1236 which_m
->m_d
.status
[6] = minmax(-8,8, which_m
->m_d
.status
[6] + how_much
);
1237 monst_spell_note(which_m
->number
,(how_much
== 0) ? 10 : 19);
1240 void scare_monst(creature_data_type
*which_m
,short how_much
)
1245 magic_adjust(which_m
,&i
);
1247 which_m
->m_d
.morale
= which_m
->m_d
.morale
- how_much
;
1248 monst_spell_note(which_m
->number
,(how_much
== 0) ? 10 : 1);
1251 void disease_monst(creature_data_type
*which_m
,short how_much
)
1256 magic_adjust(which_m
,&i
);
1258 which_m
->m_d
.status
[7] = minmax(-8,8, which_m
->m_d
.status
[7] + how_much
);
1259 monst_spell_note(which_m
->number
,(how_much
== 0) ? 10 : 25);
1263 void dumbfound_monst(creature_data_type
*which_m
,short how_much
)
1268 magic_adjust(which_m
,&i
);
1270 which_m
->m_d
.status
[9] = minmax(-8,8, which_m
->m_d
.status
[9] + how_much
);
1271 monst_spell_note(which_m
->number
,(how_much
== 0) ? 10 : 22);
1275 void charm_monst(creature_data_type
*which_m
,short penalty
,short which_status
,short amount
)
1276 // Also used for sleep and paralyze, which_statys is 0 means charm
1280 if ((which_status
== 11) && (which_m
->number
>= 138) && (which_m
->number
<= 142))
1282 if ((which_status
== 11) && (which_m
->m_d
.m_type
== 8))
1284 r1
= get_ran(1,0,100);
1285 if (which_m
->m_d
.immunities
& 1)
1287 if (which_m
->m_d
.immunities
& 2)
1290 if (which_status
== 11)
1292 if (which_status
== 12)
1294 if ((which_status
== 11) && (which_m
->m_d
.spec_skill
== 32))
1297 if (r1
> charm_odds
[which_m
->m_d
.level
/ 2]) {
1299 monst_spell_note(which_m
->number
,10);
1302 if (which_status
== 0) {
1303 which_m
->attitude
= 2;
1304 monst_spell_note(which_m
->number
,23);
1307 which_m
->m_d
.status
[which_status
] = amount
;
1308 if (which_status
== 11)
1309 monst_spell_note(which_m
->number
,28);
1310 if (which_status
== 12)
1311 monst_spell_note(which_m
->number
,30);
1316 void record_monst(creature_data_type
*which_m
)
1321 r1
= get_ran(1,0,100);
1324 if ((which_m
->m_d
.x_width
> 1) || (which_m
->m_d
.y_width
> 1)) {
1325 ASB("Capture Soul: Monster is too big.");
1327 else if ((r1
> charm_odds
[which_m
->m_d
.level
/ 2]) || (which_m
->m_d
.spec_skill
== 12)
1328 || (which_m
->m_d
.m_type
== 3)) {
1329 monst_spell_note(which_m
->number
,10);
1333 monst_spell_note(which_m
->number
,24);
1334 r1
= get_ran(1,0,3);
1335 if (party
.imprisoned_monst
[r1
] == 0)
1336 party
.imprisoned_monst
[r1
] = which_m
->number
;
1338 r1
= get_ran(1,0,3);
1339 party
.imprisoned_monst
[r1
] = which_m
->number
;
1341 ASB("Capture Soul: Success!");
1342 sprintf((char *)str
," Caught in slot %d.",r1
+ 1);
1343 add_string_to_buf((char *)str
);
1347 // returns 90 is no placement, OW returns # of spot
1348 short place_monster(unsigned char which
,location where
)
1352 while ((i
< T_M
) && ((c_town
.monst
.dudes
[i
].active
!= 0) ||
1353 (c_town
.monst
.dudes
[i
].monst_start
.spec_enc_code
> 0))) {
1358 c_town
.monst
.dudes
[i
].m_d
= return_monster_template((unsigned char) which
);
1359 c_town
.monst
.dudes
[i
].attitude
= scenario
.scen_monsters
[which
].default_attitude
;
1360 if (c_town
.monst
.dudes
[i
].attitude
% 2 == 0)
1361 c_town
.monst
.dudes
[i
].attitude
= 1;
1362 c_town
.monst
.dudes
[i
].mobile
= TRUE
;
1363 c_town
.monst
.dudes
[i
].active
= 2;
1364 c_town
.monst
.dudes
[i
].number
= which
;
1365 c_town
.monst
.dudes
[i
].m_loc
= where
;
1366 c_town
.monst
.dudes
[i
].summoned
= 0;
1367 c_town
.monst
.dudes
[i
].monst_start
= null_start_type
;
1368 monst_target
[i
] = 6;
1370 if (c_town
.monst
.dudes
[i
].m_d
.picture_num
< 1000) {
1371 add_monst_graphic(which
,1);
1374 take_crate(where
.x
,where
.y
);
1375 take_barrel(where
.x
,where
.y
);
1382 // returns TRUE if placement was successful
1383 Boolean
summon_monster(unsigned char which
,location where
,short duration
,short given_attitude
)
1384 //which; // if in town, this is caster loc., if in combat, this is where to try
1390 if ((is_town()) || (monsters_going
)) {
1391 // Ooooh ... mondo kludge. Need to find caster's attitude to give it to monst.
1392 which_m
= monst_there(where
);
1393 // if (pc_there(where) < 6)
1395 // else if (which_m == 90)
1397 // else which_att = c_town.monst.dudes[which_m].attitude;
1398 loc
= find_clear_spot(where
,0);
1403 // pc may be summoning using item, in which case where will be pc's space, so fix
1404 if (pc_there(where
) < 6) {
1405 where
= find_clear_spot(where
,0);
1409 if ((is_barrel(where
.x
,where
.y
)) || (is_crate(where
.x
,where
.y
)))
1414 spot
= place_monster(which
,loc
);
1417 add_string_to_buf(" Too many monsters.");
1418 //ASB(" Monster fails to summon monster.");
1423 // if (duration < 100)
1424 c_town
.monst
.dudes
[spot
].attitude
= given_attitude
;
1425 // else c_town.monst.dudes[spot].attitude = which_att;
1427 if (which
> 0) {//monster here for good
1428 c_town
.monst
.dudes
[spot
].summoned
= duration
;
1429 monst_spell_note(which
,21);
1431 else c_town
.monst
.dudes
[spot
].summoned
= 0;
1436 void activate_monsters(short code
,short attitude
)
1439 unsigned char which
;
1443 for (i
= 0; i
< T_M
; i
++)
1444 if (c_town
.monst
.dudes
[i
].monst_start
.spec_enc_code
== code
)
1446 c_town
.monst
.dudes
[i
].monst_start
.spec_enc_code
= 0;
1447 c_town
.monst
.dudes
[i
].active
= 2;
1448 which
= c_town
.monst
.dudes
[i
].number
;
1449 c_town
.monst
.dudes
[i
].attitude
= t_d
.creatures
[i
].start_attitude
;
1451 c_town
.monst
.dudes
[i
].summoned
= 0;
1452 c_town
.monst
.dudes
[i
].m_loc
= t_d
.creatures
[i
].start_loc
;
1453 c_town
.monst
.dudes
[i
].m_d
= return_monster_template(c_town
.monst
.dudes
[i
].number
);
1454 monst_target
[i
] = 6;
1456 add_monst_graphic(c_town
.monst
.dudes
[i
].number
,1);
1457 take_crate(c_town
.monst
.dudes
[i
].m_loc
.x
,c_town
.monst
.dudes
[i
].m_loc
.y
);
1458 take_barrel(c_town
.monst
.dudes
[i
].m_loc
.x
,c_town
.monst
.dudes
[i
].m_loc
.y
);
1462 short get_encumberance(short pc_num
)
1464 short store
= 0,i
,what_val
;
1466 for (i
= 0; i
< 16; i
++)
1467 if (adven
[pc_num
].equip
[i
] == TRUE
) {
1468 what_val
= adven
[pc_num
].items
[i
].awkward
;
1469 if ((what_val
== 1) && (get_ran(1,0,130) < hit_chance
[adven
[pc_num
].skills
[8]]))
1471 if ((what_val
> 1) && (get_ran(1,0,70) < hit_chance
[adven
[pc_num
].skills
[8]]))
1478 short get_summon_monster(short summon_class
)
1482 for (i
= 0; i
< 200; i
++) {
1483 j
= get_ran(1,0,255);
1484 if (scenario
.scen_monsters
[j
].summon_type
== summon_class
) {
1488 ASB(" Summon failed.");