19 extern party_record_type far party
;
20 extern piles_of_stuff_dumping_type
*data_store
;
21 extern piles_of_stuff_dumping_type2
*data_store2
;
22 extern talking_record_type far talking
;
23 extern scenario_data_type far scenario
;
25 extern pc_record_type far adven
[6];
26 extern current_town_type far c_town
;
27 extern big_tr_type far t_d
;
28 extern town_item_list far t_i
;
29 extern short overall_mode
,store_item_spell_level
;
30 extern short which_combat_type
;
31 extern short stat_window
;
32 extern location center
;
33 extern unsigned char far combat_terrain
[64][64];
34 extern location pc_pos
[6];
35 extern short current_pc
;
36 extern short pc_last_cast
[2][6];
37 extern short combat_active_pc
;
38 extern Boolean monsters_going
,spell_forced
,in_scen_debug
;
40 extern short store_mage
, store_priest
;
41 extern short store_mage_lev
, store_priest_lev
;
42 extern short store_spell_target
,pc_casting
,current_spell_range
;
43 extern effect_pat_type current_pat
;
44 extern short town_size
[3];
45 extern short town_type
;
46 extern short monst_target
[T_M
]; // 0-5 target that pc 6 - no target 100 + x - target monster x
47 extern short num_targets_left
;
48 extern location spell_targets
[8];
49 extern Boolean web
,crate
,barrel
,fire_barrier
,force_barrier
,quickfire
,force_wall
,fire_wall
,antimagic
,scloud
,ice_wall
,blade_wall
;
50 extern Boolean sleep_field
;
51 extern Boolean fast_bang
;
52 extern unsigned char far misc_i
[64][64],sfx
[64][64];
53 extern short store_current_pc
;
54 extern short refer_mage
[62],refer_priest
[62];
55 extern location monster_targs
[T_M
];
56 extern short combat_posing_monster
, current_working_monster
; // 0-5 PC 100 + x - monster x
58 extern short spell_caster
, missile_firer
,current_monst_tactic
;
60 short spell_being_cast
;
61 short missile_inv_slot
, ammo_inv_slot
;
62 short force_wall_position
= 10; // 10 -> no force wall
63 Boolean processing_fields
= TRUE
;
65 unsigned char store_sum_monst
;
66 short store_sum_monst_cost
;
69 location out_start_loc
= {20,23};
70 short far hit_chance
[51] = {20,30,40,45,50,55,60,65,69,73,
71 77,81,84,87,90,92,94,96,97,98,99
72 ,99,99,99,99,99,99,99,99,99,99
73 ,99,99,99,99,99,99,99,99,99,99,
74 99,99,99,99,99,99,99,99,99,99};
75 short far abil_range
[40] = {0,6,8,8,10, 10,10,8,6,8, 6,0,0,0,6, 0,0,0,0,4, 10,0,0,0,0,
76 0,0,0,0,0, 0,0,8,6,9, 0,0,0,0,0};
77 short far abil_odds
[40] = {0,5,7,6,6, 5,5,6,6,6, 6,0,0,0,4, 0,0,0,0,4, 8,0,0,0,0,
78 0,0,0,0,0, 0,0,7,5,6, 0,0,0,0,0};
81 //short s_cost[2][62] = {{1,1,1,1,1,2,15,2,1,3, 2,2,2,2,2,2,4,6,2,2, 3,3,4,3,3,5,5,4,6,4,/
82 // 4,4,4,4,30,-1,8,5, 5,8,7,5,8,10,5,7, 6,6,7,7,12,10,-1,20, 12,8,20,8,14,10,50,10},
83 // {1,1,1,2,1,2,2,5,50,1, 2,2,2,2,2,6,8,7,4,3, 3,4,3,3,3,10,6,3,3,7,
84 // 4,5,5,15,8,6,4,4, 5,5,25,8,12,12,10,5, 7,6,6,8,14,20,7,6, 8,7,20,12,8,12,30,8}};
85 short far s_cost
[2][62] = {{1,1,1,1,1,2,50,2,1,3, 2,3,2,2,2,2,4,4,2,6, 3,3,5,3,3,5,6,4,6,4,
86 4,5,4,8,30,-1,8,6, 5,8,8,6,9,10,6,6, 7,6,8,7,12,10,12,20, 12,8,20,10,14,10,50,10},
87 {1,1,1,2,1,1,3,5,50,1, 2,2,2,2,3,5,8,6,4,2, 3,4,3,3,3,10,5,3,4,6,
88 5,5,5,15,6,5,5,8, 6,7,25,8,10,12,12,6, 8,7,8,8,14,17,8,7, 10,10,35,10,12,12,30,10}};
90 short far mage_range
[80] = {0,6,0,0,7,7,0,14,8,0, 6,8,7,10,0,8,3,8,10,6, 0,0,12,0,10,12,4,10,8,0,
91 8,12,12,0,10,4,8,8, 0,0,14,0,2,4,10,12, 8,12,6,8,5,8,4,0, 0,0,8,0,4,2,4,6
92 ,10,8,8,12,8,10,10,10, 10,10,10,10,10,10,10,10,10,10};
93 short far priest_range
[62] = {0,0,0,8,0,0,0,0,0,10, 0,0,10,0,6,4,0,6,6,8, 0,0,8,0,10,0,8,0,0,8,
94 0,10,8,0,6,0,0,0, 0,0,0,9,0,4,0,8, 0,0,10,0,4,8,0,8, 0,4,0,12,0,10,0,0};
95 short far monst_mage_spell
[55] = {1,1,1,1,1,1,2,2,2,2,
96 2,2,3,3,3,3,3,4,4,4,
97 4,4,4,5,5,5,5,5,4,4,
98 6,6,6,6,7,7,7,7,7,8,
99 8,8,8,8,9,9,9,10,10,10,
101 short far monst_cleric_spell
[55] = {1,1,1,1,1,1,1,1,2,2,
102 2,2,2,3,3,3,11,11,11,4,
103 4,4,4,5,5,5,11,11,6,6,
104 6,6,6,6,7,7,7,7,7,7,
105 8,8,8,8,8,7,7,7,7,7,
107 short monst_mage_cost
[27] = {1,1,1,1,2, 2,2,2,2,4, 2,4,4,3,4, 4,4,5,5,5, 5,6,6,6,7, 7,7};
108 short monst_mage_area_effect
[27] = {0,0,0,0,0, 0,0,0,1,0, 1,1,0,1,0, 0,0,0,1,0, 1,0,0,0,0, 0,0};
109 short monst_priest_cost
[26] = {1,1,1,1,2, 2,2,4,2,3, 3,3,4,4,4, 5,5,5,10,6, 6,10,8,8,8, 8};
110 short monst_priest_area_effect
[26] = {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,1,0,0, 0,0,0,0,0, 1};
112 extern short boom_gr
[8];
114 char *d_string
[] = {"North", "NorthEast", "East", "SouthEast", "South", "SouthWest", "West", "NorthWest"};
116 short pc_marked_damage
[6];
117 short monst_marked_damage
[T_M
];
119 location hor_vert_place
[14] = {{0,0},{-1,1},{1,1},{-2,2},{0,2},
120 {2,2},{0,1},{-1,2},{1,2},{-1,3},
121 {1,3},{0,3},{0,4},{0,5}};
122 location diag_place
[14] = {{0,0},{-1,0},{0,1},{-1,1},{-2,0},
123 {0,2},{-2,1},{-1,2},{-2,2},{-3,2},
124 {-2,3},{-3,3},{-4,3},{-3,4}};
126 unsigned char beasts
[5] = {82,115,78,99,78};
127 unsigned char m1
[20] = {38,40,58,60,72, 75,79,80,40,118, 174,40,58,60,72, 75,79,80,58,120};
128 unsigned char m2
[16] = {39,41,45,47,62, 63,73,74,88,100, 116,130,134,39,41,45};
129 unsigned char m3
[16] = {48,49,50,65,66, 67,73,74,76,84, 84,103,121,127,74, 129};
131 short far mage_caster_array
[7][18] = {{1,1,1,2,2, 2,1,3,4,4, 1,1,1,2,2, 2,3,4},
132 {5,5,5,6,7, 8,9,10,11,11, 2,2,2,5,7, 10,10,5},
133 {5,5,2,9,11, 12,12,12,14,13, 13,12,12,2,2, 2,2,2},
134 {15,15,16,17,17, 5,12,12,13,13, 17,17,16,17,16, 2,2,2},
135 {15,18,19,19,20, 20,21,21,16,17, 18,18,18,18,19, 19,19,20},
136 {23,23,22,22,21, 21,20,24,19,18, 18,18,18,18,18, 23,23,19},
137 {23,23,24,25,26, 27,19,22,19,18, 18,18,18,18,26, 24,24,23}};
138 short far mage_emer_spells
[7][4] = {{2,0,0,5},
145 short far priest_caster_array
[7][10] = {{1,1,1,1,3,3,3,4,4,4},
146 {5,5,6,6,7,7,8,8,8,9},
147 {9,6,6,8,11,12,12,5,5,12},
148 {12,12,13,13,14,9,9,14,14,15},
149 {19,18,13,19,15,18,18,19,16,18},
150 {22,18,16,19,18,18,21,22,23,23},
151 {26,26,25,24,26,22,24,22,26,25}};
152 short far priest_emer_spells
[7][4] = {{0,1,0,2},
159 effect_pat_type far null_pat
= {{{0,0,0,0,0,0,0,0,0},
167 {0,0,0,0,0,0,0,0,0}}};
168 effect_pat_type far single
= {{{0,0,0,0,0,0,0,0,0},
176 {0,0,0,0,0,0,0,0,0}}};
177 effect_pat_type far t
= {{{0,0,0,0,0,0,0,0,0},
185 {0,0,0,0,0,0,0,0,0}}};
186 effect_pat_type far small_square
= {{{0,0,0,0,0,0,0,0,0},
194 {0,0,0,0,0,0,0,0,0}}};
195 effect_pat_type far square
= {{{0,0,0,0,0,0,0,0,0},
203 {0,0,0,0,0,0,0,0,0}}};
204 effect_pat_type far open_square
= {{{0,0,0,0,0,0,0,0,0},
212 {0,0,0,0,0,0,0,0,0}}};
213 effect_pat_type far rad2
= {{{0,0,0,0,0,0,0,0,0},
221 {0,0,0,0,0,0,0,0,0}}};
222 effect_pat_type far rad3
= {{{0,0,0,0,0,0,0,0,0},
230 {0,0,0,0,0,0,0,0,0}}};
231 effect_pat_type far field
[8] = {{{{0,0,0,0,1,1,0,0,0},
239 {0,0,0,0,1,1,0,0,0}}},
241 {{{0,0,0,0,0,0,0,0,1},
249 {1,1,0,0,0,0,0,0,0}}},
251 {{{0,0,0,0,0,0,0,0,0},
259 {0,0,0,0,0,0,0,0,0}}},
261 {{{1,0,0,0,0,0,0,0,0},
269 {0,0,0,0,0,0,0,1,1}}},
271 {{{0,0,0,1,1,0,0,0,0},
279 {0,0,0,1,1,0,0,0,0}}},
281 {{{0,0,0,0,0,0,0,1,1},
289 {1,0,0,0,0,0,0,0,0}}},
291 {{{0,0,0,0,0,0,0,0,0},
299 {0,0,0,0,0,0,0,0,0}}},
301 {{{1,1,0,0,0,0,0,0,0},
309 {0,0,0,0,0,0,0,0,1}}}};
311 short last_attacked
[6],pc_dir
[6],pc_parry
[6],pc_moves
[6];
312 Boolean center_on_monst
;
318 void start_outdoor_combat(outdoor_creature_type encounter
,unsigned char in_which_terrain
,short num_walls
)
320 short i
,j
,r1
,r2
,how_many
,num_tries
= 0;
321 short low
[10] = {15,7,3,3,1,1,1,7,2,1};
322 short high
[10] = {30,10,5,5,3,2,1,10,4,1};
323 RECT town_rect
= {0,0,47,47};
326 for (i
= 0; i
< 7; i
++)
327 nums
[i
] = get_ran(1,low
[i
],high
[i
]);
328 for (i
= 0; i
< 3; i
++)
329 nums
[i
+ 7] = get_ran(1,low
[i
+ 7],high
[i
+ 7]);
330 notify_out_combat_began(encounter
.what_monst
,nums
);
334 which_combat_type
= 0;
338 // Basically, in outdoor combat, we create kind of a 48x48 town for
339 // the combat to take place in
340 for (i
= 0; i
< 48; i
++)
341 for (j
= 0; j
< 48; j
++) {
342 c_town
.explored
[i
][j
] = 0;
346 c_town
.town
.in_town_rect
= town_rect
;
348 create_out_combat_terrain((short) in_which_terrain
,num_walls
,0);////
350 for (i
= 0; i
< T_M
; i
++) {
351 c_town
.monst
.dudes
[i
].number
= 0;
352 c_town
.monst
.dudes
[i
].active
= 0;
354 for (i
= 0; i
< 7; i
++) {
356 if (encounter
.what_monst
.monst
[i
] != 0)
357 for (j
= 0; j
< how_many
; j
++)
358 set_up_monst(0,encounter
.what_monst
.monst
[i
]);
360 for (i
= 0; i
< 3; i
++) {
361 how_many
= nums
[i
+ 7];
362 if (encounter
.what_monst
.friendly
[i
] != 0)
363 for (j
= 0; j
< how_many
; j
++)
364 set_up_monst(1,encounter
.what_monst
.friendly
[i
]);
368 pc_pos
[0] = out_start_loc
;
369 update_explored(pc_pos
[0]);
370 if (get_blockage(combat_terrain
[pc_pos
[0].x
][pc_pos
[0].y
]) > 0)
371 combat_terrain
[pc_pos
[0].x
][pc_pos
[0].y
] = combat_terrain
[0][0];
372 for (i
= 1; i
< 6; i
++) {
373 pc_pos
[i
] = pc_pos
[0];
374 pc_pos
[i
].x
= pc_pos
[i
].x
+ hor_vert_place
[i
].x
;
375 pc_pos
[i
].y
= pc_pos
[i
].y
+ hor_vert_place
[i
].y
;
376 if (get_blockage(combat_terrain
[pc_pos
[i
].x
][pc_pos
[i
].y
]) > 0)
377 combat_terrain
[pc_pos
[i
].x
][pc_pos
[i
].y
] = combat_terrain
[0][0];
378 update_explored(pc_pos
[i
]);
380 for (j
= 0; j
< 6; j
++)
382 adven
[i
].status
[j
] = 0;
385 // place monsters, w. friendly monsts landing near PCs
386 for (i
= 0; i
< T_M
; i
++)
387 if (c_town
.monst
.dudes
[i
].active
> 0) {
390 c_town
.monst
.dudes
[i
].m_loc
.x
= get_ran(1,15,25);
391 c_town
.monst
.dudes
[i
].m_loc
.y
= get_ran(1,14,18);
392 if (c_town
.monst
.dudes
[i
].attitude
== 2)
393 c_town
.monst
.dudes
[i
].m_loc
.y
+= 9;
394 else if ((c_town
.monst
.dudes
[i
].m_d
.mu
> 0) || (c_town
.monst
.dudes
[i
].m_d
.cl
> 0))
395 c_town
.monst
.dudes
[i
].m_loc
.y
= c_town
.monst
.dudes
[i
].m_loc
.y
- 4;//max(12,c_town.monst.dudes[i].m_loc.y - 4);
397 while (((monst_can_be_there(c_town
.monst
.dudes
[i
].m_loc
,i
) == FALSE
) ||
398 (combat_terrain
[c_town
.monst
.dudes
[i
].m_loc
.x
][c_town
.monst
.dudes
[i
].m_loc
.y
] == 180) ||
399 (pc_there(c_town
.monst
.dudes
[i
].m_loc
) < 6)) &&
400 (num_tries
++ < 50)) {
401 c_town
.monst
.dudes
[i
].m_loc
.x
= get_ran(1,15,25);
402 c_town
.monst
.dudes
[i
].m_loc
.y
= get_ran(1,14,18);
403 if (c_town
.monst
.dudes
[i
].attitude
== 2)
404 c_town
.monst
.dudes
[i
].m_loc
.y
+= 9;
405 else if ((c_town
.monst
.dudes
[i
].m_d
.mu
> 0) || (c_town
.monst
.dudes
[i
].m_d
.cl
> 0))
406 c_town
.monst
.dudes
[i
].m_loc
.y
= c_town
.monst
.dudes
[i
].m_loc
.y
- 4;//max(12,c_town.monst.dudes[i].m_loc.y - 4);
408 if (get_blockage(combat_terrain
[c_town
.monst
.dudes
[i
].m_loc
.x
][c_town
.monst
.dudes
[i
].m_loc
.y
]) > 0)
409 combat_terrain
[c_town
.monst
.dudes
[i
].m_loc
.x
][c_town
.monst
.dudes
[i
].m_loc
.y
] = combat_terrain
[0][0];
413 combat_active_pc
= 6;
414 spell_caster
= 6; missile_firer
= 6;
415 for (i
= 0; i
< T_M
; i
++)
418 for (i
= 0; i
< 6; i
++) {
420 last_attacked
[i
] = T_M
+ 10;
423 for (i
= 0; i
< NUM_TOWN_ITEMS
; i
++)
424 t_i
.items
[i
].variety
= 0;
425 store_current_pc
= current_pc
;
429 center
= pc_pos
[current_pc
];
430 load_area_graphics();
433 set_stat_window(current_pc
);
435 adjust_spell_menus();
442 Boolean
pc_combat_move(location destination
)
444 short dir
,monst_hit
,s1
,s2
,i
,monst_exist
,switch_pc
;
445 Boolean keep_going
= TRUE
,forced
= FALSE
,check_f
;
446 location monst_loc
,store_loc
;
449 if (monst_there(destination
) > T_M
)
450 keep_going
= check_special_terrain(destination
,2,current_pc
,&spec_num
,&check_f
);
457 if (keep_going
== TRUE
) {
459 dir
= set_direction(pc_pos
[current_pc
], destination
);
461 if ((loc_off_act_area(destination
) == TRUE
) && (which_combat_type
== 1)) {
462 add_string_to_buf("Move: Can't leave town during combat.");
466 else if ((combat_terrain
[destination
.x
][destination
.y
] == 90) && (which_combat_type
== 0)) {
467 if (get_ran(1,1,10) < 3) {
468 adven
[current_pc
].main_status
= 5;
469 if (combat_active_pc
== current_pc
)
470 combat_active_pc
= 6;
471 sprintf ((char *) create_line
, "Moved: Fled. ");
472 pc_moves
[current_pc
] = 0;
476 sprintf ((char *) create_line
, "Moved: Couldn't flee. ");
478 add_string_to_buf((char *) create_line
);
481 else if ((monst_hit
= monst_there(destination
)) <= T_M
) {
482 s1
= c_town
.monst
.dudes
[monst_hit
].attitude
;
483 s2
= (s1
% 2 == 1) ? 2 : fancy_choice_dialog(1045,0);
484 if ((s2
== 2) && (s1
% 2 != 1))
487 last_attacked
[current_pc
] = monst_hit
;
488 pc_attack(current_pc
,monst_hit
);
492 else if ((switch_pc
= pc_there(destination
)) < 6) {
493 if (pc_moves
[switch_pc
] == 0) {
494 add_string_to_buf("Move: Can't switch places.");
495 add_string_to_buf(" (other PC has no APs) ");
498 else pc_moves
[switch_pc
]--;
499 add_string_to_buf("Move: Switch places.");
500 store_loc
= pc_pos
[current_pc
];
501 pc_pos
[current_pc
] = destination
;
502 pc_pos
[switch_pc
] = store_loc
;
503 adven
[current_pc
].direction
= dir
;
505 check_special_terrain(store_loc
,2,switch_pc
,&spec_num
,&check_f
);
506 move_sound(combat_terrain
[destination
.x
][destination
.y
],pc_moves
[current_pc
]);
509 else if ((forced
== TRUE
)
510 || ((impassable(combat_terrain
[destination
.x
][destination
.y
]) == FALSE
) && (pc_there(destination
) == 6))) {
512 // monsters get back-shots
513 for (i
= 0; i
< T_M
; i
++) {
514 monst_loc
= c_town
.monst
.dudes
[i
].m_loc
;
515 monst_exist
= c_town
.monst
.dudes
[i
].active
;
518 if ((monst_exist
> 0) && (monst_adjacent(pc_pos
[current_pc
],i
) == TRUE
)
519 && (monst_adjacent(destination
,i
) == FALSE
) &&
520 (c_town
.monst
.dudes
[i
].attitude
% 2 == 1) &&
521 (c_town
.monst
.dudes
[i
].m_d
.status
[11] <= 0) &&
522 (c_town
.monst
.dudes
[i
].m_d
.status
[12] <= 0)) {
523 combat_posing_monster
= current_working_monster
= 100 + i
;
524 monster_attack_pc(i
,current_pc
);
525 combat_posing_monster
= current_working_monster
= -1;
528 if (s1
!= current_pc
)
532 // move if still alive
533 if (adven
[current_pc
].main_status
== 1) {
534 pc_dir
[current_pc
] = set_direction(pc_pos
[current_pc
],destination
);
535 pc_pos
[current_pc
] = destination
;
536 adven
[current_pc
].direction
= dir
;
538 //sprintf ((char *) create_line, "Moved: %s ",d_string[dir]);
539 //add_string_to_buf((char *) create_line);
540 move_sound(combat_terrain
[destination
.x
][destination
.y
],pc_moves
[current_pc
]);
547 sprintf ((char *) create_line
, "Blocked: %s ",d_string
[dir
]);
548 add_string_to_buf((char *) create_line
);
557 pc_parry
[current_pc
] = (pc_moves
[current_pc
] / 4) *
558 (2 + stat_adj(current_pc
,1) + adven
[current_pc
].skills
[8]);
559 pc_moves
[current_pc
] = 0;
562 void char_stand_ready()
564 pc_parry
[current_pc
] = 100;
565 pc_moves
[current_pc
] = 0;
568 void pc_attack(short who_att
,short target
)
570 short r1
,r2
,what_skill1
= 1, what_skill2
= 1, weap1
= 24, weap2
= 24,i
,store_hp
,skill_item
;
572 creature_data_type
*which_m
;
573 short hit_adj
, dam_adj
, spec_dam
= 0,poison_amt
;
575 // slice out bad attacks
576 if (adven
[who_att
].main_status
!= 1)
578 if ((adven
[who_att
].status
[11] > 0) || (adven
[who_att
].status
[12] > 0))
581 last_attacked
[who_att
] = target
;
582 which_m
= &c_town
.monst
.dudes
[target
];
584 for (i
= 0; i
< 24; i
++)
585 if (((adven
[who_att
].items
[i
].variety
== 1) || (adven
[who_att
].items
[i
].variety
== 2)) &&
586 (adven
[who_att
].equip
[i
] == TRUE
))
591 hit_adj
= (-5 * minmax(-8,8,adven
[who_att
].status
[1])) + 5 * minmax(-8,8,which_m
->m_d
.status
[1])
592 - stat_adj(who_att
,1) * 5 + (get_encumberance(who_att
)) * 5;
594 dam_adj
= minmax(-8,8,adven
[who_att
].status
[1]) - minmax(-8,8,which_m
->m_d
.status
[1])
595 + stat_adj(who_att
,0);
597 if ((which_m
->m_d
.status
[11] > 0) || (which_m
->m_d
.status
[12] > 0)) {
603 if ((skill_item
= text_pc_has_abil_equip(who_att
,37)) < 24) {
604 hit_adj
+= 5 * (adven
[who_att
].items
[skill_item
].item_level
/ 2 + 1);
605 dam_adj
+= adven
[who_att
].items
[skill_item
].item_level
/ 2;
607 if ((skill_item
= text_pc_has_abil_equip(who_att
,43)) < 24) {
608 dam_adj
+= adven
[who_att
].items
[skill_item
].item_level
;
609 hit_adj
+= adven
[who_att
].items
[skill_item
].item_level
* 2;
612 void_sanctuary(who_att
);
614 store_hp
= c_town
.monst
.dudes
[target
].m_d
.health
;
616 combat_posing_monster
= current_working_monster
= who_att
;
620 sprintf ((char *) create_line
, "%s punches. ",(char *) adven
[who_att
].name
);//,hit_adj, dam_adj);
621 add_string_to_buf((char *) create_line
);
623 r1
= get_ran(1,0,100) + hit_adj
- 20;
624 r1
+= 5 * (adven
[current_pc
].status
[6] / 3);
625 r2
= get_ran(1,1,4) + dam_adj
;
627 if (r1
<= hit_chance
[adven
[who_att
].skills
[what_skill1
]]) {
628 damage_monst(target
, who_att
, r2
, 0,400);
632 sprintf ((char *) create_line
, "%s misses. ",(char *) adven
[who_att
].name
);
633 add_string_to_buf((char *) create_line
);
638 // Don't forget awkward and stat adj.
640 what_skill1
= 2 + adven
[who_att
].items
[weap1
].type
;
643 if (what_skill1
== 2)
646 sprintf ((char *) create_line
, "%s swings. ",(char *) adven
[who_att
].name
);//,hit_adj, dam_adj);
647 add_string_to_buf((char *) create_line
);
649 r1
= get_ran(1,0,100) - 5 + hit_adj
650 - 5 * adven
[who_att
].items
[weap1
].bonus
;
651 r1
+= 5 * (adven
[current_pc
].status
[6] / 3);
653 if ((weap2
< 24) && (adven
[who_att
].traits
[2] == FALSE
))
657 if ((adven
[who_att
].race
== 2) && (adven
[who_att
].items
[weap1
].type
== 3))
660 r2
= get_ran(1,1,adven
[who_att
].items
[weap1
].item_level
) + dam_adj
+ 2 + adven
[who_att
].items
[weap1
].bonus
;
661 if (adven
[who_att
].items
[weap1
].ability
== 12)
662 r2
= (r2
* (10 - adven
[who_att
].items
[weap1
].ability_strength
)) / 10;
664 if (r1
<= hit_chance
[adven
[who_att
].skills
[what_skill1
]]) {
665 spec_dam
= calc_spec_dam(adven
[who_att
].items
[weap1
].ability
,
666 adven
[who_att
].items
[weap1
].ability_strength
,which_m
);
669 r1
= get_ran(1,0,100);
670 if ((adven
[who_att
].level
>= which_m
->m_d
.level
- 1)
671 && (adven
[who_att
].skills
[16] >= which_m
->m_d
.level
/ 2)
672 && (which_m
->m_d
.spec_skill
!= 12)) // Can't assassinate splitters
673 if (r1
< hit_chance
[max(adven
[who_att
].skills
[16] - which_m
->m_d
.level
,0)]) {
674 add_string_to_buf(" You assassinate. ");
678 switch (what_skill1
) {
680 if (adven
[who_att
].items
[weap1
].item_level
< 8)
681 damage_monst(target
, who_att
, r2
, spec_dam
, 100);
682 else damage_monst(target
, who_att
, r2
, spec_dam
, 200);
685 damage_monst(target
, who_att
, r2
, spec_dam
, 400);
688 damage_monst(target
, who_att
, r2
, spec_dam
, 300);
692 if ((adven
[who_att
].status
[0] > 0) && (adven
[who_att
].weap_poisoned
== weap1
)) {
693 poison_amt
= adven
[who_att
].status
[0];
694 if (pc_has_abil_equip(who_att
,51) < 24)
696 poison_monst(which_m
,poison_amt
);
697 adven
[who_att
].status
[0] = move_to_zero(adven
[who_att
].status
[0]);
699 if ((adven
[who_att
].items
[weap1
].ability
== 14) && (get_ran(1,0,1) == 1)) {
700 add_string_to_buf(" Blade drips venom. ");
701 poison_monst(which_m
,adven
[who_att
].items
[weap1
].ability_strength
/ 2);
703 if ((adven
[who_att
].items
[weap1
].ability
== 9) && (get_ran(1,0,1) == 1)) {
704 add_string_to_buf(" Blade drips acid. ");
705 acid_monst(which_m
,adven
[who_att
].items
[weap1
].ability_strength
/ 2);
707 if ((adven
[who_att
].items
[weap1
].ability
== 10) && (get_ran(1,0,1) == 1)) {
708 add_string_to_buf(" Blade drains life. ");
709 heal_pc(who_att
,adven
[who_att
].items
[weap1
].ability_strength
/ 2);
714 sprintf ((char *) create_line
, " %s misses. ",(char *) adven
[who_att
].name
);
715 add_string_to_buf((char *) create_line
);
716 if (what_skill1
== 5)
721 if ((weap2
< 24) && (which_m
->active
> 0)) {
722 what_skill2
= 2 + adven
[who_att
].items
[weap2
].type
;
725 if (what_skill2
== 2)
729 sprintf ((char *) create_line
, "%s swings. ",(char *) adven
[who_att
].name
);//,hit_adj, dam_adj);
730 add_string_to_buf((char *) create_line
);
731 r1
= get_ran(1,0,100) + hit_adj
- 5 * adven
[who_att
].items
[weap2
].bonus
;
734 if (adven
[who_att
].traits
[2] == FALSE
)
737 r1
+= 5 * (adven
[current_pc
].status
[6] / 3);
738 r2
= get_ran(1,1,adven
[who_att
].items
[weap2
].item_level
) + dam_adj
- 1 + adven
[who_att
].items
[weap2
].bonus
;
739 if (adven
[who_att
].items
[weap2
].ability
== 12)
740 r2
= (r2
* (10 - adven
[who_att
].items
[weap2
].ability_strength
)) / 10;
742 if (r1
<= hit_chance
[adven
[who_att
].skills
[what_skill2
]]) {
743 spec_dam
= calc_spec_dam(adven
[who_att
].items
[weap2
].ability
,
744 adven
[who_att
].items
[weap2
].ability_strength
,which_m
);
745 switch (what_skill2
) {
747 if (adven
[who_att
].items
[weap1
].item_level
< 8)
748 damage_monst(target
, who_att
, r2
, spec_dam
, 100);
749 else damage_monst(target
, who_att
, r2
, spec_dam
, 200);
752 damage_monst(target
, who_att
, r2
, spec_dam
, 400);
755 damage_monst(target
, who_att
, r2
, spec_dam
, 300);
759 if ((adven
[who_att
].items
[weap2
].ability
== 14) && (get_ran(1,0,1) == 1)) {
760 add_string_to_buf(" Blade drips venom. ");
761 poison_monst(which_m
,adven
[who_att
].items
[weap2
].ability_strength
/ 2);
763 if ((adven
[who_att
].items
[weap2
].ability
== 9) && (get_ran(1,0,1) == 1)) {
764 add_string_to_buf(" Blade drips acid. ");
765 acid_monst(which_m
,adven
[who_att
].items
[weap2
].ability_strength
/ 2);
767 if ((adven
[who_att
].items
[weap2
].ability
== 10) && (get_ran(1,0,1) == 1)) {
768 add_string_to_buf(" Blade drains life. ");
769 heal_pc(who_att
,adven
[who_att
].items
[weap2
].ability_strength
/ 2);
775 sprintf ((char *) create_line
, "%s misses. ",(char *) adven
[who_att
].name
);
776 add_string_to_buf((char *) create_line
);
777 if (what_skill2
== 5)
782 adven
[who_att
].status
[0] = move_to_zero(adven
[who_att
].status
[0]);
785 if (((c_town
.monst
.dudes
[target
].m_d
.status
[10] > 0) || (c_town
.monst
.dudes
[target
].m_d
.spec_skill
== 22))
786 && (store_hp
- c_town
.monst
.dudes
[target
].m_d
.health
> 0)) {
787 add_string_to_buf(" Shares damage! ");
788 damage_pc(who_att
, store_hp
- c_town
.monst
.dudes
[target
].m_d
.health
, 3,-1);
790 combat_posing_monster
= current_working_monster
= -1;
794 short calc_spec_dam(short abil
,short abil_str
,creature_data_type
*monst
) ////
800 store
+= get_ran(abil_str
,1,6);
803 if (monst
->m_d
.m_type
== 7)
804 store
+= 8 * abil_str
;
807 if (monst
->m_d
.m_type
== 7)
808 store
+= 25 + 8 * abil_str
;
811 if (monst
->m_d
.m_type
== 8)
812 store
+= 20 + 6 * abil_str
;
815 if (monst
->m_d
.m_type
== 8)
816 store
+= 6 * abil_str
;
819 if (monst
->m_d
.m_type
== 1)
820 store
+= 5 * abil_str
;
823 if (monst
->m_d
.m_type
== 9)
824 store
+= 8 * abil_str
;
827 if (monst
->m_d
.m_type
== 4)
828 store
+= 4 * abil_str
;
831 if (monst
->m_d
.m_type
== 5)
832 store
+= 4 * abil_str
;
835 if (monst
->m_d
.m_type
== 12)
836 store
+= 7 * abil_str
;
839 scare_monst(monst
,abil_str
* 10);
842 acid_monst(monst
,abil_str
);
848 void place_target(location target
)
852 if (num_targets_left
> 0) {
853 if (loc_off_act_area(target
) == TRUE
) {
854 add_string_to_buf(" Space not in town. ");
857 if (can_see(pc_pos
[current_pc
],target
,0) > 4) {
858 add_string_to_buf(" Can't see target. ");
861 if (dist(pc_pos
[current_pc
],target
) > ((spell_being_cast
>= 100) ? priest_range
[spell_being_cast
- 100] : mage_range
[spell_being_cast
])) {
862 add_string_to_buf(" Target out of range.");
865 if ((get_obscurity(target
.x
,target
.y
) == 5) && (spell_being_cast
!= 41)) {
866 add_string_to_buf(" Target space obstructed. ");
869 if (is_antimagic(target
.x
,target
.y
)) {
870 add_string_to_buf(" Target in antimagic field.");
873 for (i
= 0; i
< 8; i
++) {
874 if (same_point(spell_targets
[i
],target
) == TRUE
) {
875 add_string_to_buf(" Target removed.");
877 spell_targets
[i
].x
= 120;
882 for (i
= 0; i
< 8; i
++)
883 if (spell_targets
[i
].x
== 120) {
884 add_string_to_buf(" Target added.");
885 spell_targets
[i
] = target
;
892 if (num_targets_left
== 0) {
893 do_combat_cast(spell_targets
[0]);
901 // 64 - Ice Wall Balls
906 // 69 - Paralyze beam
908 void do_combat_cast(location target
)
910 short adjust
,r1
,r2
,targ_num
,which_mess
= 0,s_num
,level
,bonus
= 1,i
,item
,store_sound
= 0;
911 creature_data_type
*cur_monst
;
912 Boolean freebie
= FALSE
,ap_taken
= FALSE
,cost_taken
= FALSE
;
913 short num_targets
= 1,store_m_type
= 2;
914 short spray_type_array
[15] = {1,1,1,4,4,5,5,5,6,6,7,7,8,8,9};
915 unsigned char summon
;
917 location ashes_loc
= {0,0};
919 // to wedge in animations, have to kludge like crazy
920 short boom_dam
[8] = {0,0,0,0,0,0,0,0};
921 short boom_type
[8] = {0,0,0,0,0,0,0,0};
922 location boom_targ
[8];
924 if (spell_being_cast
>= 1000) {
925 spell_being_cast
-= 1000;
927 level
= store_item_spell_level
;
928 level
= minmax(2,20,level
);
931 level
= 1 + adven
[current_pc
].level
/ 2;
932 bonus
= stat_adj(current_pc
,2);
934 force_wall_position
= 10;
935 s_num
= spell_being_cast
% 100;
937 void_sanctuary(current_pc
);
938 if (overall_mode
== 11) {
939 spell_targets
[0] = target
;
945 spell_caster
= current_pc
;
947 // assign monster summoned, if summoning
948 if (spell_being_cast
== 16) {
949 summon
= get_summon_monster(1);
952 if (spell_being_cast
== 26) {
953 summon
= get_summon_monster(1);
955 if (spell_being_cast
== 43) {
956 summon
= get_summon_monster(2);
958 if (spell_being_cast
== 58) {
959 summon
= get_summon_monster(3);
961 combat_posing_monster
= current_working_monster
= current_pc
;
963 for (i
= 0; i
< num_targets
; i
++)
964 if (spell_targets
[i
].x
!= 120) {
965 target
= spell_targets
[i
];
966 spell_targets
[i
].x
= 120; // nullify target as it is used
968 if ((cost_taken
== FALSE
) && (freebie
== FALSE
) && (s_num
!= 52) && (s_num
!= 35)) {
969 adven
[current_pc
].cur_sp
-= s_cost
[spell_being_cast
/ 100][s_num
];
972 if ((cost_taken
== FALSE
) && (freebie
== FALSE
) && (s_num
== 35)) {
973 adven
[current_pc
].cur_sp
-= store_sum_monst_cost
;
977 if ((adjust
= can_see(pc_pos
[current_pc
],target
,0)) > 4) {
978 add_string_to_buf(" Can't see target. ");
980 else if (loc_off_act_area(target
) == TRUE
) {
981 add_string_to_buf(" Space not in town. ");
983 else if (dist(pc_pos
[current_pc
],target
) > ((spell_being_cast
>= 100) ? priest_range
[spell_being_cast
- 100] : mage_range
[spell_being_cast
]))
984 add_string_to_buf(" Target out of range.");
985 else if ((get_obscurity(target
.x
,target
.y
) == 5) && (spell_being_cast
!= 41))
986 add_string_to_buf(" Target space obstructed. ");
987 else if (is_antimagic(target
.x
,target
.y
))
988 add_string_to_buf(" Target in antimagic field.");
990 if (ap_taken
== FALSE
) {
991 if (freebie
== FALSE
)
996 boom_targ
[i
] = target
;
997 switch (spell_being_cast
) {
999 case 8: case 28: case 65: // web spells
1000 place_spell_pattern(current_pat
,target
,1,FALSE
,current_pc
);
1002 case 5: case 17: // fire wall spells
1003 place_spell_pattern(current_pat
,target
,5,FALSE
,current_pc
);
1005 case 15: case 66: // stink cloud
1006 place_spell_pattern(current_pat
,target
,7,FALSE
,current_pc
);
1008 case 25: case 44: case 126: // force walls
1009 place_spell_pattern(current_pat
,target
,4,FALSE
,current_pc
);
1011 case 37: case 64: // ice walls
1012 place_spell_pattern(current_pat
,target
,8,FALSE
,current_pc
);
1014 case 51: // antimagic
1015 place_spell_pattern(current_pat
,target
,6,FALSE
,current_pc
);
1017 case 19: case 67: // sleep clouds
1018 place_spell_pattern(current_pat
,target
,12,FALSE
,current_pc
);
1021 make_quickfire(target
.x
,target
.y
);
1023 case 45: // spray fields
1024 r1
= get_ran(1,0,14);
1025 place_spell_pattern(current_pat
,target
,spray_type_array
[r1
],FALSE
,current_pc
);
1027 case 159: // wall of blades
1028 place_spell_pattern(current_pat
,target
,9,FALSE
,current_pc
);
1030 case 145: case 119: case 18: // wall dispelling
1031 place_spell_pattern(current_pat
,target
,11,FALSE
,current_pc
);
1033 case 42: // Fire barrier
1035 r1
= get_ran(3,2,7);
1036 hit_space(target
,r1
,1,TRUE
,TRUE
);
1037 make_fire_barrier(target
.x
,target
.y
);
1038 if (is_fire_barrier(target
.x
,target
.y
))
1039 add_string_to_buf(" You create the barrier. ");
1040 else add_string_to_buf(" Failed.");
1042 case 59: // Force barrier
1044 r1
= get_ran(7,2,7);
1045 hit_space(target
,r1
,1,TRUE
,TRUE
);
1046 make_force_barrier(target
.x
,target
.y
);
1047 if (is_force_barrier(target
.x
,target
.y
))
1048 add_string_to_buf(" You create the barrier. ");
1049 else add_string_to_buf(" Failed.");
1052 default: // spells which involve animations
1053 start_missile_anim();
1054 switch (spell_being_cast
) {
1057 add_missile(target
,9,1,0,0);
1059 r1
= min(18,(level
* 7) / 10 + 2 * bonus
);
1060 place_spell_pattern(rad2
,target
,130 + r1
,TRUE
,current_pc
);
1065 r1
= (spell_being_cast
== 1) ? get_ran(2,1,4) : get_ran(min(20,level
+ bonus
),1,4);
1066 add_missile(target
,6,1,0,0);
1067 do_missile_anim(100,pc_pos
[current_pc
],11);
1068 hit_space(target
,r1
,(spell_being_cast
== 1) ? 3 : 5,1,0);
1070 case 27: // flame arrows
1071 add_missile(target
,4,1,0,0);
1072 r1
= get_ran(2,1,4);
1075 //hit_space(target,r1,1,1,0);
1078 add_missile(target
,6,1,0,0);
1079 r1
= get_ran(2,1,5);
1082 //hit_space(target,r1,5,1,0);
1085 r1
= get_ran(min(7,2 + bonus
+ level
/ 2),1,4);
1086 add_missile(target
,14,1,0,0);
1087 do_missile_anim(100,pc_pos
[current_pc
],24);
1088 hit_space(target
,r1
,4,1,0);
1091 r1
= get_ran(min(10,1 + level
/ 3 + bonus
),1,6);
1092 add_missile(target
,2,1,0,0);
1093 do_missile_anim(100,pc_pos
[current_pc
],11);
1094 hit_space(target
,r1
,1,1,0);
1097 r1
= min(9,1 + (level
* 2) / 3 + bonus
) + 1;
1098 add_missile(target
,2,1,0,0);
1100 //do_missile_anim(100,pc_pos[current_pc],11);
1101 if (spell_being_cast
== 141)
1102 r1
= (r1
* 14) / 10;
1103 else if (r1
> 10) r1
= (r1
* 8) / 10;
1104 if (r1
<= 0) r1
= 1;
1105 place_spell_pattern(square
,target
,50 + r1
,TRUE
,current_pc
);
1109 add_missile(target
,2,1,0,0);
1111 //do_missile_anim(100,pc_pos[current_pc],11);
1112 r1
= min(12,1 + (level
* 2) / 3 + bonus
) + 2;
1115 place_spell_pattern(rad2
,target
,50 + r1
,TRUE
,current_pc
);
1119 add_missile(target
,9,1,0,0);
1120 do_missile_anim(100,pc_pos
[current_pc
],11);
1121 r1
= get_ran(3,0,10) + adven
[current_pc
].level
* 2;
1122 hit_space(target
,40 + r1
,3,1,0);
1124 case 61: // death arrows
1125 add_missile(target
,9,1,0,0);
1127 r1
= get_ran(3,0,10) + adven
[current_pc
].level
+ 3 * bonus
;
1130 //hit_space(target,40 + r1,3,1,0);
1133 case 35: case 16: case 26: case 43: case 58: case 50:
1134 case 63: case 115: case 134: case 143: case 150:
1135 add_missile(target
,8,1,0,0);
1136 do_missile_anim(50,pc_pos
[current_pc
],61);
1137 switch (spell_being_cast
) {
1138 case 35: // Simulacrum
1139 r2
= get_ran(3,1,4) + stat_adj(current_pc
,2);
1140 if (summon_monster(store_sum_monst
,target
,r2
,2) == FALSE
)
1141 add_string_to_buf(" Summon failed.");
1143 case 16: // summon beast
1144 r2
= get_ran(3,1,4) + stat_adj(current_pc
,2);
1145 if ((summon
< 0) || (summon_monster(summon
,target
,r2
,2) == FALSE
))
1146 add_string_to_buf(" Summon failed.");
1148 case 26: // summon 1
1149 r2
= get_ran(4,1,4) + stat_adj(current_pc
,2);
1150 if ((summon
< 0) || (summon_monster(summon
,target
,r2
,2) == FALSE
))
1151 add_string_to_buf(" Summon failed.");
1153 case 43: // summon 2
1154 r2
= get_ran(5,1,4) + stat_adj(current_pc
,2);
1155 if ((summon
< 0) || (summon_monster(summon
,target
,r2
,2) == FALSE
))
1156 add_string_to_buf(" Summon failed.");
1158 case 58: // summon 3
1159 r2
= get_ran(7,1,4) + stat_adj(current_pc
,2);
1160 if ((summon
< 0) || (summon_monster(summon
,target
,r2
,2) == FALSE
))
1161 add_string_to_buf(" Summon failed.");
1164 r2
= get_ran(5,1,4) + stat_adj(current_pc
,2);
1165 if (summon_monster(85,target
,r2
,2) == FALSE
)
1166 add_string_to_buf(" Summon failed.");
1169 r1
= get_ran(3,1,4);
1170 if (summon_monster(80,target
,r1
,2) == FALSE
)
1171 add_string_to_buf(" Summon failed.");
1174 case 115: // summon spirit
1175 r2
= get_ran(2,1,5) + stat_adj(current_pc
,2);
1176 if (summon_monster(125,target
,r2
,2) == FALSE
)
1177 add_string_to_buf(" Summon failed.");
1180 r1
= get_ran(1,0,7);
1181 r2
= get_ran(2,1,5) + stat_adj(current_pc
,2);
1182 if (summon_monster((r1
== 1) ? 100 : 99,target
,r2
,2) == FALSE
)
1183 add_string_to_buf(" Summon failed.");
1186 r2
= get_ran(2,1,4) + stat_adj(current_pc
,2);
1187 if (summon_monster((i
== 0) ? 126 : 125,target
,r2
,2) == FALSE
)
1188 add_string_to_buf(" Summon failed.");
1190 case 150: // guardian
1191 r2
= get_ran(6,1,4) + stat_adj(current_pc
,2);
1192 if (summon_monster(122,target
,r2
,2) == FALSE
)
1193 add_string_to_buf(" Summon failed.");
1200 targ_num
= monst_there(target
);
1202 add_string_to_buf(" Nobody there ");
1204 cur_monst
= &c_town
.monst
.dudes
[targ_num
];
1205 if ((cur_monst
->attitude
% 2 != 1) && (spell_being_cast
!= 7)
1206 && (spell_being_cast
!= 34))
1207 make_town_hostile();
1208 store_sound
= (spell_being_cast
>= 50) ? 24 : 25;
1209 switch (spell_being_cast
) {
1210 case 68: // spray acid
1212 acid_monst(cur_monst
,level
);
1214 case 69: // paralyze
1216 charm_monst(cur_monst
,0,12,500);
1219 case 7: // monster info
1222 party
.m_seen
[cur_monst
->number
] = TRUE
;
1223 adjust_monst_menu();
1224 display_monst(0,cur_monst
,0);
1226 case 34: // Capture soul
1228 record_monst(cur_monst
);
1231 case 52: // Mindduel!
1233 if ((cur_monst
->m_d
.mu
== 0) && (cur_monst
->m_d
.cl
== 0))
1234 add_string_to_buf(" Can't duel: no magic.");
1236 item
= pc_has_abil(current_pc
,159);
1238 add_string_to_buf(" You need a smoky crystal. ");
1240 remove_charge(current_pc
,item
);
1241 do_mindduel(current_pc
,cur_monst
);
1248 charm_monst(cur_monst
,-1 * (bonus
+ adven
[current_pc
].level
/ 8),0,0);
1251 case 118: // disease
1253 r1
= get_ran(1,0,1);
1254 disease_monst(cur_monst
,2 + r1
+ bonus
);
1259 cur_monst
->m_d
.health
+= 20;
1265 dumbfound_monst(cur_monst
,1 + bonus
/ 3);
1271 scare_monst(cur_monst
,get_ran(2 + bonus
,1,6));
1276 scare_monst(cur_monst
,get_ran(min(20,adven
[current_pc
].level
/ 2 + bonus
),1,
1277 ((spell_being_cast
== 24) ? 8 : 6)));
1283 r1
= get_ran(1,0,1);
1284 slow_monst(cur_monst
,2 + r1
+ bonus
);
1288 store_m_type
= (spell_being_cast
== 36) ? 4 : 11;
1289 poison_monst(cur_monst
,2 + bonus
/ 2);
1292 case 49: // Paralysis
1294 charm_monst(cur_monst
,-10,12,1000);
1298 poison_monst(cur_monst
,4 + bonus
/ 2);
1303 poison_monst(cur_monst
,8 + bonus
/ 2);
1307 case 109: // stumble
1309 curse_monst(cur_monst
,4 + bonus
);
1314 curse_monst(cur_monst
,2 + bonus
);
1319 curse_monst(cur_monst
,2 + adven
[current_pc
].level
/ 2);
1323 if (cur_monst
->m_d
.m_type
!= 8) {
1324 add_string_to_buf(" Not undead. ");
1329 r1
= get_ran(1,0,90);
1330 if (r1
> hit_chance
[minmax(0,19,bonus
* 2 + level
* 4 - (cur_monst
->m_d
.level
/ 2) + 3)])
1331 add_string_to_buf(" Monster resisted. ");
1333 r1
= get_ran((spell_being_cast
== 103) ? 2 : 6, 1, 14);
1335 hit_space(cur_monst
->m_loc
,r1
,4,0,current_pc
);
1340 if (cur_monst
->m_d
.m_type
!= 7) {
1341 add_string_to_buf(" Not a demon. ");
1345 r1
= get_ran(1,0,100);
1346 if (r1
> hit_chance
[minmax(0,19,level
* 4 - cur_monst
->m_d
.level
+ 10)])
1347 add_string_to_buf(" Demon resisted. ");
1349 r1
= get_ran(8 + bonus
* 2, 1, 11);
1350 if (PSD
[4][0] == 3) // anama
1353 hit_space(cur_monst
->m_loc
,r1
,4,0,current_pc
);
1357 if (store_m_type
>= 0)
1358 add_missile(target
,store_m_type
,1,
1359 14 * (cur_monst
->m_d
.x_width
- 1),18 * (cur_monst
->m_d
.y_width
- 1));
1368 do_missile_anim((num_targets
> 1) ? 35 : 60,pc_pos
[current_pc
],store_sound
);
1370 // process mass damage
1371 for (i
= 0; i
< 8; i
++)
1372 if (boom_dam
[i
] > 0)
1373 hit_space(boom_targ
[i
],boom_dam
[i
],boom_type
[i
],1,0);
1375 if (ashes_loc
.x
> 0)
1376 make_sfx(ashes_loc
.x
,ashes_loc
.y
,6);
1378 do_explosion_anim(5,0);
1382 handle_marked_damage();
1383 combat_posing_monster
= current_working_monster
= -1;
1388 void handle_marked_damage()
1392 for (i
= 0; i
< 6; i
++)
1393 if (pc_marked_damage
[i
] > 0)
1395 damage_pc(i
,pc_marked_damage
[i
],10,-1);
1396 pc_marked_damage
[i
] = 0;
1398 for (i
= 0; i
< T_M
; i
++)
1399 if (monst_marked_damage
[i
] > 0)
1401 damage_monst(i
, current_pc
, monst_marked_damage
[i
], 0, 9);
1403 monst_marked_damage
[i
] = 0;
1409 short i
,bow
= 24,arrow
= 24,thrown
= 24,crossbow
= 24,bolts
= 24,no_ammo
= 24,m_type
= 0;
1411 for (i
= 0; i
< 24; i
++) {
1412 if ((adven
[current_pc
].equip
[i
] == TRUE
) &&
1413 (adven
[current_pc
].items
[i
].variety
== 6))
1415 if ((adven
[current_pc
].equip
[i
] == TRUE
) &&
1416 (adven
[current_pc
].items
[i
].variety
== 4))
1418 if ((adven
[current_pc
].equip
[i
] == TRUE
) &&
1419 (adven
[current_pc
].items
[i
].variety
== 5))
1421 if ((adven
[current_pc
].equip
[i
] == TRUE
) &&
1422 (adven
[current_pc
].items
[i
].variety
== 23))
1424 if ((adven
[current_pc
].equip
[i
] == TRUE
) &&
1425 (adven
[current_pc
].items
[i
].variety
== 24))
1427 if ((adven
[current_pc
].equip
[i
] == TRUE
) &&
1428 (adven
[current_pc
].items
[i
].variety
== 25))
1433 ammo_inv_slot
= thrown
;
1434 add_string_to_buf("Throw: Select a target. ");
1435 add_string_to_buf(" (Hit 's' to cancel.)");
1437 current_spell_range
= 8;
1438 current_pat
= single
;
1440 else if (((bolts
< 24) && (bow
< 24)) || ((arrow
< 24) && (crossbow
< 24))) {
1441 add_string_to_buf("Fire: Wrong ammunition. ");
1443 else if ((arrow
== 24) && (bow
< 24)) {
1444 add_string_to_buf("Fire: Equip some arrows. ");
1446 else if ((arrow
< 24) && (bow
< 24)) {
1447 missile_inv_slot
= bow
;
1448 ammo_inv_slot
= arrow
;
1450 add_string_to_buf("Fire: Select a target. ");
1451 add_string_to_buf(" (Hit 's' to cancel.)");
1452 current_spell_range
= 12;
1453 current_pat
= single
;
1455 else if ((bolts
< 24) && (crossbow
< 24)) {
1456 missile_inv_slot
= crossbow
;
1457 ammo_inv_slot
= bolts
;
1459 add_string_to_buf("Fire: Select a target. ");
1460 add_string_to_buf(" (Hit 's' to cancel.)");
1461 current_spell_range
= 12;
1462 current_pat
= single
;
1464 else if (no_ammo
< 24) {
1465 missile_inv_slot
= no_ammo
;
1466 ammo_inv_slot
= no_ammo
;
1468 add_string_to_buf("Fire: Select a target. ");
1469 add_string_to_buf(" (Hit 's' to cancel.)");
1470 current_spell_range
= 12;
1471 current_pat
= single
;
1473 else add_string_to_buf("Fire: Equip a missile. ");
1476 void fire_missile(location target
)
1478 short r1
, r2
, skill
, dam
, dam_bonus
, hit_bonus
, range
, targ_monst
, spec_dam
= 0,poison_amt
= 0;
1479 short skill_item
,m_type
= 0;
1480 creature_data_type
*cur_monst
;
1481 Boolean exploding
= FALSE
;
1483 skill
= (overall_mode
== 12) ? adven
[current_pc
].skills
[7] : adven
[current_pc
].skills
[8];
1484 range
= (overall_mode
== 12) ? 12 : 8;
1485 dam
= adven
[current_pc
].items
[ammo_inv_slot
].item_level
;
1486 dam_bonus
= adven
[current_pc
].items
[ammo_inv_slot
].bonus
+ minmax(-8,8,adven
[current_pc
].status
[1]);
1487 hit_bonus
= (overall_mode
== 12) ? adven
[current_pc
].items
[missile_inv_slot
].bonus
: 0;
1488 hit_bonus
+= stat_adj(current_pc
,1) - can_see(pc_pos
[current_pc
],target
,0)
1489 + minmax(-8,8,adven
[current_pc
].status
[1]);
1490 if ((skill_item
= pc_has_abil_equip(current_pc
,41)) < 24) {
1491 hit_bonus
+= adven
[current_pc
].items
[skill_item
].ability_strength
/ 2;
1492 dam_bonus
+= adven
[current_pc
].items
[skill_item
].ability_strength
/ 2;
1496 if (adven
[current_pc
].race
== 1)
1499 if (adven
[current_pc
].items
[ammo_inv_slot
].ability
== 172)
1501 if (adven
[current_pc
].items
[ammo_inv_slot
].variety
!= 25) {
1502 if (adven
[current_pc
].items
[ammo_inv_slot
].ability
!= 170)
1503 adven
[current_pc
].items
[ammo_inv_slot
].charges
--;
1504 else adven
[current_pc
].items
[ammo_inv_slot
].charges
= 1;
1505 if ((pc_has_abil_equip(current_pc
,11) < 24) && (adven
[current_pc
].items
[ammo_inv_slot
].ability
!= 170))
1506 adven
[current_pc
].items
[ammo_inv_slot
].charges
--;
1507 if (adven
[current_pc
].items
[ammo_inv_slot
].charges
<= 0)
1508 take_item(current_pc
,ammo_inv_slot
);
1511 // First, some missiles do special things
1512 if (exploding
== TRUE
) {
1513 take_ap((overall_mode
== 12) ? 3 : 2);
1514 add_string_to_buf(" The arrow explodes! ");
1515 run_a_missile(pc_pos
[current_pc
],target
,2,1,5,
1517 start_missile_anim();
1518 add_missile(target
,2,1, 0, 0);
1519 do_missile_anim(100,pc_pos
[current_pc
], 5);
1520 place_spell_pattern(rad2
,target
,
1521 50 + adven
[current_pc
].items
[ammo_inv_slot
].ability_strength
* 2,TRUE
,current_pc
);
1522 do_explosion_anim(5,0);
1524 handle_marked_damage();
1528 if (dist(pc_pos
[current_pc
],target
) > range
)
1529 add_string_to_buf(" Out of range.");
1530 else if (can_see(pc_pos
[current_pc
],target
,0) == 5)
1531 add_string_to_buf(" Can't see target. ");
1533 combat_posing_monster
= current_working_monster
= current_pc
;
1535 void_sanctuary(current_pc
);
1536 //play_sound((overall_mode == 12) ? 12 : 14);
1537 take_ap((overall_mode
== 12) ? 3 : 2);
1538 missile_firer
= current_pc
;
1539 r1
= get_ran(1,0,100) - 5 * hit_bonus
- 10;
1540 r1
+= 5 * (adven
[current_pc
].status
[6] / 3);
1541 r2
= get_ran(1,1,dam
) + dam_bonus
;
1542 sprintf ((char *) create_line
, "%s fires.",(char *) adven
[current_pc
].name
); // debug
1543 add_string_to_buf((char *) create_line
);
1545 switch (overall_mode
) {
1547 switch (adven
[current_pc
].items
[ammo_inv_slot
].item_level
) {
1548 case 7:m_type
= 10;break;
1549 case 4:m_type
= 1;break;
1550 case 8:m_type
= 5;break;
1551 case 9:m_type
= 7;break;
1552 default:m_type
= 10;break;
1556 m_type
= (is_magic(adven
[current_pc
].items
[ammo_inv_slot
]) == TRUE
) ? 4 : 3;
1559 run_a_missile(pc_pos
[current_pc
],target
,m_type
,1,(overall_mode
== 12) ? 12 : 14,
1562 if (r1
> hit_chance
[skill
])
1563 add_string_to_buf(" Missed.");
1564 else if ((targ_monst
= monst_there(target
)) < T_M
) {
1565 cur_monst
= &c_town
.monst
.dudes
[targ_monst
];
1566 spec_dam
= calc_spec_dam(adven
[current_pc
].items
[ammo_inv_slot
].ability
,
1567 adven
[current_pc
].items
[ammo_inv_slot
].ability_strength
,cur_monst
);
1568 if (adven
[current_pc
].items
[ammo_inv_slot
].ability
== 176) {
1569 ASB(" There is a flash of light.");
1570 cur_monst
->m_d
.health
+= r2
;
1572 else damage_monst(targ_monst
, current_pc
, r2
, spec_dam
, 1300);
1574 //if (adven[current_pc].items[ammo_inv_slot].ability == 33)
1575 // hit_space(cur_monst->m_loc,get_ran(3,1,6),1,1,1);
1578 if ((adven
[current_pc
].status
[0] > 0) && (adven
[current_pc
].weap_poisoned
== ammo_inv_slot
)) {
1579 poison_amt
= adven
[current_pc
].status
[0];
1580 if (pc_has_abil_equip(current_pc
,51) < 24)
1582 poison_monst(cur_monst
,poison_amt
);
1586 else hit_space(target
,r2
,0,1,0);
1590 combat_posing_monster
= current_working_monster
= -1;
1591 adven
[current_pc
].status
[0] = move_to_zero(adven
[current_pc
].status
[0]);
1595 // Select next active PC and, if necessary, run monsters
1596 // if monsters go or PC switches (i.e. if need redraw above), return TRUE
1597 Boolean
combat_next_step()
1599 Boolean need_stat_reprint
= FALSE
,to_return
= FALSE
;
1600 short store_pc
; // will print current pc name is active pc changes
1602 store_pc
= current_pc
;
1603 while (pick_next_pc() == TRUE
) {
1608 if (party_toast() == TRUE
)
1612 if (current_pc
!= store_pc
)
1614 center
= pc_pos
[current_pc
];
1615 //if (ensure_redraw == TRUE)
1618 adjust_spell_menus();
1620 // In case running monsters affected active PC...
1621 /* if (adven[current_pc].status[3] < 0)
1622 this_pc_hasted = FALSE;
1623 if ((adven[current_pc].main_status != 1) ||
1624 ((adven[current_pc].status[3] < 0) && (party.age % 2 == 0)))
1626 center = pc_pos[current_pc]; */
1628 if ((combat_active_pc
== 6) && (current_pc
!= store_pc
)) {
1629 sprintf((char *)create_line
, "Active: %s (#%d, %d ap.) ",
1630 adven
[current_pc
].name
,current_pc
+ 1,pc_moves
[current_pc
]);
1631 add_string_to_buf((char *)create_line
);
1634 if ((current_pc
!= store_pc
) || (to_return
== TRUE
)) {
1636 set_stat_window(current_pc
);
1641 // Find next active PC, return TRUE is monsters need running, and run monsters is slow spells
1643 Boolean
pick_next_pc()
1645 Boolean store
= FALSE
;
1647 if (current_pc
== 6)
1650 // If current pc isn't active, fry its moves
1651 if ((combat_active_pc
< 6) && (combat_active_pc
!= current_pc
))
1652 pc_moves
[current_pc
] = 0;
1654 // Find next PC with moves
1655 while ((pc_moves
[current_pc
] <= 0) && (current_pc
< 6)) {
1657 if ((combat_active_pc
< 6) && (combat_active_pc
!= current_pc
))
1658 pc_moves
[current_pc
] = 0;
1661 // If run out of PC's, return to start and try again
1662 if (current_pc
== 6) {
1664 while ((pc_moves
[current_pc
] <= 0) && (current_pc
< 6)) {
1666 if ((combat_active_pc
< 6) && (combat_active_pc
!= current_pc
))
1667 pc_moves
[current_pc
] = 0;
1669 if (current_pc
== 6) {
1679 void combat_run_monst()
1681 short i
,j
,k
,num_monst
,item
,item_level
;
1682 creature_data_type
*monst
;
1683 Boolean update_stat
= FALSE
;
1686 monsters_going
= TRUE
;
1688 monsters_going
= FALSE
;
1691 party
.light_level
= move_to_zero(party
.light_level
);
1692 if ((which_combat_type
== 1) && (c_town
.town
.lighting
== 2))
1693 party
.light_level
= max (0,party
.light_level
- 9);
1694 if (c_town
.town
.lighting
== 3)
1695 party
.light_level
= 0;
1697 party
.stuff_done
[305][2] = move_to_zero(party
.stuff_done
[305][2]);
1698 party
.stuff_done
[305][3] = move_to_zero(party
.stuff_done
[305][3]);
1700 // decrease monster present counter
1701 party
.stuff_done
[305][9] = move_to_zero(party
.stuff_done
[305][9]);
1706 if (party
.age
% 4 == 0)
1707 for (i
= 0; i
< 6; i
++) {
1708 if ((adven
[i
].status
[1] != 0) || (adven
[i
].status
[3] != 0))
1710 adven
[i
].status
[1] = move_to_zero(adven
[i
].status
[1]);
1711 adven
[i
].status
[3] = move_to_zero(adven
[i
].status
[3]);
1712 party
.stuff_done
[305][0] = move_to_zero(party
.stuff_done
[305][0]);
1713 if ((item
= pc_has_abil_equip(i
,50)) < 24) {
1715 heal_pc(i
,get_ran(1,0,adven
[i
].items
[item
].item_level
+ 1));
1718 for (i
= 0; i
< 6; i
++)
1719 if (adven
[i
].main_status
== 1) {
1720 if ((adven
[i
].status
[4] != 0) || (adven
[i
].status
[5] != 0)
1721 || (adven
[i
].status
[8] != 0)|| (adven
[i
].status
[10] != 0)
1722 || (adven
[i
].status
[11] != 0)|| (adven
[i
].status
[12] != 0))
1725 adven
[i
].status
[4] = move_to_zero(adven
[i
].status
[4]);
1726 adven
[i
].status
[5] = move_to_zero(adven
[i
].status
[5]);
1727 adven
[i
].status
[8] = move_to_zero(adven
[i
].status
[8]);
1728 adven
[i
].status
[10] = move_to_zero(adven
[i
].status
[10]);
1729 adven
[i
].status
[11] = move_to_zero(adven
[i
].status
[11]);
1730 adven
[i
].status
[12] = move_to_zero(adven
[i
].status
[12]);
1733 if (((item_level
= get_prot_level(i
,47)) > 0)
1734 && (get_ran(1,0,10) == 5)) {
1736 adven
[i
].status
[3] += item_level
/ 2;
1737 add_string_to_buf("An item hastes you!");
1739 if ((item_level
= get_prot_level(i
,46)) > 0) {
1740 if (get_ran(1,0,10) == 5) {
1742 adven
[i
].status
[1] += item_level
/ 2;
1743 add_string_to_buf("An item blesses you!");
1750 special_increase_age();
1753 if (party
.age
% 2 == 0)
1755 if (party
.age
% 3 == 0)
1759 if (update_stat
== TRUE
)
1765 void do_monster_turn()
1767 Boolean acted_yet
, had_monst
= FALSE
,printed_poison
= FALSE
,printed_disease
= FALSE
,printed_acid
= FALSE
;
1768 Boolean redraw_not_yet_done
= TRUE
;
1769 location monst_loc
,targ_space
= {0,0},move_targ
,l
;
1770 short i
,j
,k
,num_monst
,num_tries
= 0, target
,r1
,move_target
;
1771 creature_data_type
*cur_monst
;
1774 short abil_range
[40] = {0,6,8,8,10, 10,10,8,6,8, 6,0,0,0,6, 0,0,0,0,4, 10,0,0,6,0,
1775 0,0,0,0,0, 0,0,8,6,9, 0,0,0,0,0};
1776 short abil_odds
[40] = {0,5,7,6,6, 5,5,6,6,6, 6,0,0,0,4, 0,0,0,0,4, 8,0,0,7,0,
1777 0,0,0,0,0, 0,0,7,5,6, 0,0,0,0,0};
1779 monsters_going
= TRUE
; // This affects how graphics are drawn.
1782 if (overall_mode
< 10)
1783 which_combat_type
= 1;
1785 for (i
= 0; i
< num_monst
; i
++) { // Give monsters ap's, check activity
1787 cur_monst
= &c_town
.monst
.dudes
[i
];
1789 // See if hostile monster notices party, during combat
1790 if ((cur_monst
->active
== 1) && (cur_monst
->attitude
% 2 == 1) && (overall_mode
== 10)) {
1791 r1
= get_ran(1,1,100); // Check if see PCs first
1792 r1
+= (party
.stuff_done
[305][0] > 0) ? 45 : 0;
1793 r1
+= can_see(cur_monst
->m_loc
,closest_pc_loc(cur_monst
->m_loc
),0) * 10;
1795 cur_monst
->active
= 2;
1797 for (j
= 0; j
< T_M
; j
++)
1798 if (monst_near(j
,cur_monst
->m_loc
,5,1) == TRUE
) {
1799 cur_monst
->active
= 2;
1802 if ((cur_monst
->active
== 1) && (cur_monst
->attitude
% 2 == 1)) {
1803 // Now it looks for PC-friendly monsters
1804 // dist check is for efficiency
1805 for (j
= 0; j
< T_M
; j
++)
1806 if ((c_town
.monst
.dudes
[j
].active
> 0) &&
1807 (c_town
.monst
.dudes
[j
].attitude
% 2 != 1) &&
1808 (dist(cur_monst
->m_loc
,c_town
.monst
.dudes
[j
].m_loc
) <= 6) &&
1809 (can_see(cur_monst
->m_loc
,c_town
.monst
.dudes
[j
].m_loc
,0) < 5))
1810 cur_monst
->active
= 2;
1813 // See if friendly, fighting monster see hostile monster. If so, make mobile
1814 // dist check is for efficiency
1815 if ((cur_monst
->active
== 1) && (cur_monst
->attitude
== 2)) {
1816 for (j
= 0; j
< T_M
; j
++)
1817 if ((c_town
.monst
.dudes
[j
].active
> 0) && (c_town
.monst
.dudes
[j
].attitude
% 2 == 1) &&
1818 (dist(cur_monst
->m_loc
,c_town
.monst
.dudes
[j
].m_loc
) <= 6)
1819 && (can_see(cur_monst
->m_loc
,c_town
.monst
.dudes
[j
].m_loc
,0) < 5)) {
1820 cur_monst
->active
= 2;
1821 cur_monst
->mobile
= TRUE
;
1824 // End of seeing if monsters see others
1826 cur_monst
->m_d
.ap
= 0;
1827 if (cur_monst
->active
== 2) { // Begin action loop for angry, active monsters
1828 // First note that hostile monsters are around.
1829 if (cur_monst
->attitude
% 2 == 1)
1830 party
.stuff_done
[305][9] = 30;
1832 // Give monster its action points
1833 cur_monst
->m_d
.ap
= cur_monst
->m_d
.speed
;
1835 cur_monst
->m_d
.ap
= max(1,cur_monst
->m_d
.ap
/ 3);
1836 if (party
.age
% 2 == 0)
1837 if (cur_monst
->m_d
.status
[3] < 0)
1838 cur_monst
->m_d
.ap
= 0;
1839 if (cur_monst
->m_d
.ap
> 0) { // adjust for webs
1840 cur_monst
->m_d
.ap
= max(0,cur_monst
->m_d
.ap
- cur_monst
->m_d
.status
[6] / 2);
1841 if (cur_monst
->m_d
.ap
== 0)
1842 cur_monst
->m_d
.status
[6] = max(0,cur_monst
->m_d
.status
[6] - 2);
1844 if (cur_monst
->m_d
.status
[3] > 0)
1845 cur_monst
->m_d
.ap
*= 2;
1847 if ((cur_monst
->m_d
.status
[11] > 0) || (cur_monst
->m_d
.status
[12] > 0))
1848 cur_monst
->m_d
.ap
= 0;
1849 if (in_scen_debug
== TRUE
)
1850 cur_monst
->m_d
.ap
= 0;
1851 center_on_monst
= FALSE
;
1853 // Now take care of summoned monsters
1854 if (cur_monst
->active
> 0) {
1855 if ((cur_monst
->summoned
% 100) == 1) {
1856 cur_monst
->active
= 0;
1857 cur_monst
->m_d
.ap
= 0;
1858 monst_spell_note(cur_monst
->number
,17);
1860 cur_monst
->summoned
= move_to_zero(cur_monst
->summoned
);
1865 for (i
= 0; i
< num_monst
; i
++) { // Begin main monster loop, do monster actions
1866 // If party dead, no point
1867 if (party_toast() == TRUE
)
1870 futzing
= 0; // assume monster is fresh
1872 cur_monst
= &c_town
.monst
.dudes
[i
];
1875 for (j
= 0; j
< 6; j
++)
1876 if ((adven
[j
].main_status
== 1) && (monst_adjacent(pc_pos
[j
],i
) == TRUE
))
1878 else pc_adj
[j
] = FALSE
;
1882 while ((cur_monst
->m_d
.ap
> 0) && (cur_monst
->active
> 0)) { // Spend each action point
1884 if (is_combat()) { // Pick target. If in town, target already picked
1886 target
= monst_pick_target(i
);
1887 target
= switch_target_to_adjacent(i
,target
);
1889 targ_space
= pc_pos
[target
];
1890 else if (target
!= 6)
1891 targ_space
= c_town
.monst
.dudes
[target
- 100].m_loc
;
1892 monst_target
[i
] = target
;
1895 if (monst_target
[i
] < 6)
1896 targ_space
= c_town
.p_loc
;
1897 else if (monst_target
[i
] != 6)
1898 targ_space
= c_town
.monst
.dudes
[monst_target
[i
] - 100].m_loc
;
1901 // sprintf((char *)create_line," %d targets %d.",i,target);
1902 // add_string_to_buf((char *) create_line);
1904 if ((monst_target
[i
] < 0) || ((monst_target
[i
] > 5) && (monst_target
[i
] < 100)))
1905 monst_target
[i
] = 6;
1906 target
= monst_target
[i
];
1908 // Now if in town and monster about to attack, do a redraw, so we see monster
1910 if ((target
!= 6) && (is_town() == TRUE
) && (redraw_not_yet_done
== TRUE
)
1911 && (party_can_see_monst(i
) == TRUE
)) {
1913 redraw_not_yet_done
= FALSE
;
1916 // Draw w. monster in center, if can see
1917 if ((cur_monst
->m_d
.ap
> 0) && (is_combat() == TRUE
)
1918 // First make sure it has a target and is close, if not, don't bother
1919 && (cur_monst
->attitude
> 0) && (cur_monst
->m_d
.picture_num
> 0)
1920 && ((target
!= 6) || (cur_monst
->attitude
% 2 == 1))
1921 && (party_can_see_monst(i
) == TRUE
) ) {
1922 center_on_monst
= TRUE
;
1923 center
= cur_monst
->m_loc
;
1925 pause((PSD
[306][6] == 3) ? 9 : PSD
[306][6]);
1928 combat_posing_monster
= current_working_monster
= 100 + i
;
1933 // Now the monster, if evil, looks at the situation and maybe picks a tactic.
1934 // This only happens when there is >1 a.p. left, and tends to involve
1935 // running to a nice position.
1936 current_monst_tactic
= 0;
1937 if ((target
!= 6) && (cur_monst
->m_d
.ap
> 1) && (futzing
== 0)) {
1938 l
= closest_pc_loc(cur_monst
->m_loc
);
1939 if (((cur_monst
->m_d
.mu
> 0) || (cur_monst
->m_d
.cl
> 0)) &&
1940 (dist(cur_monst
->m_loc
,l
) < 5) && (monst_adjacent(l
,i
) == FALSE
))
1941 current_monst_tactic
= 1; // this means flee
1944 if ( (((cur_monst
->m_d
.spec_skill
> 0) && (cur_monst
->m_d
.spec_skill
< 4))
1945 || (cur_monst
->m_d
.spec_skill
== 20)) && // Archer?
1946 (dist(cur_monst
->m_loc
,targ_space
) < 6) &&
1947 (monst_adjacent(targ_space
,i
) == FALSE
))
1948 current_monst_tactic
= 1; // this means flee
1953 if ((monst_target
[i
] < 6) && (((cur_monst
->m_d
.morale
<= 0)
1954 && (cur_monst
->m_d
.spec_skill
!= 13) && (cur_monst
->m_d
.m_type
!= 8))
1955 || (current_monst_tactic
== 1))) {
1956 if (cur_monst
->m_d
.morale
< 0)
1957 cur_monst
->m_d
.morale
++;
1958 if (cur_monst
->m_d
.health
> 50)
1959 cur_monst
->m_d
.morale
++;
1960 r1
= get_ran(1,1,6);
1962 cur_monst
->m_d
.morale
++;
1963 /*crash*/ if ((adven
[monst_target
[i
]].main_status
== 1) && (cur_monst
->mobile
== TRUE
)) {
1964 acted_yet
= flee_party (i
,cur_monst
->m_loc
,targ_space
);
1965 if (acted_yet
== TRUE
) take_m_ap(1,cur_monst
);
1968 if ((target
!= 6) && (cur_monst
->attitude
> 0)
1969 && (monst_can_see(i
,targ_space
) == TRUE
)
1970 && (can_see_monst(targ_space
,i
) == TRUE
)) { // Begin spec. attacks
1972 // sprintf((char *)create_line,"%d: %d %d %d",i,cur_monst->m_d.breath,cur_monst->m_d.mu,cur_monst->m_d.cl);
1973 // add_string_to_buf((char *)create_line);
1976 if ( (cur_monst
->m_d
.breath
> 0)
1977 && (get_ran(1,1,8) < 4) && (acted_yet
== FALSE
)) {
1978 //print_nums(cur_monst->m_d.breath,cur_monst->m_d.breath_type,dist(cur_monst->m_loc,targ_space) );
1980 && (dist(cur_monst
->m_loc
,targ_space
) <= 8)) {
1981 acted_yet
= monst_breathe(cur_monst
,targ_space
,cur_monst
->m_d
.breath_type
);
1984 take_m_ap(4,cur_monst
);
1988 if ((cur_monst
->m_d
.mu
> 0) && (get_ran(1,1,10) < ((cur_monst
->m_d
.cl
> 0) ? 6 : 9) )
1989 && (acted_yet
== FALSE
)) {
1990 if (((monst_adjacent(targ_space
,i
) == FALSE
) || (get_ran(1,0,2) < 2) || (cur_monst
->number
>= 160)
1991 || (cur_monst
->m_d
.level
> 9))
1992 && (dist(cur_monst
->m_loc
,targ_space
) <= 10)) {
1993 acted_yet
= monst_cast_mage(cur_monst
,target
);
1996 take_m_ap(5,cur_monst
);
2000 if ((cur_monst
->m_d
.cl
> 0) && (get_ran(1,1,8) < 7) && (acted_yet
== FALSE
)) {
2001 if (((monst_adjacent(targ_space
,i
) == FALSE
) || (get_ran(1,0,2) < 2) || (cur_monst
->m_d
.level
> 9))
2002 && (dist(cur_monst
->m_loc
,targ_space
) <= 10)) {
2003 acted_yet
= monst_cast_priest(cur_monst
,target
);
2006 take_m_ap(4,cur_monst
);
2011 if ((abil_range
[cur_monst
->m_d
.spec_skill
] > 0) // breathing gas short range
2012 && (get_ran(1,1,8) < abil_odds
[cur_monst
->m_d
.spec_skill
]) && (acted_yet
== FALSE
)) {
2013 // Don't fire when adjacent, unless non-gaze magical attack
2014 if (((monst_adjacent(targ_space
,i
) == FALSE
) ||
2015 ((cur_monst
->m_d
.spec_skill
> 7) && (cur_monst
->m_d
.spec_skill
!= 20)
2016 && (cur_monst
->m_d
.spec_skill
!= 33)))
2018 && (dist(cur_monst
->m_loc
,targ_space
) <= abil_range
[cur_monst
->m_d
.spec_skill
])) {
2019 print_monst_name(cur_monst
->number
);
2020 monst_fire_missile(i
,cur_monst
->m_d
.skill
,cur_monst
->m_d
.status
[1],
2021 cur_monst
->m_d
.spec_skill
,cur_monst
->m_loc
,target
);
2023 // Vapors don't count as action
2024 if ((cur_monst
->m_d
.spec_skill
== 11) || (cur_monst
->m_d
.spec_skill
== 7) ||
2025 (cur_monst
->m_d
.spec_skill
== 20))
2026 take_m_ap(2,cur_monst
);
2027 else if (cur_monst
->m_d
.spec_skill
== 10)
2028 take_m_ap(1,cur_monst
);
2029 else take_m_ap(3,cur_monst
);
2034 } // Special attacks
2037 if ((monst_target
[i
] < 6) && (adven
[monst_target
[i
]].main_status
== 1)
2038 && (monst_adjacent(targ_space
,i
) == TRUE
) && (cur_monst
->attitude
% 2 == 1)
2039 && (acted_yet
== FALSE
)) {
2040 monster_attack_pc(i
,monst_target
[i
]);
2041 take_m_ap(4,cur_monst
);
2046 if ((monst_target
[i
] >= 100) && (c_town
.monst
.dudes
[monst_target
[i
] - 100].active
> 0)
2047 && (monst_adjacent(targ_space
,i
) == TRUE
) && (cur_monst
->attitude
> 0)
2048 && (acted_yet
== FALSE
)) {
2049 monster_attack_monster(i
,monst_target
[i
] - 100);
2050 take_m_ap(4,cur_monst
);
2055 if (acted_yet
== TRUE
) {
2062 if (overall_mode
== 10) {
2063 if ((acted_yet
== FALSE
) && (cur_monst
->mobile
== TRUE
)) { // move monst
2064 move_target
= (monst_target
[i
] != 6) ? monst_target
[i
] : closest_pc(cur_monst
->m_loc
);
2065 if (monst_hate_spot(i
,&move_targ
) == TRUE
) // First, maybe move out of dangerous space
2066 seek_party (i
,cur_monst
->m_loc
,move_targ
);
2067 else { // spot is OK, so go nuts
2068 if ((cur_monst
->attitude
% 2 == 1) && (move_target
< 6)) // Monsters seeking party do so
2069 if (adven
[move_target
].main_status
== 1) {
2070 seek_party (i
,cur_monst
->m_loc
,pc_pos
[move_target
]);
2071 for (k
= 0; k
< 6; k
++)
2072 if ((pc_parry
[k
] > 99) && (monst_adjacent(pc_pos
[k
],i
) == TRUE
)
2073 && (cur_monst
->active
> 0)) {
2079 if (move_target
>= 100) // Monsters seeking monsters do so
2080 if (c_town
.monst
.dudes
[move_target
- 100].active
> 0) {
2081 seek_party (i
,cur_monst
->m_loc
,c_town
.monst
.dudes
[move_target
- 100].m_loc
);
2082 for (k
= 0; k
< 6; k
++)
2083 if ((pc_parry
[k
] > 99) && (monst_adjacent(pc_pos
[k
],i
) == TRUE
)
2084 && (cur_monst
->active
> 0) && (cur_monst
->attitude
% 2 == 1)) {
2090 if (cur_monst
->attitude
== 0) {
2091 acted_yet
= rand_move (i
);
2095 take_m_ap(1,cur_monst
);
2097 if ((acted_yet
== FALSE
) && (cur_monst
->mobile
== FALSE
)) { // drain action points
2098 take_m_ap(1,cur_monst
);
2102 else if (acted_yet
== FALSE
) {
2103 take_m_ap(1,cur_monst
);
2107 // pcs attack any fleeing monsters
2108 if ((overall_mode
>= 10) && (overall_mode
< 20))
2109 for (k
= 0; k
< 6; k
++)
2110 if ((adven
[k
].main_status
== 1) && (monst_adjacent(pc_pos
[k
],i
) == FALSE
)
2111 && (pc_adj
[k
] == TRUE
) && (cur_monst
->attitude
% 2 == 1) && (cur_monst
->active
> 0) &&
2112 (adven
[k
].status
[8] == 0)) {
2113 combat_posing_monster
= current_working_monster
= k
;
2115 combat_posing_monster
= current_working_monster
= 100 + i
;
2119 // Place fields for monsters that create them. Only done when monst sees foe
2120 if ((target
!= 6) && (can_see(cur_monst
->m_loc
,targ_space
,0) < 5)) { ////
2121 if ((cur_monst
->m_d
.radiate_1
== 1) && (get_ran(1,0,100) < cur_monst
->m_d
.radiate_2
))
2122 place_spell_pattern(square
,cur_monst
->m_loc
,5,FALSE
,7);
2123 if ((cur_monst
->m_d
.radiate_1
== 2) && (get_ran(1,0,100) < cur_monst
->m_d
.radiate_2
))
2124 place_spell_pattern(square
,cur_monst
->m_loc
,8,FALSE
,7);
2125 if ((cur_monst
->m_d
.radiate_1
== 3) && (get_ran(1,0,100) < cur_monst
->m_d
.radiate_2
))
2126 place_spell_pattern(square
,cur_monst
->m_loc
,4,FALSE
,7);
2127 if ((cur_monst
->m_d
.radiate_1
== 4) && (get_ran(1,0,100) < cur_monst
->m_d
.radiate_2
))
2128 place_spell_pattern(square
,cur_monst
->m_loc
,6,FALSE
,7);
2129 if ((cur_monst
->m_d
.radiate_1
== 5) && (get_ran(1,0,100) < cur_monst
->m_d
.radiate_2
))
2130 place_spell_pattern(square
,cur_monst
->m_loc
,12,FALSE
,7);
2131 if ((cur_monst
->m_d
.radiate_1
== 6) && (get_ran(1,0,100) < cur_monst
->m_d
.radiate_2
))
2132 place_spell_pattern(square
,cur_monst
->m_loc
,7,FALSE
,7);
2133 if ((cur_monst
->m_d
.radiate_1
== 10) && (get_ran(1,0,100) < 5)){
2134 if (summon_monster(cur_monst
->m_d
.radiate_2
,
2135 cur_monst
->m_loc
,130,cur_monst
->attitude
) == TRUE
)
2136 {monst_spell_note(cur_monst
->number
,33); play_sound(61);}
2138 if ((cur_monst
->m_d
.radiate_1
== 11) && (get_ran(1,0,100) < 20)){
2139 if (summon_monster(cur_monst
->m_d
.radiate_2
,
2140 cur_monst
->m_loc
,130,cur_monst
->attitude
) == TRUE
)
2141 {monst_spell_note(cur_monst
->number
,33); play_sound(61);}
2143 if ((cur_monst
->m_d
.radiate_1
== 12) && (get_ran(1,0,100) < 50)){
2144 if (summon_monster(cur_monst
->m_d
.radiate_2
,
2145 cur_monst
->m_loc
,130,cur_monst
->attitude
) == TRUE
)
2146 {monst_spell_note(cur_monst
->number
,33); play_sound(61);}
2150 combat_posing_monster
= current_working_monster
= -1;
2151 // Redraw monster after it goes
2152 if ((cur_monst
->attitude
> 0) && (cur_monst
->active
> 0) && (cur_monst
->m_d
.ap
== 0)
2153 && (is_combat()) && (cur_monst
->m_d
.picture_num
> 0) && (party_can_see_monst(i
) == TRUE
)) {
2154 center
= cur_monst
->m_loc
;
2159 // If monster dead, take away actions
2160 if (cur_monst
->active
== 0)
2161 cur_monst
->m_d
.ap
= 0;
2163 //if ((futzing == 1) && (get_ran(1,0,1) == 0)) // If monster's just pissing around, give up
2164 // cur_monst->m_d.ap = 0;
2165 if (futzing
> 1) // If monster's just pissing around, give up
2166 cur_monst
->m_d
.ap
= 0;
2167 } // End of monster action loop
2172 for (i
= 0; i
< num_monst
; i
++) { // Begin monster time stuff loop
2173 // If party dead, no point
2174 if (party_toast() == TRUE
)
2177 cur_monst
= &c_town
.monst
.dudes
[i
];
2179 if ((cur_monst
->active
< 0) || (cur_monst
->active
> 2))
2180 cur_monst
->active
= 0; // clean up
2181 if (cur_monst
->active
!= 0) { // Take care of monster effects
2182 if (cur_monst
->m_d
.status
[13] > 0) { // Acid
2183 if (printed_acid
== FALSE
) {
2184 add_string_to_buf("Acid: ");
2185 printed_acid
= TRUE
;
2187 r1
= get_ran(cur_monst
->m_d
.status
[13],1,6);
2188 damage_monst(i
, 6,r1
, 0, 3);
2189 cur_monst
->m_d
.status
[13]--;
2192 if (cur_monst
->m_d
.status
[11] == 1)
2193 monst_spell_note(cur_monst
->number
,29);
2194 cur_monst
->m_d
.status
[11] = move_to_zero(cur_monst
->m_d
.status
[11]);
2195 cur_monst
->m_d
.status
[12] = move_to_zero(cur_monst
->m_d
.status
[12]);
2197 if (party
.age
% 2 == 0) {
2198 cur_monst
->m_d
.status
[1] = move_to_zero(cur_monst
->m_d
.status
[1]);
2199 cur_monst
->m_d
.status
[3] = move_to_zero(cur_monst
->m_d
.status
[3]);
2200 cur_monst
->m_d
.status
[6] = move_to_zero(cur_monst
->m_d
.status
[6]);
2202 if (cur_monst
->m_d
.status
[2] > 0) { // Poison
2203 if (printed_poison
== FALSE
) {
2204 add_string_to_buf("Poisoned monsters: ");
2205 printed_poison
= TRUE
;
2207 r1
= get_ran(cur_monst
->m_d
.status
[2],1,6);
2208 damage_monst(i
, 6, r1
, 0, 2);
2209 cur_monst
->m_d
.status
[2]--;
2211 if (cur_monst
->m_d
.status
[7] > 0) { // Disease
2212 if (printed_disease
== FALSE
) {
2213 add_string_to_buf("Diseased monsters: ");
2214 printed_disease
= TRUE
;
2218 case 1: case 2: poison_monst(cur_monst
, 2);break;
2219 case 3: slow_monst(cur_monst
,2); break;
2220 case 4: curse_monst(cur_monst
,2); break;
2221 case 5: scare_monst(cur_monst
,10); break;
2223 if (get_ran(1,1,6) < 4)
2224 cur_monst
->m_d
.status
[7]--;
2229 if (party
.age
% 4 == 0) {
2230 if (cur_monst
->m_d
.mp
< cur_monst
->m_d
.max_mp
)
2231 cur_monst
->m_d
.mp
+= 2;
2232 cur_monst
->m_d
.status
[9] = move_to_zero(cur_monst
->m_d
.status
[9]);
2234 } // end take care of monsters
2237 // If in town, need to restore center
2238 if (overall_mode
< 10)
2239 center
= c_town
.p_loc
;
2240 if (had_monst
== TRUE
)
2242 for (i
= 0; i
< 6; i
++)
2245 monsters_going
= FALSE
;
2248 void monster_attack_pc(short who_att
,short target
)
2250 creature_data_type
*attacker
;
2251 short r1
,r2
,i
,dam_type
= 0,store_hp
,sound_type
= 0;
2254 attacker
= &c_town
.monst
.dudes
[who_att
];
2256 // A peaceful monster won't attack
2257 if (attacker
->attitude
% 2 != 1)
2260 // Draw attacker frames
2262 && ((center_on_monst
== TRUE
) || (monsters_going
== FALSE
))) {
2263 if (attacker
->m_d
.spec_skill
!= 11)
2264 frame_space(attacker
->m_loc
,0,attacker
->m_d
.x_width
,attacker
->m_d
.y_width
);
2265 frame_space(pc_pos
[target
],1,1,1);
2270 if ((attacker
->m_d
.a
[0] != 0) || (attacker
->m_d
.a
[2] != 0))
2271 print_monst_attacks(attacker
->number
,target
);
2274 if (adven
[target
].status
[8] > 0) {
2275 r1
= get_ran(1,0,100);
2276 if (r1
> hit_chance
[attacker
->m_d
.level
/ 2]) {
2277 add_string_to_buf(" Can't find target! ");
2282 for (i
= 0; i
< 3; i
++) {
2283 if ((attacker
->m_d
.a
[i
] > 0) && (adven
[target
].main_status
== 1)) {
2284 // sprintf ((char *) create_line, " Attacks %s.",(char *) adven[target].name);
2285 // add_string_to_buf((char *) create_line);
2288 r1
= get_ran(1,0,100) - 5 * min(8,attacker
->m_d
.status
[1]) + 5 * adven
[target
].status
[1]
2289 + 5 * stat_adj(target
,1) - 15;
2290 r1
+= 5 * (attacker
->m_d
.status
[6] / 3);
2291 if (pc_parry
[target
] < 100)
2292 r1
+= 5 * pc_parry
[target
];
2295 r2
= get_ran(attacker
->m_d
.a
[i
] / 100 + 1,1,attacker
->m_d
.a
[i
] % 100)
2296 + min(8,attacker
->m_d
.status
[1]) - adven
[target
].status
[1] + 1;
2297 if (difficulty_adjust() > 2)
2299 if (difficulty_adjust() == 2)
2302 if ((adven
[target
].status
[11] > 0) || (adven
[target
].status
[12] > 0)) {
2308 // Check if hit, and do effects
2309 if (r1
<= hit_chance
[(attacker
->m_d
.skill
+ 4) / 2]) {
2310 if (attacker
->m_d
.m_type
== 7)
2312 if (attacker
->m_d
.m_type
== 8)
2315 store_hp
= adven
[target
].cur_health
;
2316 sound_type
= get_monst_sound(attacker
,i
);
2318 if ((damage_pc(target
,r2
,sound_type
* 100 + 30 + dam_type
,
2319 attacker
->m_d
.m_type
) == TRUE
) &&
2320 (store_hp
- adven
[target
].cur_health
> 0)) {
2321 damaged_message(store_hp
- adven
[target
].cur_health
,
2322 (i
> 0) ? attacker
->m_d
.a23_type
: attacker
->m_d
.a1_type
);
2324 if (adven
[target
].status
[10] > 0) {
2325 add_string_to_buf(" Shares damage! ");
2326 damage_monst(who_att
, 6, store_hp
- adven
[target
].cur_health
, 0, 3);
2329 if ((attacker
->m_d
.poison
> 0) && (i
== 0)) {
2330 poison_pc(target
,attacker
->m_d
.poison
);
2334 if ((attacker
->m_d
.spec_skill
== 21) && (get_ran(1,0,2) < 2)) {
2335 add_string_to_buf(" Steals food! ");
2338 party
.food
= (long) max(0, (short) (party
.food
) - get_ran(1,0,10) - 10);
2343 if (((attacker
->m_d
.spec_skill
== 25) || (attacker
->m_d
.spec_skill
== 30))
2344 && (get_ran(1,0,2) < 2)) {
2345 add_string_to_buf(" Causes disease! ");
2347 disease_pc(target
,(attacker
->m_d
.spec_skill
== 25) ? 6 : 2);
2351 if (((attacker
->m_d
.spec_skill
== 16) || (attacker
->m_d
.spec_skill
== 17))
2352 && (pc_has_abil_equip(target
,48) == 24)) {
2353 add_string_to_buf(" Drains life! ");
2354 drain_pc(target
,(attacker
->m_d
.level
* 3) / 2);
2359 if ((attacker
->m_d
.spec_skill
== 18) && (get_ran(1,0,8) < 6) && (pc_has_abil_equip(target
,48) == 24)) {
2360 add_string_to_buf(" Stuns! ");
2365 if (attacker
->m_d
.spec_skill
== 24) {
2366 add_string_to_buf(" Dumbfounds! ");
2367 dumbfound_pc(target
,2);
2372 if (attacker
->m_d
.spec_skill
== 27) {
2373 add_string_to_buf(" Webs! ");
2378 if (attacker
->m_d
.spec_skill
== 28) {
2379 add_string_to_buf(" Sleeps! ");
2380 sleep_pc(target
,6,11,-15);
2384 if (attacker
->m_d
.spec_skill
== 29) {
2385 add_string_to_buf(" Paralysis touch! ");
2386 sleep_pc(target
,500,12,-5);
2390 if (attacker
->m_d
.spec_skill
== 31) {
2391 add_string_to_buf(" Acid touch! ");
2392 acid_pc(target
,(attacker
->m_d
.level
> 20) ? 4 : 2);
2396 if (((attacker
->m_d
.spec_skill
== 15) || (attacker
->m_d
.spec_skill
== 17))
2397 && (get_ran(1,0,8) < 6) && (pc_has_abil_equip(target
,48) == 24)) {
2398 add_string_to_buf(" Freezing touch!");
2399 r1
= get_ran(3,1,10);
2400 damage_pc(target
,r1
,5,-1);
2403 if (attacker
->m_d
.spec_skill
== 35)
2405 add_string_to_buf(" Killing touch!");
2406 r1
= get_ran(20,1,10);
2407 damage_pc(target
,r1
,4,-1);
2412 sprintf ((char *) create_line
, " Misses.");
2413 add_string_to_buf((char *) create_line
);
2416 combat_posing_monster
= -1;
2418 combat_posing_monster
= 100 + who_att
;
2422 if (adven
[target
].main_status
!= 1)
2428 void monster_attack_monster(short who_att
,short attackee
)
2430 creature_data_type
*attacker
,*target
;
2431 short r1
,r2
,i
,dam_type
= 0,store_hp
,sound_type
= 0;
2433 attacker
= &c_town
.monst
.dudes
[who_att
];
2434 target
= &c_town
.monst
.dudes
[attackee
];
2436 // Draw attacker frames
2438 && ((center_on_monst
== TRUE
) || (monsters_going
== FALSE
))) {
2439 if (attacker
->m_d
.spec_skill
!= 11)
2440 frame_space(attacker
->m_loc
,0,attacker
->m_d
.x_width
,attacker
->m_d
.y_width
);
2441 frame_space(target
->m_loc
,1,1,1);
2445 if ((attacker
->m_d
.a
[1] != 0) || (attacker
->m_d
.a
[0] != 0))
2446 print_monst_attacks(attacker
->number
,100 + attackee
);
2447 for (i
= 0; i
< 3; i
++) {
2448 if ((attacker
->m_d
.a
[i
] > 0) && (target
->active
!= 0)) {
2449 // sprintf ((char *) create_line, " Attacks %s.",(char *) adven[target].name);
2450 // add_string_to_buf((char *) create_line);
2452 // if friendly to party, make able to attack
2453 if (target
->attitude
== 0)
2454 target
->attitude
= 2;
2457 r1
= get_ran(1,0,100) - 5 * min(10,attacker
->m_d
.status
[1])
2458 + 5 * target
->m_d
.status
[1] - 15;
2459 r1
+= 5 * (attacker
->m_d
.status
[6] / 3);
2462 r2
= get_ran(attacker
->m_d
.a
[i
] / 100 + 1,1,attacker
->m_d
.a
[i
] % 100)
2463 + min(10,attacker
->m_d
.status
[1]) - target
->m_d
.status
[1] + 2;
2465 if ((target
->m_d
.status
[11] > 0) || (target
->m_d
.status
[12] > 0)) {
2471 // Check if hit, and do effects
2472 if (r1
<= hit_chance
[(attacker
->m_d
.skill
+ 4) / 2]) {
2473 if (attacker
->m_d
.m_type
== 7)
2475 if (attacker
->m_d
.m_type
== 8)
2477 store_hp
= target
->m_d
.health
;
2479 sound_type
= get_monst_sound(attacker
,i
);
2481 if (damage_monst(attackee
,7,r2
,0,sound_type
* 100 + 10 + dam_type
) == TRUE
) {
2482 damaged_message(store_hp
- target
->m_d
.health
,
2483 (i
> 0) ? attacker
->m_d
.a23_type
: attacker
->m_d
.a1_type
);
2485 if ((attacker
->m_d
.poison
> 0) && (i
== 0)) {
2486 poison_monst(target
,attacker
->m_d
.poison
);
2490 if ((attacker
->m_d
.spec_skill
== 18) && (get_ran(1,0,8) < 6)) {
2491 add_string_to_buf(" Stuns! ");
2492 slow_monst(target
,2);
2496 if (attacker
->m_d
.spec_skill
== 27) {
2497 add_string_to_buf(" Webs! ");
2498 web_monst(target
,4);
2501 if (attacker
->m_d
.spec_skill
== 28) {
2502 add_string_to_buf(" Sleeps! ");
2503 charm_monst(target
,-15,11,6);
2506 if (attacker
->m_d
.spec_skill
== 24) {
2507 add_string_to_buf(" Dumbfounds! ");
2508 dumbfound_monst(target
,2);
2511 if (attacker
->m_d
.spec_skill
== 29) {
2512 add_string_to_buf(" Paralysis touch! ");
2513 charm_monst(target
,-5,12,500);
2516 if (attacker
->m_d
.spec_skill
== 31) {
2517 add_string_to_buf(" Acid touch! ");
2518 acid_monst(target
,3);
2522 if (((attacker
->m_d
.spec_skill
== 15) || (attacker
->m_d
.spec_skill
== 17))
2523 && (get_ran(1,0,8) < 6)) {
2524 add_string_to_buf(" Freezing touch!");
2525 r1
= get_ran(3,1,10);
2526 damage_monst(attackee
,7,r1
,0,5);
2530 if ((attacker
->m_d
.spec_skill
== 35)
2531 && (get_ran(1,0,8) < 6)) {
2532 add_string_to_buf(" Killing touch!");
2533 r1
= get_ran(20,1,10);
2534 damage_monst(attackee
,7,r1
,0,4);
2539 sprintf ((char *) create_line
, " Misses.");
2540 add_string_to_buf((char *) create_line
);
2543 combat_posing_monster
= -1;
2545 combat_posing_monster
= 100 + who_att
;
2547 if (target
->active
== 0)
2554 void monst_fire_missile(short m_num
,short skill
,short bless
,short level
,location source
,short target
)
2555 //short target; // 100 + - monster is target
2557 creature_data_type
*m_target
;
2558 short r1
,r2
,dam
[40] = {0,1,2,3,4, 6,8,7,0,0, 0,0,0,0,0, 0,0,0,0,0,
2559 8,0,0,0,0, 0,0,0,0,0, 0,0,0,0,6, 0,0,0,0,0},i
,j
;
2560 location targ_space
;
2564 if (target
>= 100) {
2565 targ_space
= c_town
.monst
.dudes
[target
- 100].m_loc
;
2566 if (c_town
.monst
.dudes
[target
- 100].active
== 0)
2570 targ_space
= (is_combat()) ? pc_pos
[target
] : c_town
.p_loc
;
2571 if (adven
[target
].main_status
!= 1)
2576 m_target
= &c_town
.monst
.dudes
[target
- 100];
2577 if (((overall_mode
>= 10) && (overall_mode
<= 20)) && (center_on_monst
== TRUE
)) {
2578 frame_space(source
,0,c_town
.monst
.dudes
[m_num
].m_d
.x_width
,c_town
.monst
.dudes
[m_num
].m_d
.y_width
);
2580 frame_space(targ_space
,1,m_target
->m_d
.x_width
,m_target
->m_d
.y_width
);
2581 else frame_space(targ_space
,1,1,1);
2585 if (level
== 32) { // sleep cloud
2586 ASB("Creature breathes.");
2587 run_a_missile(source
,targ_space
,0,0,44,
2589 place_spell_pattern(rad2
,targ_space
,12,FALSE
,7);
2591 else if (level
== 14) { // vapors
2593 if (target
< 100) { // on PC
2594 sprintf ((char *) create_line
, " Breathes on %s. ",(char *) adven
[target
].name
);
2595 add_string_to_buf((char *) create_line
);
2598 add_string_to_buf(" Breathes vapors.");
2600 run_a_missile(source
,targ_space
,12,0,44,
2602 scloud_space(targ_space
.x
,targ_space
.y
);
2604 else if (level
== 19) { // webs
2606 if (target
< 100) { // on PC
2607 sprintf ((char *) create_line
, " Throws web at %s. ",(char *) adven
[target
].name
);
2608 add_string_to_buf((char *) create_line
);
2611 add_string_to_buf(" Throws web.");
2613 run_a_missile(source
,targ_space
,8,0,14,
2615 web_space(targ_space
.x
,targ_space
.y
);
2617 else if (level
== 23) { // paral
2619 if (target
< 100) { // on PC
2620 sprintf ((char *) create_line
, " Fires ray at %s. ",(char *) adven
[target
].name
);
2621 add_string_to_buf((char *) create_line
);
2622 sleep_pc(target
,100,12,0);
2625 add_string_to_buf(" Shoots a ray.");
2626 charm_monst(m_target
,0,12,100);
2628 //run_a_missile(source,targ_space,8,0,14,
2630 //web_space(targ_space.x,targ_space.y);
2632 else if (level
== 8) { // petrify
2634 run_a_missile(source
,targ_space
,14,0,43,0,0,100);
2635 if (target
< 100) { // on PC
2636 sprintf ((char *) create_line
, " Gazes at %s. ",(char *) adven
[target
].name
);
2637 add_string_to_buf((char *) create_line
);
2638 r1
= get_ran(1,0,20) + adven
[target
].level
/ 4 + adven
[target
].status
[1];
2639 if (pc_has_abil_equip(target
,49) < 24)
2642 sprintf ((char *) create_line
, " %s resists. ",(char *) adven
[target
].name
);
2643 add_string_to_buf((char *) create_line
);
2646 sprintf ((char *) create_line
, " %s is turned to stone. ",(char *) adven
[target
].name
);
2647 add_string_to_buf((char *) create_line
);
2652 monst_spell_note(m_target
->number
,9);
2653 r1
= get_ran(1,0,20) + m_target
->m_d
.level
/ 4 + m_target
->m_d
.status
[1];
2654 if ((r1
> 14) || (m_target
->m_d
.immunities
& 2))
2655 monst_spell_note(m_target
->number
,10);
2657 monst_spell_note(m_target
->number
,8);
2658 kill_monst(m_target
,7);
2662 else if (level
== 9) { /// Drain sp
2663 if (target
< 100) { // pc
2664 // modify target is target has no sp
2665 if (adven
[target
].cur_sp
< 4) {
2666 for (i
= 0; i
< 8; i
++) {
2668 if ((adven
[j
].main_status
== 1) && (adven
[j
].cur_sp
> 4) &&
2669 (can_see(source
,pc_pos
[j
],0) < 5) && (dist(source
,pc_pos
[j
]) <= 8)) {
2672 targ_space
= pc_pos
[target
];
2677 run_a_missile(source
,targ_space
,8,0,43,0,0,100);
2678 sprintf ((char *) create_line
, " Drains %s. ",(char *) adven
[target
].name
);
2679 add_string_to_buf((char *) create_line
);
2680 adven
[target
].cur_sp
= adven
[target
].cur_sp
/ 2;
2683 run_a_missile(source
,targ_space
,8,0,43,0,0,100);
2684 monst_spell_note(m_target
->number
,11);
2685 if (m_target
->m_d
.mp
>= 4)
2686 m_target
->m_d
.mp
= m_target
->m_d
.mp
/ 2;
2687 else m_target
->m_d
.skill
= 1;
2690 else if (level
== 10) { // heat ray
2691 run_a_missile(source
,targ_space
,13,0,51,
2693 r1
= get_ran(7,1,6);
2694 start_missile_anim();
2695 if (target
< 100) { // pc
2696 sprintf ((char *) create_line
, " Hits %s with heat ray.",(char *) adven
[target
].name
);
2697 add_string_to_buf((char *) create_line
);
2698 damage_pc(target
,r1
,1,-1);
2701 add_string_to_buf(" Fires heat ray.");
2702 damage_monst(target
- 100,7,r1
,0,1);
2704 do_explosion_anim(5,0);
2706 handle_marked_damage();
2708 else if (level
== 33) { // acid spit
2709 run_a_missile(source
,targ_space
,0,1,64,
2712 if (target
< 100) { // pc
2713 sprintf ((char *) create_line
, " Spits acid on %s.",(char *) adven
[target
].name
);
2714 add_string_to_buf((char *) create_line
);
2718 add_string_to_buf(" Spits acid.");
2719 acid_monst(m_target
,6);
2722 else if (target
< 100) { // missile on PC
2725 case 1: case 2: case 20:
2726 run_a_missile(source
,targ_space
,3,1,12,0,0,100);
2727 sprintf ((char *) create_line
, " Shoots at %s.",(char *) adven
[target
].name
);
2730 run_a_missile(source
,targ_space
,5,1,14,0,0,100);
2731 sprintf ((char *) create_line
, " Throws spear at %s.",(char *) adven
[target
].name
);
2734 run_a_missile(source
,targ_space
,7,1,14,0,0,100);
2735 sprintf ((char *) create_line
, " Throws razordisk at %s.",(char *) adven
[target
].name
);
2738 run_a_missile(source
,targ_space
,5,1,14,0,0,100);
2739 sprintf ((char *) create_line
, " Fires spines at %s.",(char *) adven
[target
].name
);
2742 run_a_missile(source
,targ_space
,12,1,14,0,0,100);
2743 sprintf ((char *) create_line
, " Throws rock at %s.",(char *) adven
[target
].name
);
2747 add_string_to_buf((char *) create_line
);
2750 if (adven
[target
].status
[8] > 0) {
2751 r1
= get_ran(1,0,100);
2752 if (r1
> hit_chance
[level
]) {
2753 add_string_to_buf(" Can't find target! ");
2758 r1
= get_ran(1,0,100) - 5 * min(10,bless
) + 5 * adven
[target
].status
[1]
2759 - 5 * (can_see(source
, pc_pos
[target
],0));
2760 if (pc_parry
[target
] < 100)
2761 r1
+= 5 * pc_parry
[target
];
2762 r2
= get_ran(dam
[level
],1,7) + min(10,bless
);
2764 if (r1
<= hit_chance
[dam
[level
] * 2]) {
2765 // sprintf ((char *) create_line, " Hits %s.",(char *) adven[target].name);
2766 // add_string_to_buf((char *) create_line);
2768 if (damage_pc(target
,r2
,1300,-1) == TRUE
) {
2772 sprintf ((char *) create_line
, " Misses %s.",(char *) adven
[target
].name
);
2773 add_string_to_buf((char *) create_line
);
2777 else { // missile on monst
2779 case 1: case 2: case 20:
2780 run_a_missile(source
,targ_space
,3,1,12,0,0,100);
2781 monst_spell_note(m_target
->number
,12);
2784 run_a_missile(source
,targ_space
,5,1,14,0,0,100);
2785 monst_spell_note(m_target
->number
,13);
2788 run_a_missile(source
,targ_space
,7,1,14,0,0,100);
2789 monst_spell_note(m_target
->number
,15);
2792 run_a_missile(source
,targ_space
,5,1,14,0,0,100);
2793 monst_spell_note(m_target
->number
,32);
2796 run_a_missile(source
,targ_space
,12,1,14,0,0,100);
2797 monst_spell_note(m_target
->number
,14);
2800 r1
= get_ran(1,0,100) - 5 * min(10,bless
) + 5 * m_target
->m_d
.status
[1]
2801 - 5 * (can_see(source
, m_target
->m_loc
,0));
2802 r2
= get_ran(dam
[level
],1,7) + min(10,bless
);
2804 if (r1
<= hit_chance
[dam
[level
] * 2]) {
2805 // monst_spell_note(m_target->number,16);
2807 damage_monst(target
- 100,7,r2
,0,1300);
2810 monst_spell_note(m_target
->number
,18);
2816 Boolean
monst_breathe(creature_data_type
*caster
,location targ_space
,short dam_type
)
2817 //dam_type; // 0 - fire 1 - cold 2 - magic
2819 short level
,type
[4] = {1,5,3,4},missile_t
[4] = {13,6,8,8};
2823 if ((is_combat()) && (center_on_monst
== TRUE
)) {
2824 frame_space(caster
->m_loc
,0,caster
->m_d
.x_width
,caster
->m_d
.y_width
);
2828 if ((caster
->m_d
.direction
< 4) &&
2829 (caster
->m_d
.x_width
> 1))
2832 dam_type
= caster
->m_d
.breath_type
;
2833 run_a_missile(l
,targ_space
,missile_t
[dam_type
],0,44,0,0,100);
2835 //else play_sound(64);
2836 level
= caster
->m_d
.breath
;
2840 monst_breathe_note(caster
->number
);
2841 level
= get_ran(caster
->m_d
.breath
,1,8);
2842 if (overall_mode
< 10)
2844 start_missile_anim();
2845 hit_space(targ_space
,level
,type
[dam_type
],1,1);
2846 do_explosion_anim(5,0);
2848 handle_marked_damage();
2853 Boolean
monst_cast_mage(creature_data_type
*caster
,short targ
)
2855 short r1
,r2
,j
,spell
,i
,level
,target_levels
,friend_levels_near
,x
;
2856 Boolean acted
= FALSE
;
2857 location target
,vict_loc
,ashes_loc
= {0,0},l
;
2858 creature_data_type
*affected
;
2860 short caster_array
[7][18] = {{1,1,1,2,2, 2,1,3,4,4, 1,1,1,2,2, 2,3,4},
2861 {5,5,5,6,7, 8,9,10,11,11, 2,2,2,5,7, 10,10,5},
2862 {5,5,2,9,11, 12,12,12,14,13, 13,12,12,2,2, 2,2,2},
2863 {15,15,16,17,17, 5,12,12,13,13, 17,17,16,17,16, 2,2,2},
2864 {15,18,19,19,20, 20,21,21,16,17, 18,18,18,18,19, 19,19,20},
2865 {23,23,22,22,21, 21,20,24,19,18, 18,18,18,18,18, 23,23,19},
2866 {23,23,24,25,26, 27,19,22,19,18, 18,18,18,18,26, 24,24,23}};
2867 short emer_spells
[7][4] = {{2,0,0,5},
2876 if (is_antimagic(caster
->m_loc
.x
,caster
->m_loc
.y
)) {
2880 if ((targ
< 6) && (adven
[targ
].main_status
!= 1))
2882 if ((targ
>= 100) && (c_town
.monst
.dudes
[targ
- 100].active
== 0))
2885 level
= max(1,caster
->m_d
.mu
- caster
->m_d
.status
[9]) - 1;
2887 target
= find_fireball_loc(caster
->m_loc
,1,(caster
->attitude
% 2 == 1) ? 0 : 1,&target_levels
);
2888 friend_levels_near
= (caster
->attitude
% 2 != 1) ? count_levels(caster
->m_loc
,3) : -1 * count_levels(caster
->m_loc
,3);
2890 if ((caster
->m_d
.health
* 4 < caster
->m_d
.m_health
) && (get_ran(1,0,10) < 9))
2891 spell
= emer_spells
[level
][3];
2892 else if ((((caster
->m_d
.status
[3] < 0) && (get_ran(1,0,10) < 7)) ||
2893 ((caster
->m_d
.status
[3] == 0) && (get_ran(1,0,10) < 5))) && (emer_spells
[level
][0] != 0))
2894 spell
= emer_spells
[level
][0];
2895 else if ((friend_levels_near
<= -10) && (get_ran(1,0,10) < 7) && (emer_spells
[level
][1] != 0))
2896 spell
= emer_spells
[level
][1];
2897 else if ((target_levels
> 50) && (get_ran(1,0,10) < 7) && (emer_spells
[level
][2] != 0))
2898 spell
= emer_spells
[level
][2];
2900 r1
= get_ran(1,0,17);
2901 spell
= caster_array
[level
][r1
];
2904 // Hastes happen often now, but don't cast them redundantly
2905 if ((caster
->m_d
.status
[3] > 0) && ((spell
== 2) || (spell
== 18)))
2906 spell
= emer_spells
[level
][3];
2909 // Anything prventing spell?
2910 if ((target
.x
> 64) && (monst_mage_area_effect
[spell
- 1] > 0)) {
2911 r1
= get_ran(1,0,9);
2912 spell
= caster_array
[level
][r1
];
2913 if ((target
.x
> 64) && (monst_mage_area_effect
[spell
- 1] > 0))
2916 if (monst_mage_area_effect
[spell
- 1] > 0) {
2921 vict_loc
= (is_combat()) ? pc_pos
[targ
] : c_town
.p_loc
;
2923 vict_loc
= target
= c_town
.p_loc
;
2926 vict_loc
= c_town
.monst
.dudes
[targ
- 100].m_loc
;
2927 if ((targ
== 6) && (is_antimagic(target
.x
,target
.y
)))
2932 if ((targ
< 6) && (is_antimagic(pc_pos
[targ
].x
,pc_pos
[targ
].y
)))
2935 if ((targ
< 6) && (is_antimagic(c_town
.p_loc
.x
,c_town
.p_loc
.y
)))
2937 if ((targ
>= 100) && (is_antimagic(c_town
.monst
.dudes
[targ
- 100].m_loc
.x
,
2938 c_town
.monst
.dudes
[targ
- 100].m_loc
.y
)))
2942 // How about shockwave? Good idea?
2943 if ((spell
== 27) && (caster
->attitude
% 2 != 1))
2945 if ((spell
== 27) && (caster
->attitude
% 2 == 1) && (count_levels(caster
->m_loc
,10) < 45))
2948 // sprintf((char *)create_line,"m att %d trg %d trg2 x%dy%d spl %d mp %d tl:%d ",caster->attitude,targ,
2949 // (short)target.x,(short)target.y,spell,caster->m_d.mp,target_levels);
2950 // add_string_to_buf((char *) create_line);
2953 if ((caster
->m_d
.direction
< 4) && (caster
->m_d
.x_width
> 1))
2956 if (caster
->m_d
.mp
>= monst_mage_cost
[spell
- 1]) {
2957 monst_cast_spell_note(caster
->number
,spell
,0);
2959 caster
->m_d
.mp
-= monst_mage_cost
[spell
- 1];
2964 run_a_missile(l
,vict_loc
,6,1,11,0,0,80);
2965 r1
= get_ran(2,1,4);
2966 damage_target(targ
,r1
,1);
2968 case 2: // minor haste
2970 caster
->m_d
.status
[3] += 2;
2974 caster
->m_d
.status
[1] += 3;
2976 case 4: // flame cloud
2977 run_a_missile(l
,vict_loc
,2,1,11,0,0,80);
2978 place_spell_pattern(single
,vict_loc
,5,FALSE
,7);
2981 run_a_missile(l
,vict_loc
,2,1,11,0,0,80);
2982 start_missile_anim();
2983 r1
= get_ran(caster
->m_d
.level
,1,4);
2984 damage_target(targ
,r1
,1);
2986 case 6: // minor poison
2987 run_a_missile(l
,vict_loc
,11,0,25,0,0,80);
2989 poison_pc(targ
,2 + get_ran(1,0,1));
2990 else poison_monst(&c_town
.monst
.dudes
[targ
- 100],2 + get_ran(1,0,1));
2993 run_a_missile(l
,vict_loc
,15,0,25,0,0,80);
2995 slow_pc(targ
,2 + caster
->m_d
.level
/ 2);
2996 else slow_monst(&c_town
.monst
.dudes
[targ
- 100],2 + caster
->m_d
.level
/ 2);
2998 case 8: // dumbfound
2999 run_a_missile(l
,vict_loc
,14,0,25,0,0,80);
3001 dumbfound_pc(targ
,2);
3002 else dumbfound_monst(&c_town
.monst
.dudes
[targ
- 100],2);
3005 run_a_missile(l
,target
,0,0,25,0,0,80);
3006 place_spell_pattern(square
,target
,7,FALSE
,7);
3008 case 10: // summon beast
3009 r1
= get_summon_monster(1);
3013 //Delay(12,&dummy); // gives sound time to end
3016 summon_monster(r1
,caster
->m_loc
,
3017 ((caster
->attitude
% 2 != 1) ? 0 : 100) + x
,caster
->attitude
);
3019 case 11: // conflagration
3020 run_a_missile(l
,target
,13,1,25,0,0,80);
3021 place_spell_pattern(rad2
,target
,5,FALSE
,7);
3023 case 12: // fireball
3024 r1
= 1 + (caster
->m_d
.level
* 3) / 4;
3025 if (r1
> 29) r1
= 29;
3026 run_a_missile(l
,target
,2,1,11,0,0,80);
3027 start_missile_anim();
3028 place_spell_pattern(square
,target
,50 + r1
,TRUE
,7);
3031 case 13: case 20: case 26:// summon
3034 r1
= get_summon_monster(1);
3037 j
= get_ran(2,1,3) + 1;
3040 r1
= get_summon_monster(2);
3043 j
= get_ran(2,1,2) + 1;
3046 r1
= get_summon_monster(3);
3051 Delay(12,&dummy
); // gives sound time to end
3053 for (i
= 0; i
< j
; i
++){
3055 if (summon_monster(r1
,caster
->m_loc
,
3056 ((caster
->attitude
% 2 != 1) ? 0 : 100) + x
,caster
->attitude
) == FALSE
) {
3057 add_string_to_buf(" Summon failed."); i
= j
;}
3062 place_spell_pattern(rad2
,target
,1,FALSE
,7);
3065 run_a_missile(l
,vict_loc
,11,0,25,0,0,80);
3068 poison_pc(targ
,4 + x
);
3069 else poison_monst(&c_town
.monst
.dudes
[targ
- 100],4 + x
);
3071 case 16: // ice bolt
3072 run_a_missile(l
,vict_loc
,6,1,11,0,0,80);
3073 r1
= get_ran(5 + (caster
->m_d
.level
/ 5),1,8);
3074 start_missile_anim();
3075 damage_target(targ
,r1
,5);
3079 if (caster
->attitude
% 2 == 1)
3080 for (i
= 0; i
< 6; i
++)
3081 if (pc_near(i
,caster
->m_loc
,8))
3082 slow_pc(i
,2 + caster
->m_d
.level
/ 4);
3083 for (i
= 0; i
< T_M
; i
++) {
3084 if ((c_town
.monst
.dudes
[i
].active
!= 0) &&
3085 (((c_town
.monst
.dudes
[i
].attitude
% 2 == 1) && (caster
->attitude
% 2 != 1)) ||
3086 ((c_town
.monst
.dudes
[i
].attitude
% 2 != 1) && (caster
->attitude
% 2 == 1)) ||
3087 ((c_town
.monst
.dudes
[i
].attitude
% 2 == 1) && (caster
->attitude
!= c_town
.monst
.dudes
[i
].attitude
)))
3088 && (dist(caster
->m_loc
,c_town
.monst
.dudes
[i
].m_loc
) <= 7))
3089 slow_monst(&c_town
.monst
.dudes
[i
],2 + caster
->m_d
.level
/ 4);
3092 case 18: // major haste
3094 for (i
= 0; i
< T_M
; i
++)
3095 if ((monst_near(i
,caster
->m_loc
,8,0)) &&
3096 (caster
->attitude
== c_town
.monst
.dudes
[i
].attitude
)) {
3097 affected
= &c_town
.monst
.dudes
[i
];
3098 affected
->m_d
.status
[3] += 3;
3102 case 19: // firestorm
3103 run_a_missile(l
,target
,2,1,11,0,0,80);
3104 r1
= 1 + (caster
->m_d
.level
* 3) / 4 + 3;
3105 if (r1
> 29) r1
= 29;
3106 start_missile_anim();
3107 place_spell_pattern(rad2
,target
,50 + r1
,TRUE
,7);
3114 case 21: // shockstorm
3115 run_a_missile(l
,target
,6,1,11,0,0,80);
3116 place_spell_pattern(rad2
,target
,4,FALSE
,7);
3118 case 22: // m. poison
3119 run_a_missile(l
,vict_loc
,11,1,11,0,0,80);
3122 poison_pc(targ
,6 + x
);
3123 else poison_monst(&c_town
.monst
.dudes
[targ
- 100],6 + x
);
3126 run_a_missile(l
,vict_loc
,9,1,11,0,0,80);
3127 r1
= 35 + get_ran(3,1,10);
3128 start_missile_anim();
3129 damage_target(targ
,r1
,3);
3135 Delay(12,&dummy
); // gives sound time to end
3136 summon_monster(85,caster
->m_loc
,
3137 ((caster
->attitude
% 2 != 1) ? 0 : 100) + x
,caster
->attitude
);
3139 case 25: // major bless
3141 for (i
= 0; i
< T_M
; i
++)
3142 if ((monst_near(i
,caster
->m_loc
,8,0)) &&
3143 (caster
->attitude
== c_town
.monst
.dudes
[i
].attitude
)) {
3144 affected
= &c_town
.monst
.dudes
[i
];
3145 affected
->m_d
.health
+= get_ran(2,1,10);
3146 r1
= get_ran(3,1,4);
3147 affected
->m_d
.status
[1] = min(8,affected
->m_d
.status
[1] + r1
);
3148 affected
->m_d
.status
[6] = 0;
3149 if (affected
->m_d
.status
[3] < 0)
3150 affected
->m_d
.status
[3] = 0;
3151 affected
->m_d
.morale
+= get_ran(3,1,10);
3155 case 27: // shockwave
3156 do_shockwave(caster
->m_loc
);
3160 else caster
->m_d
.mp
++;
3162 if (ashes_loc
.x
> 0)
3163 make_sfx(ashes_loc
.x
,ashes_loc
.y
,6);
3164 do_explosion_anim(5,0);
3166 handle_marked_damage();
3171 Boolean
monst_cast_priest(creature_data_type
*caster
,short targ
)
3173 short r1
,r2
,spell
,i
,x
,level
,target_levels
,friend_levels_near
;
3174 Boolean acted
= FALSE
;
3175 location target
,vict_loc
,l
;
3176 creature_data_type
*affected
;
3177 short caster_array
[7][10] = {{1,1,1,1,3,3,3,4,4,4},
3178 {5,5,6,6,7,7,8,8,8,9},
3179 {9,6,6,8,11,12,12,5,5,12},
3180 {12,12,13,13,14,9,9,14,14,15},
3181 {19,18,13,19,15,18,18,19,16,18},
3182 {22,18,16,19,18,18,21,22,23,23},
3183 {26,26,25,24,26,22,24,22,26,25}};
3184 short emer_spells
[7][4] = {{0,1,0,2},
3191 location ashes_loc
= {0,0};
3194 if ((targ
< 6) && (adven
[targ
].main_status
!= 1))
3196 if ((targ
>= 100) && (c_town
.monst
.dudes
[targ
- 100].active
== 0))
3198 if (is_antimagic(caster
->m_loc
.x
,caster
->m_loc
.y
)) {
3201 level
= max(1,caster
->m_d
.cl
- caster
->m_d
.status
[9]) - 1;
3203 target
= find_fireball_loc(caster
->m_loc
,1,(caster
->attitude
% 2 == 1) ? 0 : 1,&target_levels
);
3204 friend_levels_near
= (caster
->attitude
% 2 != 1) ? count_levels(caster
->m_loc
,3) : -1 * count_levels(caster
->m_loc
,3);
3206 if ((caster
->m_d
.health
* 4 < caster
->m_d
.m_health
) && (get_ran(1,0,10) < 9))
3207 spell
= emer_spells
[level
][3];
3208 else if ((caster
->m_d
.status
[3] < 0) && (get_ran(1,0,10) < 7) && (emer_spells
[level
][0] != 0))
3209 spell
= emer_spells
[level
][0];
3210 else if ((friend_levels_near
<= -10) && (get_ran(1,0,10) < 7) && (emer_spells
[level
][1] != 0))
3211 spell
= emer_spells
[level
][1];
3212 else if ((target_levels
> 50 < 0) && (get_ran(1,0,10) < 7) && (emer_spells
[level
][2] != 0))
3213 spell
= emer_spells
[level
][2];
3215 r1
= get_ran(1,0,9);
3216 spell
= caster_array
[level
][r1
];
3221 // Anything preventing spell?
3222 if ((target
.x
> 64) && (monst_priest_area_effect
[spell
- 1] > 0)) {
3223 r1
= get_ran(1,0,9);
3224 spell
= caster_array
[level
][r1
];
3225 if ((target
.x
> 64) && (monst_priest_area_effect
[spell
- 1] > 0))
3228 if (monst_priest_area_effect
[spell
- 1] > 0)
3231 vict_loc
= (is_town()) ? c_town
.p_loc
: pc_pos
[targ
];
3233 vict_loc
= c_town
.monst
.dudes
[targ
- 100].m_loc
;
3234 if ((targ
== 6) && (is_antimagic(target
.x
,target
.y
)))
3236 if ((targ
< 6) && (is_antimagic(pc_pos
[targ
].x
,pc_pos
[targ
].y
)))
3238 if ((targ
>= 100) && (is_antimagic(c_town
.monst
.dudes
[targ
- 100].m_loc
.x
,
3239 c_town
.monst
.dudes
[targ
- 100].m_loc
.y
)))
3243 // sprintf((char *)create_line,"p att %d trg %d trg2 x%dy%d spl %d mp %d",caster->attitude,targ,
3244 // (short)target.x,(short)target.y,spell,caster->m_d.mp);
3245 // add_string_to_buf((char *) create_line);
3247 // snuff heals if unwounded
3248 if ((caster
->m_d
.health
== caster
->m_d
.m_health
) &&
3249 ((spell
== 17) || (spell
== 20)))
3253 if ((caster
->m_d
.direction
< 4) && (caster
->m_d
.x_width
> 1))
3256 if (caster
->m_d
.mp
>= monst_priest_cost
[spell
- 1]) {
3257 monst_cast_spell_note(caster
->number
,spell
,1);
3259 caster
->m_d
.mp
-= monst_priest_cost
[spell
- 1];
3263 run_a_missile(l
,vict_loc
,8,0,24,0,0,80);
3264 r1
= get_ran(2,1,4);
3265 start_missile_anim();
3266 damage_target(targ
,r1
,4);
3270 place_spell_pattern(single
,vict_loc
,1,FALSE
,7);
3272 case 1: case 5: // Blesses
3274 caster
->m_d
.status
[1] = min(8,caster
->m_d
.status
[1] + (spell
== 1) ? 3 : 5);
3278 run_a_missile(l
,vict_loc
,8,0,24,0,0,80);
3281 curse_pc(targ
,2 + x
);
3282 else curse_monst(&c_town
.monst
.dudes
[targ
- 100],2 + x
);
3285 run_a_missile(l
,vict_loc
,8,0,24,0,0,80);
3286 r1
= get_ran(2,1,6) + 2;
3287 start_missile_anim();
3288 damage_target(targ
,r1
,3);
3290 case 8: case 22: // summon spirit,summon guardian
3295 summon_monster(((spell
== 8) ? 125 : 122),caster
->m_loc
,
3296 ((caster
->attitude
% 2 != 1) ? 0 : 100) + x
,caster
->attitude
);
3299 run_a_missile(l
,vict_loc
,11,0,24,0,0,80);
3302 disease_pc(targ
,2 + x
);
3303 else disease_monst(&c_town
.monst
.dudes
[targ
- 100],2 + x
);
3305 case 11: // holy scourge
3306 run_a_missile(l
,vict_loc
,15,0,24,0,0,80);
3308 r1
= get_ran(1,0,2);
3309 slow_pc(targ
,2 + r1
);
3310 r1
= get_ran(1,0,2);
3311 curse_pc(targ
,3 + r1
);
3314 r1
= get_ran(1,0,2);
3315 slow_monst(&c_town
.monst
.dudes
[targ
- 100],r1
);
3316 r1
= get_ran(1,0,2);
3317 curse_monst(&c_town
.monst
.dudes
[targ
- 100],r1
);
3321 run_a_missile(l
,vict_loc
,6,0,24,0,0,80);
3322 r1
= get_ran(4,1,6) + 2;
3323 start_missile_anim();
3324 damage_target(targ
,r1
,5);
3326 case 14: // sticks to snakes
3328 r1
= get_ran(1,1,4) + 2;
3329 for (i
= 0; i
< r1
; i
++) {
3331 r2
= get_ran(1,0,7);
3333 summon_monster((r2
== 1) ? 100 : 99,caster
->m_loc
,
3334 ((caster
->attitude
% 2 != 1) ? 0 : 100) + x
,caster
->attitude
);
3337 case 15: // martyr's shield
3339 caster
->m_d
.status
[10] = min(10,caster
->m_d
.status
[10] + 5);
3341 case 19: // summon host
3343 x
= get_ran(3,1,4) + 1;
3345 summon_monster(126,caster
->m_loc
,
3346 ((caster
->attitude
% 2 != 1) ? 0 : 100) + x
,caster
->attitude
);
3347 for (i
= 0; i
< 4; i
++) {
3349 if (summon_monster(125,caster
->m_loc
,
3350 ((caster
->attitude
% 2 != 1) ? 0 : 100) + x
,caster
->attitude
) == FALSE
)
3355 case 13: case 23: // holy scourge,curse all,pestilence
3357 r1
= get_ran(2,0,2);
3358 r2
= get_ran(1,0,2);
3359 if (caster
->attitude
% 2 == 1)
3360 for (i
= 0; i
< 6; i
++)
3361 if (pc_near(i
,caster
->m_loc
,8)) {
3365 disease_pc(i
,2 + r2
);
3367 for (i
= 0; i
< T_M
; i
++) {
3368 if ((c_town
.monst
.dudes
[i
].active
!= 0) &&
3369 (((c_town
.monst
.dudes
[i
].attitude
% 2 == 1) && (caster
->attitude
% 2 != 1)) ||
3370 ((c_town
.monst
.dudes
[i
].attitude
% 2 != 1) && (caster
->attitude
% 2 == 1)) ||
3371 ((c_town
.monst
.dudes
[i
].attitude
% 2 == 1) && (caster
->attitude
!= c_town
.monst
.dudes
[i
].attitude
)))
3372 && (dist(caster
->m_loc
,c_town
.monst
.dudes
[i
].m_loc
) <= 7)) {
3374 curse_monst(&c_town
.monst
.dudes
[i
],2 + r1
);
3376 disease_monst(&c_town
.monst
.dudes
[i
],2 + r2
);
3381 case 2: case 10: case 17: case 20: // heals
3384 case 2: r1
= get_ran(2,1,4) + 2; break;
3385 case 10: r1
= get_ran(3,1,6); break;
3386 case 17: r1
= get_ran(5,1,6) + 3; break;
3387 case 20: r1
= 50; break;
3389 caster
->m_d
.health
= min(caster
->m_d
.health
+ r1
, caster
->m_d
.m_health
);
3391 case 16: case 24:// bless all,revive all
3393 r1
= get_ran(2,1,4); r2
= get_ran(3,1,6);
3394 for (i
= 0; i
< T_M
; i
++)
3395 if ((monst_near(i
,caster
->m_loc
,8,0)) &&
3396 (caster
->attitude
== c_town
.monst
.dudes
[i
].attitude
)) {
3397 affected
= &c_town
.monst
.dudes
[i
];
3399 affected
->m_d
.status
[1] = min(8,affected
->m_d
.status
[1] + r1
);
3401 affected
->m_d
.health
+= r1
;
3405 case 18: // Flamestrike
3406 run_a_missile(l
,target
,2,0,11,0,0,80);
3407 r1
= 2 + caster
->m_d
.level
/ 2 + 2;
3408 start_missile_anim();
3409 place_spell_pattern(square
,target
,50 + r1
,TRUE
,7);
3414 case 21: // holy ravaging
3415 run_a_missile(l
,vict_loc
,14,0,53,0,0,80);
3416 r1
= get_ran(4,1,8);
3417 r2
= get_ran(1,0,2);
3418 damage_target(targ
,r1
,3);
3421 poison_pc(targ
,5 + r2
);
3424 slow_monst(&c_town
.monst
.dudes
[targ
- 100],6);
3425 poison_monst(&c_town
.monst
.dudes
[targ
- 100],5 + r2
);
3430 monst_spell_note(caster
->number
,26);
3431 caster
->m_d
.health
= caster
->m_d
.m_health
;
3432 caster
->m_d
.status
[1] = 8;
3433 caster
->m_d
.status
[2] = 0;
3434 caster
->m_d
.status
[3] = 8;
3435 caster
->m_d
.status
[6] = 0;
3436 caster
->m_d
.status
[7] = 0;
3437 caster
->m_d
.status
[9] = 0;
3438 caster
->m_d
.status
[10] = 8;
3440 case 26: // divine thud
3441 run_a_missile(l
,target
,9,0,11,0,0,80);
3442 r1
= (caster
->m_d
.level
* 3) / 4 + 5;
3443 if (r1
> 29) r1
= 29;
3444 start_missile_anim();
3445 place_spell_pattern(rad2
,target
,130 + r1
,TRUE
,7 );
3452 else caster
->m_d
.mp
++;
3453 if (ashes_loc
.x
> 0)
3454 make_sfx(ashes_loc
.x
,ashes_loc
.y
,6);
3455 do_explosion_anim(5,0);
3457 handle_marked_damage();
3462 void damage_target(short target
,short dam
,short type
)
3465 if (target
== 6) return;
3467 damage_pc(target
,dam
,type
,-1);
3468 else damage_monst(target
- 100, 7, dam
, 0, type
);
3472 // target = find_fireball_loc(caster->m_loc,1,(caster->attitude == 1) ? 0 : 1,&target_levels);
3474 location
find_fireball_loc(location where
,short radius
,short mode
,short *m
)
3475 //short mode; // 0 - hostile casting 1 - friendly casting
3477 location check_loc
,cast_loc
= {120,0};
3478 short i
,j
,k
,cur_lev
,level_max
= 10;
3480 for (check_loc
.x
= 1; check_loc
.x
< town_size
[town_type
] - 1; check_loc
.x
++)
3481 for (check_loc
.y
= 1; check_loc
.y
< town_size
[town_type
] - 1; check_loc
.y
++)
3482 if ((dist(where
,check_loc
) <= 8) && (can_see(where
,check_loc
,2) < 5) && (get_obscurity(check_loc
.x
,check_loc
.y
) < 5)) {
3484 cur_lev
= count_levels(check_loc
,radius
);
3486 cur_lev
= cur_lev
* -1;
3487 if ( ((cur_lev
> level_max
) || ((cur_lev
== level_max
) && (get_ran(1,0,1) == 0)))
3488 && (dist(where
,check_loc
) > radius
)) {
3489 level_max
= cur_lev
;
3490 cast_loc
= check_loc
;
3499 location
closest_pc_loc(location where
)
3502 location pc_where
= {120,120};
3504 for (i
= 0; i
< 6; i
++)
3505 if (adven
[i
].main_status
== 1)
3506 if ((dist(where
,pc_pos
[i
])) < (dist(where
,pc_where
)))
3507 pc_where
= pc_pos
[i
];
3511 short count_levels(location where
,short radius
)
3515 for (i
= 0; i
< T_M
; i
++)
3516 if (monst_near(i
,where
,radius
,0) == TRUE
) {
3517 if (c_town
.monst
.dudes
[i
].attitude
% 2 == 1)
3518 store
= store
- c_town
.monst
.dudes
[i
].m_d
.level
;
3519 else store
= store
+ c_town
.monst
.dudes
[i
].m_d
.level
;
3522 for (i
= 0; i
< 6; i
++)
3523 if (pc_near(i
,where
,radius
) == TRUE
)
3527 if ((vdist(where
,c_town
.p_loc
) <= radius
) && (can_see(where
,c_town
.p_loc
,2) < 5))
3533 Boolean
pc_near(short pc_num
,location where
,short radius
)
3535 // Assuming not looking
3536 if (overall_mode
>= 10) {
3537 if ((adven
[pc_num
].main_status
== 1) && (vdist(pc_pos
[pc_num
],where
) <= radius
))
3541 if ((adven
[pc_num
].main_status
== 1) && (vdist(c_town
.p_loc
,where
) <= radius
))
3546 /*short pc_there(where)
3551 for (i = 0; i < 6; i++)
3552 if ((adven[i].main_status == 1) && (pc_pos[i].x == where.x) && (pc_pos[i].y == where.y))
3557 Boolean
monst_near(short m_num
,location where
,short radius
,short active
)
3558 //short active; // 0 - any monst 1 - monster need be active
3560 if ((c_town
.monst
.dudes
[m_num
].active
!= 0) && (vdist(c_town
.monst
.dudes
[m_num
].m_loc
,where
) <= radius
)
3561 && ((active
== 0) || (c_town
.monst
.dudes
[m_num
].active
== 2)) )
3566 void fireball_space(location loc
,short dam
)
3568 place_spell_pattern(square
,loc
,50 + dam
,FALSE
,7);
3571 void place_spell_pattern(effect_pat_type pat
,location center
,short type
,Boolean prep_for_anim
,short who_hit
)
3572 //type; // 0 - take codes in pattern, OW make all nonzero this type
3573 // Types 0 - Null 1 - web 2 - fire barrier 3 - force barrier 4 - force wall 5 - fire wall
3574 // 6 - anti-magic field 7 - stink cloud 8 - ice wall 9 - blade wall 10 - quickfire
3575 // 11 - dispel 12 - sleep field
3576 // 50 + i - 80 : id6 fire damage 90 + i - 120 : id6 cold damage 130 + i - 160 : id6 magic dam.
3577 // if prep for anim is TRUE, supporess look checks and go fast
3579 short i
,j
,r1
,k
,store
= 0;
3580 unsigned char effect
;
3584 creature_data_type
*which_m
;
3585 Boolean monster_hit
= FALSE
;
3587 location pool_locs
[5] = {{13,2},{11,19},{34,22},{46,15},{46,7}};
3590 modify_pattern(&pat
,type
);
3592 // first clip out special results.
3593 if (((is_town()) || ((is_combat()) && (which_combat_type
== 1))) && (c_town
.town_num
== 46) && (center
.x
== 24) && (center
.y
== 41)
3594 && (PSD
[46][9] == 0) && (type
>= 50) && (type
< 90)) {
3596 run_a_missile(pc_pos
[current_pc
],center
,2,1,11,0,0,200);
3597 mondo_boom(center
,0);
3600 for (i
= 0; i
< 4; i
++)
3601 elim_monst(138 + i
,46,9);
3602 alter_space(24,41,0);
3605 for (i
= 0; i
< 5; i
++)
3606 store
+= PSD
[20][i
];
3607 if (((is_town()) || ((is_combat()) && (which_combat_type
== 1))) && (c_town
.town_num
== 23))
3608 for (i
= 0; i
< 5; i
++)
3609 if ((center
.x
== pool_locs
[i
].x
) && (center
.y
== pool_locs
[i
].y
)
3610 && (PSD
[20][i
] == 0) && (type
>= 50) && (type
< 90)) {
3612 run_a_missile(pc_pos
[current_pc
],center
,2,1,11,0,0,200);
3613 mondo_boom(center
,0);
3621 alter_space(pool_locs
[i
].x
,pool_locs
[i
].y
,0);
3626 active
= c_town
.town
.in_town_rect
;
3627 // eliminate barriers that can't be seen
3628 for (i
= minmax(active
.left
+ 1,active
.right
- 1,center
.x
- 4);
3629 i
<= minmax(active
.left
+ 1,active
.right
- 1,center
.x
+ 4); i
++)
3630 for (j
= minmax(active
.top
+ 1,active
.bottom
- 1,center
.y
- 4);
3631 j
<= minmax(active
.top
+ 1,active
.bottom
- 1,center
.y
+ 4); j
++) {
3632 s_loc
.x
= i
; s_loc
.y
= j
;
3633 if (can_see(center
,s_loc
,0) == 5)
3634 pat
.pattern
[i
- center
.x
+ 4][j
- center
.y
+ 4] = 0;
3638 // First actually make barriers, then draw them, then inflict damaging effects.
3639 for (i
= minmax(0,town_size
[town_type
] - 1,center
.x
- 4); i
<= minmax(0,town_size
[town_type
] - 1,center
.x
+ 4); i
++)
3640 for (j
= minmax(0,town_size
[town_type
] - 1,center
.y
- 4); j
<= minmax(0,town_size
[town_type
] - 1,center
.y
+ 4); j
++)
3641 if (get_obscurity(i
,j
) < 5) {
3642 effect
= pat
.pattern
[i
- center
.x
+ 4][j
- center
.y
+ 4];
3644 case 1: web_space(i
,j
); break;
3645 case 2: make_fire_barrier(i
,j
); break;
3646 case 3: make_force_barrier(i
,j
); break;
3648 make_force_wall(i
,j
); break;
3649 case 5: make_fire_wall(i
,j
); break;
3650 case 6: make_antimagic(i
,j
); break;
3651 case 7: scloud_space(i
,j
); break;
3652 case 8: make_ice_wall(i
,j
); break;
3653 case 9: make_blade_wall(i
,j
); break;
3655 make_quickfire(i
,j
);
3658 dispel_fields(i
,j
,0);
3660 case 12: sleep_cloud_space(i
,j
); break;
3664 if (is_town()) // now make things move faster if in town
3668 for (k
= 0; k
< 6; k
++)
3669 for (i
= minmax(0,town_size
[town_type
] - 1,center
.x
- 4); i
<= minmax(0,town_size
[town_type
] - 1,center
.x
+ 4); i
++)
3670 for (j
= minmax(0,town_size
[town_type
] - 1,center
.y
- 4); j
<= minmax(0,town_size
[town_type
] - 1,center
.y
+ 4); j
++) {
3673 if ((get_obscurity(i
,j
) < 5) && (adven
[k
].main_status
== 1)
3674 && (((is_combat()) &&(same_point(pc_pos
[k
],spot_hit
) == TRUE
)) ||
3675 ((is_town()) && (same_point(c_town
.p_loc
,spot_hit
) == TRUE
)))) {
3676 effect
= pat
.pattern
[i
- center
.x
+ 4][j
- center
.y
+ 4];
3679 r1
= get_ran(2,1,6);
3680 damage_pc(k
,r1
,3,-1);
3683 r1
= get_ran(1,1,6) + 1;
3684 damage_pc(k
,r1
,1,-1);
3687 r1
= get_ran(2,1,6);
3688 damage_pc(k
,r1
,5,-1);
3691 r1
= get_ran(4,1,8);
3692 damage_pc(k
,r1
,0,-1);
3695 if ((effect
>= 50) && (effect
< 80)) {
3696 r1
= get_ran(effect
- 50,1,6);
3697 damage_pc(k
,r1
,1,-1);
3699 if ((effect
>= 90) && (effect
< 120)) {
3700 r1
= get_ran(effect
- 90,1,6);
3701 damage_pc(k
,r1
,5,-1);
3703 if ((effect
>= 130) && (effect
< 160)) {
3704 r1
= get_ran(effect
- 130,1,6);
3705 damage_pc(k
,r1
,3,-1);
3714 // Damage to monsters
3715 for (k
= 0; k
< T_M
; k
++)
3716 if ((c_town
.monst
.dudes
[k
].active
> 0) && (dist(center
,c_town
.monst
.dudes
[k
].m_loc
) <= 5)) {
3717 monster_hit
= FALSE
;
3718 // First actually make barriers, then draw them, then inflict damaging effects.
3719 for (i
= minmax(0,town_size
[town_type
] - 1,center
.x
- 4); i
<= minmax(0,town_size
[town_type
] - 1,center
.x
+ 4); i
++)
3720 for (j
= minmax(0,town_size
[town_type
] - 1,center
.y
- 4); j
<= minmax(0,town_size
[town_type
] - 1,center
.y
+ 4); j
++) {
3724 if ((monster_hit
== FALSE
) && (get_obscurity(i
,j
) < 5) && (monst_on_space(spot_hit
,k
) > 0)) {
3726 if (pat
.pattern
[i
- center
.x
+ 4][j
- center
.y
+ 4] > 0)
3728 effect
= pat
.pattern
[i
- center
.x
+ 4][j
- center
.y
+ 4];
3731 which_m
= &c_town
.monst
.dudes
[k
];
3732 web_monst(which_m
,3);
3735 r1
= get_ran(3,1,6);
3736 damage_monst(k
, who_hit
, r1
,0, 3);
3739 r1
= get_ran(2,1,6);
3740 which_m
= &c_town
.monst
.dudes
[k
];
3741 if (which_m
->m_d
.spec_skill
== 22)
3743 damage_monst(k
, who_hit
, r1
,0, 1);
3746 which_m
= &c_town
.monst
.dudes
[k
];
3747 curse_monst(which_m
,get_ran(1,1,2));
3750 which_m
= &c_town
.monst
.dudes
[k
];
3751 r1
= get_ran(3,1,6);
3752 if (which_m
->m_d
.spec_skill
== 23)
3754 damage_monst(k
, who_hit
, r1
,0, 5);
3757 r1
= get_ran(6,1,8);
3758 damage_monst(k
, who_hit
, r1
,0, 0);
3761 which_m
= &c_town
.monst
.dudes
[k
];
3762 charm_monst(which_m
,0,11,3);
3765 if ((effect
>= 50) && (effect
< 80)) {
3766 r1
= get_ran(effect
- 50,1,6);
3767 damage_monst(k
,who_hit
, r1
,0,1);
3769 if ((effect
>= 90) && (effect
< 120)) {
3770 r1
= get_ran(effect
- 90,1,6);
3771 damage_monst(k
,who_hit
, r1
,0, 5);
3773 if ((effect
>= 130) && (effect
< 160)) {
3774 r1
= get_ran(effect
- 130,1,6);
3775 damage_monst(k
,who_hit
, r1
,0, 3 );
3784 void modify_pattern(effect_pat_type
*pat
,short type
)
3788 for (i
= 0; i
< 9; i
++)
3789 for (j
= 0; j
< 9; j
++)
3790 if (pat
->pattern
[i
][j
] > 0)
3791 pat
->pattern
[i
][j
] = type
;
3794 void do_shockwave(location target
)
3798 start_missile_anim();
3799 for (i
= 0; i
< 6; i
++)
3800 if ((dist(target
,pc_pos
[i
]) > 0) && (dist(target
,pc_pos
[i
]) < 11)
3801 && (adven
[i
].main_status
== 1))
3802 damage_pc(i
, get_ran(2 + dist(target
,pc_pos
[i
]) / 2, 1, 6), 4,-1);
3803 for (i
= 0; i
< T_M
; i
++)
3804 if ((c_town
.monst
.dudes
[i
].active
!= 0) && (dist(target
,c_town
.monst
.dudes
[i
].m_loc
) > 0)
3805 && (dist(target
,c_town
.monst
.dudes
[i
].m_loc
) < 11)
3806 && (can_see(target
,c_town
.monst
.dudes
[i
].m_loc
,0) < 5))
3807 damage_monst(i
, current_pc
, get_ran(2 + dist(target
,c_town
.monst
.dudes
[i
].m_loc
) / 2 , 1, 6), 0, 4);
3808 do_explosion_anim(5,0);
3810 handle_marked_damage();
3813 void radius_damage(location target
,short radius
, short dam
, short type
)////
3818 for (i
= 0; i
< 6; i
++)
3819 if ((dist(target
,c_town
.p_loc
) > 0) && (dist(target
,c_town
.p_loc
) <= radius
)
3820 && (adven
[i
].main_status
== 1))
3821 damage_pc(i
, dam
, type
,-1);
3822 for (i
= 0; i
< T_M
; i
++)
3823 if ((c_town
.monst
.dudes
[i
].active
!= 0) && (dist(target
,c_town
.monst
.dudes
[i
].m_loc
) > 0)
3824 && (dist(target
,c_town
.monst
.dudes
[i
].m_loc
) <= radius
)
3825 && (can_see(target
,c_town
.monst
.dudes
[i
].m_loc
,0) < 5))
3826 damage_monst(i
, current_pc
, dam
, 0, type
);
3830 start_missile_anim();
3831 for (i
= 0; i
< 6; i
++)
3832 if ((dist(target
,pc_pos
[i
]) > 0) && (dist(target
,pc_pos
[i
]) <= radius
)
3833 && (adven
[i
].main_status
== 1))
3834 damage_pc(i
, dam
, type
,-1);
3835 for (i
= 0; i
< T_M
; i
++)
3836 if ((c_town
.monst
.dudes
[i
].active
!= 0) && (dist(target
,c_town
.monst
.dudes
[i
].m_loc
) > 0)
3837 && (dist(target
,c_town
.monst
.dudes
[i
].m_loc
) <= radius
)
3838 && (can_see(target
,c_town
.monst
.dudes
[i
].m_loc
,0) < 5))
3839 damage_monst(i
, current_pc
, dam
, 0, type
);
3840 do_explosion_anim(5,0);
3842 handle_marked_damage();
3845 // Slightly kludgy way to only damage PCs in space)
3846 void hit_pcs_in_space(location target
,short dam
,short type
,short report
,short hit_all
)
3848 //short store_active[T_M],i;
3850 //for (i = 0; i < T_M; i++) {
3851 // store_active[i] = c_town.monst.dudes[i].active;
3852 // c_town.monst.dudes[i].active = 0;
3854 hit_space(target
, dam
,type
, report
, 10 + hit_all
);
3855 //for (i = 0; i < T_M; i++)
3856 // c_town.monst.dudes[i].active = store_active[i];
3859 void hit_space(location target
,short dam
,short type
,short report
,short hit_all
)
3860 //type; // 0 - weapon 1 - fire 2 - poison 3 - general magic 4 - unblockable 5 - cold
3861 // 6 - demon 7 - undead
3862 //short report; // 0 - no 1 - print result
3863 //hit_all; // 0 - nail top thing 1 - hit all in space + 10 ... no monsters
3866 Boolean stop_hitting
= FALSE
,hit_monsters
= TRUE
;
3868 // sprintf ((char *) create_line, " %d %d. ",target.x,target.y);
3869 // add_string_to_buf((char *) create_line);
3870 if ((target
.x
< 0) || (target
.x
> 63) || (target
.y
< 0) || (target
.y
> 63))
3873 if (hit_all
>= 10) {
3874 hit_monsters
= FALSE
;
3878 if ((is_antimagic(target
.x
,target
.y
)) && ((type
== 1) || (type
== 3) || (type
== 5))) {
3883 add_string_to_buf(" No damage.");
3887 for (i
= 0; i
< T_M
; i
++)
3888 if ((hit_monsters
== TRUE
) && (c_town
.monst
.dudes
[i
].active
!= 0) && (stop_hitting
== FALSE
))
3889 if (monst_on_space(target
,i
)) {
3890 if (processing_fields
== TRUE
)
3891 damage_monst(i
, 6, dam
, 0, type
);
3892 else damage_monst(i
, (monsters_going
== TRUE
) ? 7 : current_pc
, dam
, 0, type
);
3893 stop_hitting
= (hit_all
== 1) ? FALSE
: TRUE
;
3896 if (overall_mode
>= 10)
3897 for (i
= 0; i
< 6; i
++)
3898 if ((adven
[i
].main_status
== 1) && (stop_hitting
== FALSE
))
3899 if (same_point(pc_pos
[i
],target
) == TRUE
) {
3900 damage_pc(i
,dam
,type
,-1);
3901 stop_hitting
= (hit_all
== 1) ? FALSE
: TRUE
;
3903 if (overall_mode
< 10)
3904 if (same_point(target
,c_town
.p_loc
) == TRUE
) {
3906 hit_party(dam
,type
);
3908 stop_hitting
= (hit_all
== 1) ? FALSE
: TRUE
;
3911 if ((report
== 1) && (hit_all
== 0) && (stop_hitting
== FALSE
))
3912 add_string_to_buf(" Missed.");
3921 Boolean some_poison
= FALSE
;
3923 for (i
= 0; i
< 6; i
++)
3924 if (adven
[i
].main_status
== 1)
3925 if (adven
[i
].status
[2] > 0)
3927 if (some_poison
== TRUE
) {
3928 add_string_to_buf("Poison: ");
3929 for (i
= 0; i
< 6; i
++)
3930 if (adven
[i
].main_status
== 1)
3931 if (adven
[i
].status
[2] > 0) {
3932 r1
= get_ran(adven
[i
].status
[2],1,6);
3933 damage_pc(i
,r1
,2,-1);
3934 if (get_ran(1,0,8) < 6)
3935 adven
[i
].status
[2] = move_to_zero(adven
[i
].status
[2]);
3936 if (get_ran(1,0,8) < 6)
3937 if (adven
[i
].traits
[6] == TRUE
)
3938 adven
[i
].status
[2] = move_to_zero(adven
[i
].status
[2]);
3941 //if (overall_mode < 10)
3942 // boom_space(party.p_loc,overall_mode,2,r1);
3947 void handle_disease()
3950 Boolean disease
= FALSE
;
3952 for (i
= 0; i
< 6; i
++)
3953 if (adven
[i
].main_status
== 1)
3954 if (adven
[i
].status
[7] > 0)
3957 if (disease
== TRUE
) {
3958 add_string_to_buf("Disease: ");
3959 for (i
= 0; i
< 6; i
++)
3960 if (adven
[i
].main_status
== 1)
3961 if (adven
[i
].status
[7] > 0) {
3962 r1
= get_ran(1,1,10);
3980 sprintf ((char *) create_line
, " %s unaffected. ",
3981 (char *) adven
[i
].name
);
3982 add_string_to_buf((char *) create_line
);
3985 r1
= get_ran(1,0,7);
3986 if (adven
[i
].traits
[6] == TRUE
)
3988 if ((get_ran(1,0,7) <= 0) || (pc_has_abil_equip(i
,67) < 24))
3989 adven
[i
].status
[7] = move_to_zero(adven
[i
].status
[7]);
3998 Boolean some_acid
= FALSE
;
4000 for (i
= 0; i
< 6; i
++)
4001 if (adven
[i
].main_status
== 1)
4002 if (adven
[i
].status
[13] > 0)
4005 if (some_acid
== TRUE
) {
4006 add_string_to_buf("Acid: ");
4007 for (i
= 0; i
< 6; i
++)
4008 if (adven
[i
].main_status
== 1)
4009 if (adven
[i
].status
[13] > 0) {
4010 r1
= get_ran(adven
[i
].status
[13],1,6);
4011 damage_pc(i
,r1
,3,-1);
4012 adven
[i
].status
[13] = move_to_zero(adven
[i
].status
[13]);
4014 if (overall_mode
< 10)
4015 boom_space(party
.p_loc
,overall_mode
,3,r1
,8);
4019 Boolean
no_pcs_left()
4024 if (adven
[i
].main_status
== 1)
4032 Boolean
hit_end_c_button()
4034 Boolean end_ok
= TRUE
;
4037 if (which_combat_type
== 0) {
4038 end_ok
= out_monst_all_dead();
4040 // if (adven[0].extra[7] > 0)
4048 Boolean
out_monst_all_dead()
4052 for (i
= 0; i
< T_M
; i
++)
4053 if ((c_town
.monst
.dudes
[i
].active
> 0) && (c_town
.monst
.dudes
[i
].attitude
% 2 == 1))
4062 for (i
= 0; i
< 6; i
++) {
4063 if (adven
[i
].main_status
== 5)
4064 adven
[i
].main_status
= 1;
4065 adven
[i
].status
[0] = 0;
4066 adven
[i
].status
[1] = 0;
4067 adven
[i
].status
[3] = 0;
4069 if (which_combat_type
== 0) {
4071 load_area_graphics();
4073 combat_active_pc
= 6;
4074 current_pc
= store_current_pc
;
4075 if (adven
[current_pc
].main_status
!= 1)
4076 current_pc
= first_active_pc();
4077 put_item_screen(stat_window
,0);
4082 Boolean
combat_cast_mage_spell()
4084 short spell_num
,target
,i
,store_sp
,bonus
= 1,r1
,store_sound
= 0,store_m_type
= 0,num_opp
= 0;
4086 creature_data_type
*which_m
;
4087 monster_record_type get_monst
;
4089 if (is_antimagic(pc_pos
[current_pc
].x
,pc_pos
[current_pc
].y
)) {
4090 add_string_to_buf(" Not in antimagic field.");
4093 store_sp
= adven
[current_pc
].cur_sp
;
4094 if (adven
[current_pc
].cur_sp
== 0)
4095 add_string_to_buf("Cast: No spell points. ");
4096 else if (adven
[current_pc
].skills
[9] == 0)
4097 add_string_to_buf("Cast: No mage skill. ");
4098 else if (get_encumberance(current_pc
) > 1) {
4099 add_string_to_buf("Cast: Too encumbered. ");
4107 if (spell_forced
== FALSE
)
4108 spell_num
= pick_spell(current_pc
,0,2);
4110 if (repeat_cast_ok(0) == FALSE
)
4112 spell_num
= pc_last_cast
[0][current_pc
];
4115 if (spell_num
== 35) {
4116 store_sum_monst
= pick_trapped_monst();
4117 if (store_sum_monst
== 0)
4119 get_monst
= return_monster_template(store_sum_monst
);
4120 if (store_sp
< get_monst
.level
) {
4121 add_string_to_buf("Cast: Not enough spell points. ");
4124 store_sum_monst_cost
= get_monst
.level
;
4127 bonus
= stat_adj(current_pc
,2);
4128 combat_posing_monster
= current_working_monster
= current_pc
;
4129 if (spell_num
>= 70)
4131 if (spell_num
< 70) {
4132 print_spell_cast(spell_num
,0);
4133 if (refer_mage
[spell_num
] == 0) {
4136 do_mage_spell(current_pc
,spell_num
);
4137 combat_posing_monster
= current_working_monster
= -1;
4139 else if (refer_mage
[spell_num
] == 2) {
4140 start_spell_targeting(spell_num
);
4142 else if (refer_mage
[spell_num
] == 3) {
4143 start_fancy_spell_targeting(spell_num
);
4146 start_missile_anim();
4149 switch (spell_num
) {
4151 adven
[current_pc
].cur_sp
-= s_cost
[0][spell_num
];
4152 add_string_to_buf(" The ground shakes. ");
4153 do_shockwave(pc_pos
[current_pc
]);
4156 case 2: case 21: case 3: case 14: case 29:
4157 // target = select_pc(11,0);
4158 target
= store_spell_target
;
4160 adven
[current_pc
].cur_sp
-= s_cost
[0][spell_num
];
4162 switch (spell_num
) {
4164 sprintf ((char *) c_line
, " %s receives venom. ",
4165 (char *) adven
[target
].name
);
4166 poison_weapon(target
,3 + bonus
,1);
4171 sprintf ((char *) c_line
, " %s stronger. ",
4172 (char *) adven
[target
].name
);
4173 adven
[target
].status
[1] = adven
[target
].status
[1] + 3;
4177 sprintf ((char *) c_line
, " %s resistant. ",
4178 (char *) adven
[target
].name
);
4179 adven
[target
].status
[5] = adven
[target
].status
[5] + 5 + bonus
;
4184 i
= (spell_num
== 2) ? 2 : max(2,adven
[current_pc
].level
/ 2 + bonus
);
4185 adven
[target
].status
[3] = min(8,
4186 adven
[target
].status
[3] + i
);
4187 sprintf ((char *) c_line
, " %s hasted. ",
4188 (char *) adven
[target
].name
);
4192 add_string_to_buf((char *) c_line
);
4193 add_missile(pc_pos
[target
],store_m_type
,0,0,0);
4199 adven
[current_pc
].cur_sp
-= s_cost
[0][spell_num
];
4202 for (i
= 0; i
< 6; i
++)
4203 if (adven
[i
].main_status
== 1) {
4204 adven
[i
].status
[3] = min(8,
4205 adven
[i
].status
[3] + ((spell_num
== 39) ? 1 + adven
[current_pc
].level
/ 8 + bonus
: 3 + bonus
));
4206 if (spell_num
== 55) {
4207 poison_weapon(i
,2,1);
4208 adven
[i
].status
[1] += 4;
4209 add_missile(pc_pos
[i
],14,0,0,0);
4211 else add_missile(pc_pos
[i
],8,0,0,0);
4214 if (spell_num
== 39)
4215 sprintf ((char *) c_line
, " Party hasted. ");
4217 sprintf ((char *) c_line
, " Party blessed! ");
4218 add_string_to_buf((char *) c_line
);
4224 case 32: case 47: case 56: // affect monsters in area spells
4225 adven
[current_pc
].cur_sp
-= s_cost
[0][spell_num
];
4227 if (spell_num
== 47)
4229 switch (spell_num
) {
4230 case 32: sprintf ((char *) c_line
, " Enemy slowed: "); break;
4231 case 49: sprintf ((char *) c_line
, " Enemy ravaged: ");break;
4232 case 47: sprintf ((char *) c_line
, " Enemy scared: ");break;
4233 case 56: sprintf ((char *) c_line
, " Enemy paralyzed: ");break;
4235 add_string_to_buf((char *) c_line
);
4236 for (i
= 0; i
< T_M
; i
++) {
4237 if ((c_town
.monst
.dudes
[i
].active
!= 0) && (c_town
.monst
.dudes
[i
].attitude
% 2 == 1)
4238 && (dist(pc_pos
[current_pc
],c_town
.monst
.dudes
[i
].m_loc
) <= mage_range
[spell_num
])
4239 && (can_see(pc_pos
[current_pc
],c_town
.monst
.dudes
[i
].m_loc
,0) < 5)) {
4240 which_m
= &c_town
.monst
.dudes
[i
];
4241 switch (spell_num
) {
4243 r1
= get_ran(adven
[current_pc
].level
/ 3,1,8);
4244 scare_monst(which_m
,r1
);
4248 slow_monst(which_m
,5 + bonus
);
4249 if (spell_num
== 49)
4250 curse_monst(which_m
,3 + bonus
);
4254 charm_monst(which_m
,15,12,1000);
4259 add_missile(c_town
.monst
.dudes
[i
].m_loc
,store_m_type
,0,
4260 14 * (which_m
->m_d
.x_width
- 1),18 * (which_m
->m_d
.y_width
- 1));
4270 do_missile_anim((num_opp
< 5) ? 50 : 25,pc_pos
[current_pc
],store_sound
);
4271 else play_sound(store_sound
);
4277 combat_posing_monster
= current_working_monster
= -1;
4278 // Did anything actually get cast?
4279 if (store_sp
== adven
[current_pc
].cur_sp
)
4285 Boolean
combat_cast_priest_spell()
4287 short spell_num
,target
,i
,store_sp
,bonus
,store_sound
= 0,store_m_type
= 0,num_opp
= 0;
4289 creature_data_type
*which_m
;
4290 effect_pat_type protect_pat
= {{{0,4,4,4,4,4,4,4,0},
4291 {4,8,8,8,8,8,8,8,4},
4292 {4,8,9,9,9,9,9,8,4},
4293 {4,8,9,6,6,6,9,8,4},
4294 {4,8,9,6,6,6,9,8,4},
4295 {4,8,9,6,6,6,9,8,4},
4296 {4,8,9,9,9,9,9,8,4},
4297 {4,8,8,8,8,8,8,8,4},
4298 {0,4,4,4,4,4,4,4,0}}};
4300 if (is_antimagic(pc_pos
[current_pc
].x
,pc_pos
[current_pc
].y
)) {
4301 add_string_to_buf(" Not in antimagic field.");
4304 if (spell_forced
== FALSE
)
4305 spell_num
= pick_spell(current_pc
,1,2);
4307 if (repeat_cast_ok(1) == FALSE
)
4309 spell_num
= pc_last_cast
[1][current_pc
];
4312 store_sp
= adven
[current_pc
].cur_sp
;
4314 if (spell_num
>= 70)
4316 bonus
= stat_adj(current_pc
,2);
4318 combat_posing_monster
= current_working_monster
= current_pc
;
4320 if (adven
[current_pc
].cur_sp
== 0)
4321 add_string_to_buf("Cast: No spell points. ");
4322 else if (spell_num
< 70) {
4323 print_spell_cast(spell_num
,1);
4324 if (refer_priest
[spell_num
] == 0) {
4327 do_priest_spell(current_pc
,spell_num
);
4329 else if (refer_priest
[spell_num
] == 2) {
4330 start_spell_targeting(100 + spell_num
);
4332 else if (refer_priest
[spell_num
] == 3) {
4333 start_fancy_spell_targeting(100 + spell_num
);
4336 start_missile_anim();
4339 switch (spell_num
) {
4341 // target = select_pc(11,0);
4342 target
= store_spell_target
;
4345 adven
[current_pc
].cur_sp
-= s_cost
[1][spell_num
];
4346 adven
[target
].status
[1] += (spell_num
== 0) ? 2 :
4347 max(2,(adven
[current_pc
].level
* 3) / 4 + 1 + bonus
);
4348 sprintf ((char *) c_line
, " %s blessed. ",
4349 (char *) adven
[target
].name
);
4350 add_string_to_buf((char *) c_line
);
4351 add_missile(pc_pos
[target
],8,0,0,0);
4356 adven
[current_pc
].cur_sp
-= s_cost
[1][spell_num
];
4357 for (i
= 0; i
< 6; i
++)
4358 if (adven
[i
].main_status
== 1) {
4359 adven
[i
].status
[1] += adven
[current_pc
].level
/ 3;
4360 add_missile(pc_pos
[i
],8,0,0,0);
4362 sprintf ((char *) c_line
, " Party blessed. ");
4363 add_string_to_buf((char *) c_line
);
4368 adven
[current_pc
].cur_sp
-= s_cost
[1][spell_num
];
4369 sprintf ((char *) c_line
, " %s is an avatar! ",
4370 (char *) adven
[current_pc
].name
);
4371 add_string_to_buf((char *) c_line
);
4372 heal_pc(current_pc
,200);
4373 cure_pc(current_pc
,8);
4374 adven
[current_pc
].status
[1] = 8;
4375 adven
[current_pc
].status
[3] = 8;
4376 adven
[current_pc
].status
[4] = 3;
4377 adven
[current_pc
].status
[5] = 8;
4378 adven
[current_pc
].status
[6] = 0;
4379 adven
[current_pc
].status
[7] = 0;
4380 adven
[current_pc
].status
[9] = 0;
4381 adven
[current_pc
].status
[10] = 8;
4384 case 31: case 51: case 53:
4385 adven
[current_pc
].cur_sp
-= s_cost
[1][spell_num
];
4387 for (i
= 0; i
< T_M
; i
++) {
4388 if ((c_town
.monst
.dudes
[i
].active
!= 0) &&(c_town
.monst
.dudes
[i
].attitude
% 2 == 1) &&
4389 (dist(pc_pos
[current_pc
],c_town
.monst
.dudes
[i
].m_loc
) <= priest_range
[spell_num
])) {
4390 which_m
= &c_town
.monst
.dudes
[i
];
4391 switch (spell_num
) {
4393 curse_monst(which_m
,3 + bonus
);
4397 charm_monst(which_m
,28 - bonus
,0,0);
4401 disease_monst(which_m
,3 + bonus
);
4406 add_missile(c_town
.monst
.dudes
[i
].m_loc
,store_m_type
,0,
4407 14 * (which_m
->m_d
.x_width
- 1),18 * (which_m
->m_d
.y_width
- 1));
4414 adven
[current_pc
].cur_sp
-= s_cost
[1][spell_num
];
4416 add_string_to_buf(" Protective field created.");
4417 place_spell_pattern(protect_pat
,pc_pos
[current_pc
],0,FALSE
,6);
4422 do_missile_anim((num_opp
< 5) ? 50 : 25,pc_pos
[current_pc
],store_sound
);
4423 else play_sound(store_sound
);
4428 combat_posing_monster
= current_working_monster
= -1;
4429 // Did anything actually get cast?
4430 if (store_sp
== adven
[current_pc
].cur_sp
)
4435 void start_spell_targeting(short num
)
4438 // First, remember what spell was cast.
4439 spell_being_cast
= num
;
4441 // Then, is num >= 1000, it's a freebie, so remove the 1000
4444 sprintf ((char *) create_line
, " Target spell. ");
4445 add_string_to_buf((char *) create_line
);
4447 add_string_to_buf(" (Hit 'm' to cancel.)");
4448 else add_string_to_buf(" (Hit 'p' to cancel.)");
4450 current_spell_range
= (num
>= 100) ? priest_range
[num
- 100] : mage_range
[num
];
4451 current_pat
= single
;
4453 switch (num
) { // Different spells have different messages and diff. target shapes
4455 current_pat
= small_square
;
4457 case 18: case 22: case 141: case 126: case 15: case 119:
4458 current_pat
= square
;
4460 case 17: case 40: case 44: case 28: case 51: case 157: case 145: case 64: case 67:
4463 case 153: case 65: case 66:
4466 case 25: case 37: case 159:
4467 add_string_to_buf(" (Hit space to rotate.)");
4468 force_wall_position
= 0;
4469 current_pat
= field
[0];
4474 void start_fancy_spell_targeting(short num
)
4477 location null_loc
= {120,0};
4479 // First, remember what spell was cast.
4480 spell_being_cast
= num
;
4481 // Then, is num >= 1000, it's a freebie, so remove the 1000
4485 for (i
= 0; i
< 8; i
++)
4486 spell_targets
[i
] = null_loc
;
4487 sprintf ((char *) create_line
, " Target spell. ");
4489 add_string_to_buf(" (Hit 'm' to cancel.)");
4490 else add_string_to_buf(" (Hit 'p' to cancel.)");
4491 add_string_to_buf(" (Hit space to cast.)");
4492 add_string_to_buf((char *) create_line
);
4494 current_pat
= single
;
4495 current_spell_range
= (num
>= 100) ? priest_range
[num
- 100] : mage_range
[num
];
4497 switch (num
) { // Assign special targeting shapes and number of targets
4499 num_targets_left
= minmax(1,8,adven
[current_pc
].level
/ 4 + stat_adj(current_pc
,2) / 2);
4501 case 134: // sticks to snakes
4502 num_targets_left
= adven
[current_pc
].level
/ 5 + stat_adj(current_pc
,2) / 2;
4504 case 143: // summon host
4505 num_targets_left
= 5;
4507 case 27: // flame arrows
4508 num_targets_left
= adven
[current_pc
].level
/ 4 + stat_adj(current_pc
,2) / 2;
4510 case 36: // venom arrows
4511 num_targets_left
= adven
[current_pc
].level
/ 5 + stat_adj(current_pc
,2) / 2;
4513 case 61: case 49: // paralysis, death arrows
4514 num_targets_left
= adven
[current_pc
].level
/ 8 + stat_adj(current_pc
,2) / 3;
4516 case 45: // spray fields
4517 num_targets_left
= adven
[current_pc
].level
/ 5 + stat_adj(current_pc
,2) / 2;
4520 case 26: // summon 1
4521 num_targets_left
= minmax(1,7,adven
[current_pc
].level
/ 4 + stat_adj(current_pc
,2) / 2);
4523 case 43: // summon 2
4524 num_targets_left
= minmax(1,6,adven
[current_pc
].level
/ 6 + stat_adj(current_pc
,2) / 2);
4526 case 58: // summon 3
4527 num_targets_left
= minmax(1,5,adven
[current_pc
].level
/ 8 + stat_adj(current_pc
,2) / 2);
4531 num_targets_left
= minmax(1,8,num_targets_left
);
4534 void spell_cast_hit_return()
4536 location null_loc
= {0,0};
4538 if (force_wall_position
< 10) {
4539 force_wall_position
= (force_wall_position
+ 1) % 8;
4540 current_pat
= field
[force_wall_position
];
4544 void process_fields()
4555 r
= c_town
.town
.in_town_rect
;
4556 for (i
= 0; i
< town_size
[town_type
]; i
++)
4557 for (j
= 0; j
< town_size
[town_type
]; j
++)
4558 qf
[i
][j
] = (is_quickfire(i
,j
)) ? 2 : 0;
4559 for (k
= 0; k
< ((is_combat()) ? 4 : 1); k
++) {
4560 for (i
= r
.left
+ 1; i
< r
.right
; i
++)
4561 for (j
= r
.top
+ 1; j
< r
.bottom
; j
++)
4562 if (is_quickfire(i
,j
) > 0) {
4563 r1
= get_ran(1,1,8);
4571 for (i
= r
.left
+ 1; i
< r
.right
; i
++)
4572 for (j
= r
.top
+ 1; j
< r
.bottom
; j
++)
4574 make_quickfire(i
,j
);
4579 for (i
= 0; i
< T_M
; i
++)
4580 if (c_town
.monst
.dudes
[i
].active
> 0)
4581 monst_inflict_fields(i
);
4583 // First fry PCs, then call to handle damage to monsters
4584 processing_fields
= TRUE
; // this, in hit_space, makes damage considered to come from whole party
4587 for (i
= 0; i
< town_size
[town_type
]; i
++)
4588 for (j
= 0; j
< town_size
[town_type
]; j
++)
4589 if (is_force_wall(i
,j
)) {
4590 r1
= get_ran(3,1,6);
4591 loc
.x
= i
; loc
.y
= j
;
4592 hit_pcs_in_space(loc
,r1
,3,1,1);
4593 r1
= get_ran(1,1,6);
4595 take_force_wall(i
,j
);
4603 for (i
= 0; i
< town_size
[town_type
]; i
++)
4604 for (j
= 0; j
< town_size
[town_type
]; j
++)
4605 if (is_fire_wall(i
,j
)) {
4606 loc
.x
= i
; loc
.y
= j
;
4607 r1
= get_ran(2,1,6) + 1;
4608 hit_pcs_in_space(loc
,r1
,1,1,1);
4609 r1
= get_ran(1,1,4);
4611 take_fire_wall(i
,j
);
4619 for (i
= 0; i
< town_size
[town_type
]; i
++)
4620 for (j
= 0; j
< town_size
[town_type
]; j
++)
4621 if (is_antimagic(i
,j
)) {
4622 r1
= get_ran(1,1,8);
4624 take_antimagic(i
,j
);
4625 else antimagic
= TRUE
;
4630 for (i
= 0; i
< town_size
[town_type
]; i
++)
4631 for (j
= 0; j
< town_size
[town_type
]; j
++)
4632 if (is_scloud(i
,j
)) {
4633 r1
= get_ran(1,1,4);
4643 sleep_field
= FALSE
;
4644 for (i
= 0; i
< town_size
[town_type
]; i
++)
4645 for (j
= 0; j
< town_size
[town_type
]; j
++)
4646 if (is_sleep_cloud(i
,j
)) {
4647 r1
= get_ran(1,1,4);
4649 take_sleep_cloud(i
,j
);
4651 sleep_cloud_space(i
,j
);
4658 for (i
= 0; i
< town_size
[town_type
]; i
++)
4659 for (j
= 0; j
< town_size
[town_type
]; j
++)
4660 if (is_ice_wall(i
,j
)) {
4661 loc
.x
= i
; loc
.y
= j
;
4662 r1
= get_ran(3,1,6);
4663 hit_pcs_in_space(loc
,r1
,5,1,1);
4664 r1
= get_ran(1,1,6);
4674 for (i
= 0; i
< town_size
[town_type
]; i
++)
4675 for (j
= 0; j
< town_size
[town_type
]; j
++)
4676 if (is_blade_wall(i
,j
)) {
4677 loc
.x
= i
; loc
.y
= j
;
4678 r1
= get_ran(6,1,8);
4679 hit_pcs_in_space(loc
,r1
,0,1,1);
4680 r1
= get_ran(1,1,5);
4682 take_blade_wall(i
,j
);
4689 processing_fields
= FALSE
;
4690 monsters_going
= TRUE
; // this changes who the damage is considered to come from
4694 for (i
= 0; i
< town_size
[town_type
]; i
++)
4695 for (j
= 0; j
< town_size
[town_type
]; j
++)
4696 if (is_quickfire(i
,j
)) {
4697 loc
.x
= i
; loc
.y
= j
;
4698 r1
= get_ran(2,1,8);
4699 hit_pcs_in_space(loc
,r1
,1,1,1);
4703 monsters_going
= FALSE
;
4706 void scloud_space(short m
,short n
)
4709 creature_data_type
*which_m
;
4712 target
.x
= (char) m
;
4713 target
.y
= (char) n
;
4717 if (overall_mode
>= 10)
4718 for (i
= 0; i
< 6; i
++)
4719 if (adven
[i
].main_status
== 1)
4720 if (same_point(pc_pos
[i
],target
) == TRUE
) {
4721 curse_pc(i
,get_ran(1,1,2));
4723 if (overall_mode
< 10)
4724 if (same_point(target
,c_town
.p_loc
) == TRUE
) {
4725 for (i
= 0; i
< 6; i
++)
4726 if (adven
[i
].main_status
== 1)
4727 curse_pc(i
,get_ran(1,1,2));
4731 void web_space(short m
,short n
)
4734 creature_data_type
*which_m
;
4737 target
.x
= (char) m
;
4738 target
.y
= (char) n
;
4742 if (overall_mode
>= 10)
4743 for (i
= 0; i
< 6; i
++)
4744 if (adven
[i
].main_status
== 1)
4745 if (same_point(pc_pos
[i
],target
) == TRUE
) {
4748 if (overall_mode
< 10)
4749 if (same_point(target
,c_town
.p_loc
) == TRUE
) {
4750 for (i
= 0; i
< 6; i
++)
4754 void sleep_cloud_space(short m
,short n
)
4757 creature_data_type
*which_m
;
4760 target
.x
= (char) m
;
4761 target
.y
= (char) n
;
4763 make_sleep_cloud(m
,n
);
4765 if (overall_mode
>= 10)
4766 for (i
= 0; i
< 6; i
++)
4767 if (adven
[i
].main_status
== 1)
4768 if (same_point(pc_pos
[i
],target
) == TRUE
) {
4771 if (overall_mode
< 10)
4772 if (same_point(target
,c_town
.p_loc
) == TRUE
) {
4773 for (i
= 0; i
< 6; i
++)
4779 void take_m_ap(short num
,creature_data_type
*monst
)
4781 monst
->m_d
.ap
= max(0,monst
->m_d
.ap
- num
);
4784 void add_new_action(short pc_num
)
4790 short get_monst_sound(creature_data_type
*attacker
,short which_att
) {
4791 short type
,strength
,i
;
4793 type
= (which_att
== 0) ? attacker
->m_d
.a1_type
: attacker
->m_d
.a23_type
;
4794 strength
= attacker
->m_d
.a
[which_att
];
4811 if (attacker
->m_d
.m_type
== 0) {
4816 if ((attacker
->m_d
.m_type
== 0) ||(attacker
->m_d
.m_type
== 6) ||(attacker
->m_d
.m_type
== 9) ){
4819 if (attacker
->m_d
.m_type
== 4)
4821 if (attacker
->m_d
.m_type
== 5)