ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/pets.C
(Generate patch)

Comparing deliantra/server/server/pets.C (file contents):
Revision 1.1 by elmex, Sun Aug 13 17:16:04 2006 UTC vs.
Revision 1.9 by root, Thu Sep 14 22:34:04 2006 UTC

1/*
2 * static char *rcsid_pets_c =
3 * "$Id: pets.C,v 1.1 2006/08/13 17:16:04 elmex Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
21 16
22 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 20
26 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
27*/ 22*/
28 23
29#include <global.h> 24#include <global.h>
30#ifndef __CEXTRACT__ 25#ifndef __CEXTRACT__
31#include <sproto.h> 26# include <sproto.h>
32#endif 27#endif
33 28
34/* given that 'pet' is a friendly object, this function returns a 29/* given that 'pet' is a friendly object, this function returns a
35 * monster the pet should attack, NULL if nothing appropriate is 30 * monster the pet should attack, NULL if nothing appropriate is
36 * found. it basically looks for nasty things around the owner 31 * found. it basically looks for nasty things around the owner
37 * of the pet to attack. 32 * of the pet to attack.
38 * this is now tilemap aware. 33 * this is now tilemap aware.
39 */ 34 */
40 35
36object *
41object *get_pet_enemy(object * pet, rv_vector *rv){ 37get_pet_enemy (object *pet, rv_vector * rv)
38{
42 object *owner, *tmp, *attacker, *tmp3; 39 object *owner, *tmp, *attacker, *tmp3;
43 int i; 40 int i;
44 sint16 x,y; 41 sint16 x, y;
45 mapstruct *nm; 42 mapstruct *nm;
46 int search_arr[SIZEOFFREE]; 43 int search_arr[SIZEOFFREE];
47 int mflags; 44 int mflags;
48 45
49 attacker = pet->attacked_by; /*pointer to attacking enemy*/ 46 attacker = pet->attacked_by; /*pointer to attacking enemy */
50 pet->attacked_by = NULL; /*clear this, since we are dealing with it*/ 47 pet->attacked_by = NULL; /*clear this, since we are dealing with it */
51 48
52 if ((owner = get_owner(pet)) != NULL) { 49 if ((owner = get_owner (pet)) != NULL)
50 {
53 /* If the owner has turned on the pet, make the pet 51 /* If the owner has turned on the pet, make the pet
54 * unfriendly. 52 * unfriendly.
55 */ 53 */
56 if ((check_enemy(owner,rv)) == pet) { 54 if ((check_enemy (owner, rv)) == pet)
55 {
56 CLEAR_FLAG (pet, FLAG_FRIENDLY);
57 remove_friendly_object (pet);
58 pet->attack_movement &= ~PETMOVE;
59 return owner;
60 }
61 }
62 else
63 {
64 /* else the owner is no longer around, so the
65 * pet no longer needs to be friendly.
66 */
57 CLEAR_FLAG(pet, FLAG_FRIENDLY); 67 CLEAR_FLAG (pet, FLAG_FRIENDLY);
58 remove_friendly_object(pet); 68 remove_friendly_object (pet);
59 pet->attack_movement &=~PETMOVE; 69 pet->attack_movement &= ~PETMOVE;
60 return owner;
61 }
62 } else {
63 /* else the owner is no longer around, so the
64 * pet no longer needs to be friendly.
65 */
66 CLEAR_FLAG(pet, FLAG_FRIENDLY);
67 remove_friendly_object(pet);
68 pet->attack_movement &=~PETMOVE;
69 return NULL; 70 return NULL;
70 } 71 }
71 /* If they are not on the same map, the pet won't be agressive */ 72 /* If they are not on the same map, the pet won't be agressive */
72 if (!on_same_map(pet,owner)) 73 if (!on_same_map (pet, owner))
73 return NULL; 74 return NULL;
74 75
75 /* See if the pet has an existing enemy. If so, don't start a new one*/ 76 /* See if the pet has an existing enemy. If so, don't start a new one */
76 if((tmp=check_enemy(pet, rv))!=NULL) 77 if ((tmp = check_enemy (pet, rv)) != NULL)
77 { 78 {
78 if(tmp == owner && !QUERY_FLAG(pet,FLAG_CONFUSED) 79 if (tmp == owner && !QUERY_FLAG (pet, FLAG_CONFUSED) && QUERY_FLAG (pet, FLAG_FRIENDLY))
79 && QUERY_FLAG(pet,FLAG_FRIENDLY))
80 /* without this check, you can actually get pets with 80 /* without this check, you can actually get pets with
81 * enemy set to owner! 81 * enemy set to owner!
82 */
83 pet->enemy = NULL;
84 else
85 return tmp;
86 }
87 get_search_arr (search_arr);
88
89 if (owner->type == PLAYER && owner->contr->petmode > pet_normal)
90 {
91 if (owner->contr->petmode == pet_sad)
92 {
93 tmp = find_nearest_living_creature (pet);
94 if (tmp != NULL)
95 {
96 get_rangevector (pet, tmp, rv, 0);
97 if (check_enemy (pet, rv) != NULL)
98 return tmp;
99 else
100 pet->enemy = NULL;
101 }
102 /* if we got here we have no enemy */
103 /* we return NULL to avoid heading back to the owner */
104 pet->enemy = NULL;
105 return NULL;
106 }
107 }
108
109 /* Since the pet has no existing enemy, look for anything nasty
110 * around the owner that it should go and attack.
82 */ 111 */
112 tmp3 = NULL;
113 for (i = 0; i < SIZEOFFREE; i++)
114 {
115 x = owner->x + freearr_x[search_arr[i]];
116 y = owner->y + freearr_y[search_arr[i]];
117 nm = owner->map;
118 /* Only look on the space if there is something alive there. */
119 mflags = get_map_flags (nm, &nm, x, y, &x, &y);
120 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE)
121 {
122 for (tmp = get_map_ob (nm, x, y); tmp != NULL; tmp = tmp->above)
123 {
124 object *tmp2 = tmp->head == NULL ? tmp : tmp->head;
125
126 if (QUERY_FLAG (tmp2, FLAG_ALIVE) && ((!QUERY_FLAG (tmp2, FLAG_FRIENDLY) &&
127 (tmp2->type != PLAYER)) ||
128 should_arena_attack (pet, owner, tmp2))
129 && !QUERY_FLAG (tmp2, FLAG_UNAGGRESSIVE) && tmp2 != pet && tmp2 != owner && can_detect_enemy (pet, tmp2, rv))
130 {
131
132 if (!can_see_enemy (pet, tmp2))
133 {
134 if (tmp3 != NULL)
135 tmp3 = tmp2;
136 }
137 else
138 {
139 pet->enemy = tmp2;
140 if (check_enemy (pet, rv) != NULL)
141 return tmp2;
142 else
143 pet->enemy = NULL;
144 }
145 } /* if this is a valid enemy */
146 } /* for objects on this space */
147 } /* if there is something living on this space */
148 } /* for loop of spaces around the owner */
149
150 /* fine, we went through the whole loop and didn't find one we could
151 see, take what we have */
152 if (tmp3 != NULL)
153 {
154 pet->enemy = tmp3;
155 if (check_enemy (pet, rv) != NULL)
156 return tmp3;
157 else
158 pet->enemy = NULL;
159 }
160
161 /* No threat to owner, check to see if the pet has an attacker */
162 if (attacker)
163 {
164 /* also need to check to make sure it is not freindly */
165 /* or otherwise non-hostile, and is an appropriate target */
166 if (!QUERY_FLAG (attacker, FLAG_FRIENDLY) && on_same_map (pet, attacker))
167 {
168 pet->enemy = attacker;
169
170 if (check_enemy (pet, rv) != NULL)
171 return attacker;
172 else
83 pet->enemy = NULL; 173 pet->enemy = NULL;
84 else 174 }
85 return tmp;
86 }
87 get_search_arr(search_arr);
88
89 if (owner->type == PLAYER && owner->contr->petmode > pet_normal) {
90 if (owner->contr->petmode == pet_sad) {
91 tmp = find_nearest_living_creature(pet);
92 if (tmp != NULL) {
93 get_rangevector(pet, tmp, rv, 0);
94 if(check_enemy(pet, rv) != NULL)
95 return tmp;
96 else
97 pet->enemy = NULL;
98 } 175 }
99 /* if we got here we have no enemy */
100 /* we return NULL to avoid heading back to the owner */
101 pet->enemy = NULL;
102 return NULL;
103 }
104 }
105 176
106 /* Since the pet has no existing enemy, look for anything nasty
107 * around the owner that it should go and attack.
108 */
109 tmp3 = NULL;
110 for (i = 0; i < SIZEOFFREE; i++) {
111 x = owner->x + freearr_x[search_arr[i]];
112 y = owner->y + freearr_y[search_arr[i]];
113 nm = owner->map;
114 /* Only look on the space if there is something alive there. */
115 mflags = get_map_flags(nm, &nm, x, y, &x, &y);
116 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) {
117 for (tmp = get_map_ob(nm, x, y); tmp != NULL; tmp = tmp->above) {
118 object *tmp2 = tmp->head == NULL?tmp:tmp->head;
119
120 if (QUERY_FLAG(tmp2,FLAG_ALIVE) && ((
121 !QUERY_FLAG(tmp2, FLAG_FRIENDLY) &&
122 (tmp2->type != PLAYER)) ||
123 should_arena_attack(pet, owner, tmp2))
124 && !QUERY_FLAG(tmp2,FLAG_UNAGGRESSIVE) &&
125 tmp2 != pet && tmp2 != owner &&
126 can_detect_enemy(pet, tmp2, rv)) {
127
128 if (!can_see_enemy(pet, tmp2)) {
129 if (tmp3 != NULL)
130 tmp3 = tmp2;
131 } else {
132 pet->enemy = tmp2;
133 if(check_enemy(pet, rv)!=NULL)
134 return tmp2;
135 else
136 pet->enemy = NULL;
137 }
138 }/* if this is a valid enemy */
139 }/* for objects on this space */
140 }/* if there is something living on this space */
141 } /* for loop of spaces around the owner */
142
143 /* fine, we went through the whole loop and didn't find one we could
144 see, take what we have */
145 if (tmp3 != NULL) {
146 pet->enemy = tmp3;
147 if (check_enemy(pet, rv) != NULL)
148 return tmp3;
149 else
150 pet->enemy = NULL;
151 }
152
153 /* No threat to owner, check to see if the pet has an attacker*/
154 if (attacker)
155 {
156 /* need to be sure this is the right one! */
157 if (attacker->count == pet->attacked_by_count)
158 {
159 /* also need to check to make sure it is not freindly */
160 /* or otherwise non-hostile, and is an appropriate target */
161 if (!QUERY_FLAG(attacker, FLAG_FRIENDLY) && on_same_map(pet, attacker))
162 {
163 pet->enemy = attacker;
164 if (check_enemy(pet, rv) != NULL)
165 return attacker;
166 else
167 pet->enemy = NULL;
168 }
169 }
170 }
171
172 /* Don't have an attacker or legal enemy, so look for a new one!. 177 /* Don't have an attacker or legal enemy, so look for a new one!.
173 * This looks for one around where the pet is. Thus, you could lead 178 * This looks for one around where the pet is. Thus, you could lead
174 * a pet to danger, then take a few steps back. This code is basically 179 * a pet to danger, then take a few steps back. This code is basically
175 * the same as the code that looks around the owner. 180 * the same as the code that looks around the owner.
176 */ 181 */
177 if (owner->type == PLAYER && owner->contr->petmode != pet_defend) { 182 if (owner->type == PLAYER && owner->contr->petmode != pet_defend)
183 {
178 tmp3 = NULL; 184 tmp3 = NULL;
179 for (i = 0; i < SIZEOFFREE; i++) { 185 for (i = 0; i < SIZEOFFREE; i++)
186 {
180 x = pet->x + freearr_x[search_arr[i]]; 187 x = pet->x + freearr_x[search_arr[i]];
181 y = pet->y + freearr_y[search_arr[i]]; 188 y = pet->y + freearr_y[search_arr[i]];
182 nm = pet->map; 189 nm = pet->map;
183 /* Only look on the space if there is something alive there. */ 190 /* Only look on the space if there is something alive there. */
184 mflags = get_map_flags(nm, &nm, x,y, &x, &y); 191 mflags = get_map_flags (nm, &nm, x, y, &x, &y);
185 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) { 192 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE)
193 {
186 for (tmp = get_map_ob(nm, x, y); tmp != NULL; tmp = tmp->above) { 194 for (tmp = get_map_ob (nm, x, y); tmp != NULL; tmp = tmp->above)
195 {
187 object *tmp2 = tmp->head == NULL?tmp:tmp->head; 196 object *tmp2 = tmp->head == NULL ? tmp : tmp->head;
188 if (QUERY_FLAG(tmp2,FLAG_ALIVE) && ((
189 !QUERY_FLAG(tmp2, FLAG_FRIENDLY) &&
190 (tmp2->type != PLAYER)) ||
191 should_arena_attack(pet, owner, tmp2))
192 && !QUERY_FLAG(tmp2,FLAG_UNAGGRESSIVE) &&
193 tmp2 != pet && tmp2 != owner &&
194 can_detect_enemy(pet, tmp2, rv)) {
195 197
196 if (!can_see_enemy(pet, tmp2)) { 198 if (QUERY_FLAG (tmp2, FLAG_ALIVE) && ((!QUERY_FLAG (tmp2, FLAG_FRIENDLY) &&
197 if (tmp3 != NULL) 199 (tmp2->type != PLAYER)) ||
198 tmp3 = tmp2; 200 should_arena_attack (pet, owner, tmp2))
199 } else { 201 && !QUERY_FLAG (tmp2, FLAG_UNAGGRESSIVE) && tmp2 != pet && tmp2 != owner && can_detect_enemy (pet, tmp2, rv))
200 pet->enemy = tmp2; 202 {
201 if(check_enemy(pet, rv)!=NULL) 203
202 return tmp2; 204 if (!can_see_enemy (pet, tmp2))
203 else 205 {
204 pet->enemy = NULL; 206 if (tmp3 != NULL)
205 } 207 tmp3 = tmp2;
208 }
209 else
210 {
211 pet->enemy = tmp2;
212 if (check_enemy (pet, rv) != NULL)
213 return tmp2;
214 else
215 pet->enemy = NULL;
216 }
206 } /* make sure we can get to the bugger */ 217 } /* make sure we can get to the bugger */
207 }/* for objects on this space */ 218 } /* for objects on this space */
208 } /* if there is something living on this space */ 219 } /* if there is something living on this space */
209 } /* for loop of spaces around the pet */ 220 } /* for loop of spaces around the pet */
210 } /* pet in defence mode */ 221 } /* pet in defence mode */
211 222
212 /* fine, we went through the whole loop and didn't find one we could 223 /* fine, we went through the whole loop and didn't find one we could
213 see, take what we have */ 224 see, take what we have */
214 if (tmp3 != NULL) { 225 if (tmp3 != NULL)
226 {
215 pet->enemy = tmp3; 227 pet->enemy = tmp3;
216 if (check_enemy(pet, rv) != NULL) 228 if (check_enemy (pet, rv) != NULL)
217 return tmp3; 229 return tmp3;
218 else 230 else
219 pet->enemy = NULL; 231 pet->enemy = NULL;
220 } 232 }
221 233
222 /* Didn't find anything - return the owner's enemy or NULL */ 234 /* Didn't find anything - return the owner's enemy or NULL */
223 return check_enemy(pet, rv); 235 return check_enemy (pet, rv);
224} 236}
225 237
238void
226void terminate_all_pets(object *owner) { 239terminate_all_pets (object *owner)
240{
227 objectlink *obl, *next; 241 objectlink *obl, *next;
242
228 for(obl = first_friendly_object; obl != NULL; obl = next) { 243 for (obl = first_friendly_object; obl != NULL; obl = next)
244 {
229 object *ob = obl->ob; 245 object *ob = obl->ob;
246
230 next = obl->next; 247 next = obl->next;
231 if(get_owner(ob) == owner) { 248 if (get_owner (ob) == owner)
249 {
232 if(!QUERY_FLAG(ob, FLAG_REMOVED)) 250 if (!QUERY_FLAG (ob, FLAG_REMOVED))
233 remove_ob(ob); 251 remove_ob (ob);
234 remove_friendly_object(ob); 252 remove_friendly_object (ob);
235 free_object(ob); 253 free_object (ob);
236 } 254 }
237 } 255 }
238} 256}
239 257
240/* 258/*
241 * Unfortunately, sometimes, the owner of a pet is in the 259 * Unfortunately, sometimes, the owner of a pet is in the
242 * process of entering a new map when this is called. 260 * process of entering a new map when this is called.
244 * the pet... 262 * the pet...
245 * Interesting enough, we don't use the passed map structure in 263 * Interesting enough, we don't use the passed map structure in
246 * this function. 264 * this function.
247 */ 265 */
248 266
267void
249void remove_all_pets(mapstruct *map) { 268remove_all_pets (mapstruct *map)
269{
250 objectlink *obl, *next; 270 objectlink *obl, *next;
251 object *owner; 271 object *owner;
252 272
253 for(obl = first_friendly_object; obl != NULL; obl = next) { 273 for (obl = first_friendly_object; obl != NULL; obl = next)
274 {
254 next = obl->next; 275 next = obl->next;
255 if(obl->ob->type != PLAYER && QUERY_FLAG(obl->ob,FLAG_FRIENDLY) && 276 if (obl->ob->type != PLAYER && QUERY_FLAG (obl->ob, FLAG_FRIENDLY) &&
256 (owner = get_owner(obl->ob)) != NULL && !on_same_map(owner, obl->ob)) 277 (owner = get_owner (obl->ob)) != NULL && !on_same_map (owner, obl->ob))
257 { 278 {
258 /* follow owner checks map status for us */ 279 /* follow owner checks map status for us */
259 follow_owner(obl->ob,owner); 280 follow_owner (obl->ob, owner);
260 } 281 }
261 } 282 }
262} 283}
263 284
285int
264int follow_owner(object *ob, object *owner) { 286follow_owner (object *ob, object *owner)
287{
265 object *tmp; 288 object *tmp;
266 int dir; 289 int dir;
267 290
268 if (!QUERY_FLAG(ob,FLAG_REMOVED)) 291 if (!QUERY_FLAG (ob, FLAG_REMOVED))
269 remove_ob(ob); 292 remove_ob (ob);
270 293
271 if(owner->map == NULL) { 294 if (owner->map == NULL)
295 {
272 LOG(llevError,"Can't follow owner (%d): no map.\n", owner->name); 296 LOG (llevError, "Can't follow owner (%d): no map.\n", &owner->name);
273 goto fail; 297 goto fail;
274 } 298 }
275 if(owner->map->in_memory != MAP_IN_MEMORY) { 299 if (owner->map->in_memory != MAP_IN_MEMORY)
300 {
276 LOG(llevError,"Owner of the pet not on a map in memory!?\n"); 301 LOG (llevError, "Owner of the pet not on a map in memory!?\n");
277 goto fail; 302 goto fail;
278 } 303 }
279 304
280 dir = find_free_spot(ob, owner->map, owner->x, owner->y, 1, SIZEOFFREE); 305 dir = find_free_spot (ob, owner->map, owner->x, owner->y, 1, SIZEOFFREE);
281 306
282 if (dir==-1) { 307 if (dir == -1)
308 {
283 LOG(llevMonster,"No space for pet to follow, freeing %s.\n",ob->name); 309 LOG (llevMonster, "No space for pet to follow, freeing %s.\n", &ob->name);
284 goto fail; 310 goto fail;
285 } 311 }
286 for(tmp=ob;tmp!=NULL;tmp=tmp->more) { 312 for (tmp = ob; tmp != NULL; tmp = tmp->more)
313 {
287 tmp->x = owner->x + freearr_x[dir]+(tmp->arch==NULL?0:tmp->arch->clone.x); 314 tmp->x = owner->x + freearr_x[dir] + (tmp->arch == NULL ? 0 : tmp->arch->clone.x);
288 tmp->y = owner->y + freearr_y[dir]+(tmp->arch==NULL?0:tmp->arch->clone.y); 315 tmp->y = owner->y + freearr_y[dir] + (tmp->arch == NULL ? 0 : tmp->arch->clone.y);
289 tmp->map = owner->map; 316 tmp->map = owner->map;
290 if (OUT_OF_REAL_MAP(tmp->map, tmp->x, tmp->y)) { 317 if (OUT_OF_REAL_MAP (tmp->map, tmp->x, tmp->y))
318 {
291 tmp->map = get_map_from_coord(tmp->map, &tmp->x, &tmp->y); 319 tmp->map = get_map_from_coord (tmp->map, &tmp->x, &tmp->y);
292 } 320 }
293 } 321 }
294 insert_ob_in_map(ob, ob->map, NULL,0); 322 insert_ob_in_map (ob, ob->map, NULL, 0);
295 if (owner->type == PLAYER) /* Uh, I hope this is always true... */ 323 if (owner->type == PLAYER) /* Uh, I hope this is always true... */
296 new_draw_info(NDI_UNIQUE, 0,owner, "Your pet magically appears next to you"); 324 new_draw_info (NDI_UNIQUE, 0, owner, "Your pet magically appears next to you");
297 325
298 return 0; 326 return 0;
299 327
300fail: 328fail:
301 remove_friendly_object (ob); 329 remove_friendly_object (ob);
302 free_object (ob); 330 free_object (ob);
303 331
304 return 1; 332 return 1;
305} 333}
306 334
335void
307void pet_move(object * ob) 336pet_move (object *ob)
308{ 337{
309 int dir, tag, i; 338 int dir, tag, i;
310 sint16 dx, dy; 339 sint16 dx, dy;
311 object *ob2, *owner; 340 object *ob2, *owner;
312 mapstruct *m; 341 mapstruct *m;
313 342
314 /* Check to see if player pulled out */ 343 /* Check to see if player pulled out */
315 if ((owner = get_owner(ob)) == NULL) { 344 if ((owner = get_owner (ob)) == NULL)
345 {
316 remove_ob(ob); /* Will be freed when returning */ 346 remove_ob (ob); /* Will be freed when returning */
317 remove_friendly_object(ob); 347 remove_friendly_object (ob);
318 free_object(ob); 348 free_object (ob);
319 LOG(llevMonster, "Pet: no owner, leaving.\n"); 349 LOG (llevMonster, "Pet: no owner, leaving.\n");
320 return; 350 return;
321 } 351 }
322 352
323 /* move monster into the owners map if not in the same map */ 353 /* move monster into the owners map if not in the same map */
324 if (!on_same_map(ob, owner)) { 354 if (!on_same_map (ob, owner))
355 {
325 follow_owner(ob, owner); 356 follow_owner (ob, owner);
326 return; 357 return;
327 } 358 }
328 /* Calculate Direction */ 359 /* Calculate Direction */
329 if (owner->type == PLAYER && owner->contr->petmode == pet_sad) { 360 if (owner->type == PLAYER && owner->contr->petmode == pet_sad)
361 {
330 /* in S&D mode, if we have no enemy, run randomly about. */ 362 /* in S&D mode, if we have no enemy, run randomly about. */
331 for (i=0; i < 15; i++) { 363 for (i = 0; i < 15; i++)
364 {
332 dir = rndm(1, 8); 365 dir = rndm (1, 8);
333 dx = ob->x + freearr_x[dir]; 366 dx = ob->x + freearr_x[dir];
334 dy = ob->y + freearr_y[dir]; 367 dy = ob->y + freearr_y[dir];
335 m = ob->map; 368 m = ob->map;
336 if (get_map_flags(ob->map, &m, dx, dy, &dx, &dy) & P_OUT_OF_MAP) 369 if (get_map_flags (ob->map, &m, dx, dy, &dx, &dy) & P_OUT_OF_MAP)
337 continue; 370 continue;
338 else if (OB_TYPE_MOVE_BLOCK(ob, GET_MAP_MOVE_BLOCK(m, dx, dy))) 371 else if (OB_TYPE_MOVE_BLOCK (ob, GET_MAP_MOVE_BLOCK (m, dx, dy)))
339 continue; 372 continue;
373 else
374 break;
375 }
376 }
340 else 377 else
341 break; 378 {
342 }
343 } else {
344 struct rv_vector rv; 379 struct rv_vector rv;
380
345 get_rangevector (ob, ob->owner, &rv, 0); 381 get_rangevector (ob, ob->owner, &rv, 0);
346 dir = rv.direction; 382 dir = rv.direction;
347 } 383 }
348 ob->direction = dir; 384 ob->direction = dir;
349 385
350 tag = ob->count; 386 tag = ob->count;
351 /* move_ob returns 0 if the object couldn't move. If that is the 387 /* move_ob returns 0 if the object couldn't move. If that is the
352 * case, lets do some other work. 388 * case, lets do some other work.
353 */ 389 */
354 if (!(move_ob(ob, dir, ob))) { 390 if (!(move_ob (ob, dir, ob)))
391 {
355 object *part; 392 object *part;
356 393
357 /* the failed move_ob above may destroy the pet, so check here */ 394 /* the failed move_ob above may destroy the pet, so check here */
358 if (was_destroyed(ob, tag)) return; 395 if (was_destroyed (ob, tag))
396 return;
359 397
360 for(part = ob; part != NULL; part = part->more) 398 for (part = ob; part != NULL; part = part->more)
361 { 399 {
362 dx = part->x + freearr_x[dir]; 400 dx = part->x + freearr_x[dir];
363 dy = part->y + freearr_y[dir]; 401 dy = part->y + freearr_y[dir];
364 m = get_map_from_coord(part->map, &dx, &dy); 402 m = get_map_from_coord (part->map, &dx, &dy);
365 if (!m) continue; 403 if (!m)
404 continue;
366 405
367 for (ob2 = get_map_ob(m, dx, dy); ob2 != NULL; ob2 = ob2->above) 406 for (ob2 = get_map_ob (m, dx, dy); ob2 != NULL; ob2 = ob2->above)
368 { 407 {
369 object *new_ob; 408 object *new_ob;
409
370 new_ob = ob2->head?ob2->head:ob2; 410 new_ob = ob2->head ? ob2->head : ob2;
371 if(new_ob == ob) 411 if (new_ob == ob)
372 break; 412 break;
373 if (new_ob == ob->owner) 413 if (new_ob == ob->owner)
374 return; 414 return;
375 if (get_owner(new_ob) == ob->owner) 415 if (get_owner (new_ob) == ob->owner)
376 break; 416 break;
377 417
378 /* Hmm. Did we try to move into an enemy monster? If so, 418 /* Hmm. Did we try to move into an enemy monster? If so,
379 * make it our enemy. 419 * make it our enemy.
380 */ 420 */
381 if (QUERY_FLAG(new_ob,FLAG_ALIVE) && !QUERY_FLAG(ob,FLAG_UNAGGRESSIVE) 421 if (QUERY_FLAG (new_ob, FLAG_ALIVE) && !QUERY_FLAG (ob, FLAG_UNAGGRESSIVE)
382 && !QUERY_FLAG(new_ob,FLAG_UNAGGRESSIVE) && 422 && !QUERY_FLAG (new_ob, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (new_ob, FLAG_FRIENDLY))
383 !QUERY_FLAG(new_ob,FLAG_FRIENDLY)) { 423 {
384 424
385 ob->enemy = new_ob; 425 ob->enemy = new_ob;
386 if(new_ob->enemy == NULL) 426 if (new_ob->enemy == NULL)
387 new_ob->enemy = ob; 427 new_ob->enemy = ob;
388 return; 428 return;
429 }
389 } else if (new_ob->type == PLAYER) { 430 else if (new_ob->type == PLAYER)
431 {
390 new_draw_info(NDI_UNIQUE, 0,new_ob, "You stand in the way of someones pet."); 432 new_draw_info (NDI_UNIQUE, 0, new_ob, "You stand in the way of someones pet.");
391 return; 433 return;
392 } 434 }
435 }
436 }
437 /* Try a different course */
438 dir = absdir (dir + 4 - (RANDOM () % 5) - (RANDOM () % 5));
439 (void) move_ob (ob, dir, ob);
393 } 440 }
394 }
395 /* Try a different course */
396 dir = absdir(dir + 4 - (RANDOM() %5) - (RANDOM()%5));
397 (void) move_ob(ob, dir, ob);
398 }
399 return; 441 return;
400} 442}
401 443
402/**************************************************************************** 444/****************************************************************************
403 * 445 *
404 * GOLEM SPELL CODE 446 * GOLEM SPELL CODE
409 * proper for map insertion. 451 * proper for map insertion.
410 * at is the archetype, op is the caster of the spell, dir is the 452 * at is the archetype, op is the caster of the spell, dir is the
411 * direction the monster should be placed in. 453 * direction the monster should be placed in.
412 * is_golem is to note that this is a golem spell. 454 * is_golem is to note that this is a golem spell.
413 */ 455 */
456object *
414object *fix_summon_pet(archetype *at, object *op, int dir, int is_golem ) { 457fix_summon_pet (archetype *at, object *op, int dir, int is_golem)
458{
415 archetype *atmp; 459 archetype *atmp;
416 object *tmp=NULL, *prev=NULL, *head=NULL; 460 object *tmp = NULL, *prev = NULL, *head = NULL;
417 461
418 for(atmp = at; atmp!=NULL; atmp = atmp->more) { 462 for (atmp = at; atmp != NULL; atmp = atmp->more)
463 {
419 tmp = arch_to_object(atmp); 464 tmp = arch_to_object (atmp);
420 if (atmp == at) { 465 if (atmp == at)
421 if(!is_golem)
422 SET_FLAG(tmp, FLAG_MONSTER);
423 set_owner(tmp, op);
424 if (op->type == PLAYER) {
425 tmp->stats.exp = 0;
426 add_friendly_object(tmp);
427 SET_FLAG(tmp, FLAG_FRIENDLY);
428 if(is_golem) CLEAR_FLAG(tmp, FLAG_MONSTER);
429 } else {
430 if(QUERY_FLAG(op, FLAG_FRIENDLY)) {
431 object *owner = get_owner(op);
432 if(owner != NULL) {/* For now, we transfer ownership */
433 set_owner(tmp,owner);
434 tmp->attack_movement = PETMOVE;
435 add_friendly_object(tmp);
436 SET_FLAG(tmp, FLAG_FRIENDLY);
437 }
438 }
439 }
440 if(op->type!=PLAYER || !is_golem) {
441 tmp->attack_movement = PETMOVE;
442 tmp->speed_left = -1;
443 tmp->type = 0;
444 tmp->enemy = op->enemy;
445 } else
446 tmp->type = GOLEM;
447 466 {
448 } 467 if (!is_golem)
468 SET_FLAG (tmp, FLAG_MONSTER);
469 set_owner (tmp, op);
470 if (op->type == PLAYER)
471 {
472 tmp->stats.exp = 0;
473 add_friendly_object (tmp);
474 SET_FLAG (tmp, FLAG_FRIENDLY);
475 if (is_golem)
476 CLEAR_FLAG (tmp, FLAG_MONSTER);
477 }
478 else
479 {
480 if (QUERY_FLAG (op, FLAG_FRIENDLY))
481 {
482 object *owner = get_owner (op);
483
484 if (owner != NULL)
485 { /* For now, we transfer ownership */
486 set_owner (tmp, owner);
487 tmp->attack_movement = PETMOVE;
488 add_friendly_object (tmp);
489 SET_FLAG (tmp, FLAG_FRIENDLY);
490 }
491 }
492 }
493 if (op->type != PLAYER || !is_golem)
494 {
495 tmp->attack_movement = PETMOVE;
496 tmp->speed_left = -1;
497 tmp->type = 0;
498 tmp->enemy = op->enemy;
499 }
500 else
501 tmp->type = GOLEM;
502
503 }
449 if(head == NULL) 504 if (head == NULL)
450 head = tmp; 505 head = tmp;
451 tmp->x = op->x + freearr_x[dir] + tmp->arch->clone.x; 506 tmp->x = op->x + freearr_x[dir] + tmp->arch->clone.x;
452 tmp->y = op->y + freearr_y[dir] + tmp->arch->clone.y; 507 tmp->y = op->y + freearr_y[dir] + tmp->arch->clone.y;
453 tmp->map = op->map; 508 tmp->map = op->map;
454 if(tmp->invisible) tmp->invisible=0; 509 if (tmp->invisible)
510 tmp->invisible = 0;
455 if(head != tmp) 511 if (head != tmp)
456 tmp->head = head, prev->more = tmp; 512 tmp->head = head, prev->more = tmp;
457 prev = tmp; 513 prev = tmp;
458 } 514 }
459 head->direction = dir; 515 head->direction = dir;
460 516
461 /* need to change some monster attr to prevent problems/crashing */ 517 /* need to change some monster attr to prevent problems/crashing */
462 head->last_heal=0; 518 head->last_heal = 0;
463 head->last_eat=0; 519 head->last_eat = 0;
464 head->last_grace=0; 520 head->last_grace = 0;
465 head->last_sp=0; 521 head->last_sp = 0;
466 head->other_arch=NULL; 522 head->other_arch = NULL;
467 head->stats.exp = 0; 523 head->stats.exp = 0;
468 CLEAR_FLAG(head,FLAG_CHANGING); 524 CLEAR_FLAG (head, FLAG_CHANGING);
469 CLEAR_FLAG(head,FLAG_STAND_STILL); 525 CLEAR_FLAG (head, FLAG_STAND_STILL);
470 CLEAR_FLAG(head,FLAG_GENERATOR); 526 CLEAR_FLAG (head, FLAG_GENERATOR);
471 CLEAR_FLAG(head,FLAG_SPLITTING); 527 CLEAR_FLAG (head, FLAG_SPLITTING);
472 if(head->attacktype&AT_GHOSTHIT) head->attacktype=(AT_PHYSICAL|AT_DRAIN); 528 if (head->attacktype & AT_GHOSTHIT)
529 head->attacktype = (AT_PHYSICAL | AT_DRAIN);
473 530
474 return head; 531 return head;
475} 532}
476 533
477/* updated this to allow more than the golem 'head' to attack */ 534/* updated this to allow more than the golem 'head' to attack */
535
478/* op is the golem to be moved. */ 536/* op is the golem to be moved. */
479 537
538void
480void move_golem(object *op) { 539move_golem (object *op)
540{
481 int made_attack=0; 541 int made_attack = 0;
482 object *tmp; 542 object *tmp;
483 tag_t tag; 543 tag_t tag;
484 544
485 if(QUERY_FLAG(op, FLAG_MONSTER)) 545 if (QUERY_FLAG (op, FLAG_MONSTER))
486 return; /* Has already been moved */ 546 return; /* Has already been moved */
487 547
488 if(get_owner(op)==NULL) { 548 if (get_owner (op) == NULL)
549 {
489 LOG(llevDebug,"Golem without owner destructed.\n"); 550 LOG (llevDebug, "Golem without owner destructed.\n");
490 remove_ob(op); 551 remove_ob (op);
491 free_object(op); 552 free_object (op);
492 return; 553 return;
493 } 554 }
494 /* It would be nice to have a cleaner way of what message to print 555 /* It would be nice to have a cleaner way of what message to print
495 * when the golem expires than these hard coded entries. 556 * when the golem expires than these hard coded entries.
496 * Note it is intentional that a golems duration is based on its 557 * Note it is intentional that a golems duration is based on its
497 * hp, and not duration 558 * hp, and not duration
498 */ 559 */
499 if(--op->stats.hp<0) { 560 if (--op->stats.hp < 0)
561 {
500 if (op->msg) 562 if (op->msg)
501 new_draw_info(NDI_UNIQUE, 0,op->owner,op->msg); 563 new_draw_info (NDI_UNIQUE, 0, op->owner, op->msg);
502 op->owner->contr->ranges[range_golem]=NULL; 564 op->owner->contr->ranges[range_golem] = NULL;
503 op->owner->contr->golem_count = 0; 565 op->owner->contr->golem_count = 0;
504 remove_friendly_object(op); 566 remove_friendly_object (op);
505 remove_ob(op); 567 remove_ob (op);
506 free_object(op); 568 free_object (op);
507 return; 569 return;
508 } 570 }
509 571
510 /* Do golem attacks/movement for single & multisq golems. 572 /* Do golem attacks/movement for single & multisq golems.
511 * Assuming here that op is the 'head' object. Pass only op to 573 * Assuming here that op is the 'head' object. Pass only op to
512 * move_ob (makes recursive calls to other parts) 574 * move_ob (makes recursive calls to other parts)
513 * move_ob returns 0 if the creature was not able to move. 575 * move_ob returns 0 if the creature was not able to move.
514 */ 576 */
515 tag = op->count; 577 tag = op->count;
516 if(move_ob(op,op->direction,op)) return; 578 if (move_ob (op, op->direction, op))
579 return;
517 if (was_destroyed (op, tag)) 580 if (was_destroyed (op, tag))
518 return; 581 return;
519 582
520 for(tmp=op;tmp;tmp=tmp->more) { 583 for (tmp = op; tmp; tmp = tmp->more)
584 {
521 sint16 x=tmp->x+freearr_x[op->direction],y=tmp->y+freearr_y[op->direction]; 585 sint16 x = tmp->x + freearr_x[op->direction], y = tmp->y + freearr_y[op->direction];
522 object *victim; 586 object *victim;
523 mapstruct *m; 587 mapstruct *m;
524 int mflags; 588 int mflags;
525 589
526 m = op->map; 590 m = op->map;
527 mflags = get_map_flags(m, &m, x, y, &x, &y); 591 mflags = get_map_flags (m, &m, x, y, &x, &y);
528 592
529 if (mflags & P_OUT_OF_MAP) continue; 593 if (mflags & P_OUT_OF_MAP)
594 continue;
530 595
531 for(victim=get_map_ob(op->map,x,y);victim;victim=victim->above) 596 for (victim = get_map_ob (op->map, x, y); victim; victim = victim->above)
532 if(QUERY_FLAG(victim,FLAG_ALIVE)) break; 597 if (QUERY_FLAG (victim, FLAG_ALIVE))
598 break;
533 599
534 /* We used to call will_hit_self to make sure we don't 600 /* We used to call will_hit_self to make sure we don't
535 * hit ourselves, but that didn't work, and I don't really 601 * hit ourselves, but that didn't work, and I don't really
536 * know if that was more efficient anyways than this. 602 * know if that was more efficient anyways than this.
537 * This at least works. Note that victim->head can be NULL, 603 * This at least works. Note that victim->head can be NULL,
538 * but since we are not trying to dereferance that pointer, 604 * but since we are not trying to dereferance that pointer,
539 * that isn't a problem. 605 * that isn't a problem.
540 */ 606 */
541 if(victim && victim!=op && victim->head!=op) { 607 if (victim && victim != op && victim->head != op)
608 {
542 609
543 /* for golems with race fields, we don't attack 610 /* for golems with race fields, we don't attack
544 * aligned races 611 * aligned races
545 */ 612 */
546 613
547 if(victim->race && op->race && strstr(op->race,victim->race)) { 614 if (victim->race && op->race && strstr (op->race, victim->race))
548 if(op->owner) new_draw_info_format(NDI_UNIQUE, 0,op->owner, 615 {
549 "%s avoids damaging %s.",op->name,victim->name); 616 if (op->owner)
617 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s avoids damaging %s.", &op->name, &victim->name);
618 }
550 } else if (victim == op->owner) { 619 else if (victim == op->owner)
551 if(op->owner) new_draw_info_format(NDI_UNIQUE, 0,op->owner, 620 {
552 "%s avoids damaging you.",op->name); 621 if (op->owner)
553 } else { 622 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s avoids damaging you.", &op->name);
554 attack_ob(victim,op); 623 }
555 made_attack=1; 624 else
625 {
626 attack_ob (victim, op);
627 made_attack = 1;
628 }
629 } /* If victim */
556 } 630 }
557 } /* If victim */ 631 if (made_attack)
558 }
559 if(made_attack) update_object(op,UP_OBJ_FACE); 632 update_object (op, UP_OBJ_FACE);
560} 633}
561 634
562/* this is a really stupid function when you get down and 635/* this is a really stupid function when you get down and
563 * look at it. Keep it here for the time being - makes life 636 * look at it. Keep it here for the time being - makes life
564 * easier if we ever decide to do more interesting thing with 637 * easier if we ever decide to do more interesting thing with
565 * controlled golems. 638 * controlled golems.
566 */ 639 */
640void
567void control_golem(object *op,int dir) { 641control_golem (object *op, int dir)
642{
568 op->direction=dir; 643 op->direction = dir;
569} 644}
570 645
571/* summon golem: summons a monster for 'op'. caster is the object 646/* summon golem: summons a monster for 'op'. caster is the object
572 * casting the spell, dir is the direction to place the monster, 647 * casting the spell, dir is the direction to place the monster,
573 * at is the archetype of the monster, and spob is the spell 648 * at is the archetype of the monster, and spob is the spell
574 * object. At this stage, all spob is really used for is to 649 * object. At this stage, all spob is really used for is to
575 * adjust some values in the monster. 650 * adjust some values in the monster.
576 */ 651 */
652int
577int summon_golem(object *op,object *caster,int dir,object *spob) { 653summon_golem (object *op, object *caster, int dir, object *spob)
654{
578 object *tmp, *god=NULL; 655 object *tmp, *god = NULL;
579 archetype *at; 656 archetype *at;
580 char buf[MAX_BUF]; 657 char buf[MAX_BUF];
581 658
582 /* Because there can be different golem spells, player may want to 659 /* Because there can be different golem spells, player may want to
583 * 'lose' their old golem. 660 * 'lose' their old golem.
584 */ 661 */
585 if(op->type==PLAYER && 662 if (op->type == PLAYER && op->contr->ranges[range_golem] != NULL && op->contr->golem_count == op->contr->ranges[range_golem]->count)
586 op->contr->ranges[range_golem]!=NULL && 663 {
587 op->contr->golem_count == op->contr->ranges[range_golem]->count) {
588 new_draw_info(NDI_UNIQUE, 0, op, "You dismiss your existing golem."); 664 new_draw_info (NDI_UNIQUE, 0, op, "You dismiss your existing golem.");
589 remove_ob(op->contr->ranges[range_golem]); 665 remove_ob (op->contr->ranges[range_golem]);
590 free_object(op->contr->ranges[range_golem]); 666 free_object (op->contr->ranges[range_golem]);
591 op->contr->ranges[range_golem]=NULL; 667 op->contr->ranges[range_golem] = NULL;
592 op->contr->golem_count=(uint32)-1; 668 op->contr->golem_count = (uint32) - 1;
593 } 669 }
594 670
595 if (spob->other_arch) 671 if (spob->other_arch)
596 at = spob->other_arch; 672 at = spob->other_arch;
597 else if (spob->race) { 673 else if (spob->race)
674 {
598 god = find_god(determine_god(caster)); 675 god = find_god (determine_god (caster));
599 676
600 if (!god) { 677 if (!god)
678 {
601 new_draw_info_format(NDI_UNIQUE, 0,op,"You must worship a god to cast %s.", spob->name); 679 new_draw_info_format (NDI_UNIQUE, 0, op, "You must worship a god to cast %s.", &spob->name);
602 return 0; 680 return 0;
603 } 681 }
682
604 at = determine_holy_arch (god, spob->race); 683 at = determine_holy_arch (god, spob->race);
605 if (!at) { 684
685 if (!at)
686 {
606 new_draw_info_format(NDI_UNIQUE, 0,op,"%s has no %s for you to call.", 687 new_draw_info_format (NDI_UNIQUE, 0, op, "%s has no %s for you to call.", &god->name, &spob->race);
607 god->name,spob->race);
608 return 0; 688 return 0;
609 } 689 }
610 } else { 690 }
691 else
692 {
611 LOG(llevError,"Spell %s lacks other_arch\n", spob->name); 693 LOG (llevError, "Spell %s lacks other_arch\n", &spob->name);
612 return 0; 694 return 0;
613 } 695 }
614 696
615 if(!dir) 697 if (!dir)
616 dir=find_free_spot(NULL,op->map,op->x,op->y,1,SIZEOFFREE1+1); 698 dir = find_free_spot (NULL, op->map, op->x, op->y, 1, SIZEOFFREE1 + 1);
617 699
618 if ((dir==-1) || ob_blocked(&at->clone, op->map, op->x + freearr_x[dir], op->y + freearr_y[dir])) { 700 if (dir == -1 || ob_blocked (&at->clone, op->map, op->x + freearr_x[dir], op->y + freearr_y[dir]))
701 {
619 new_draw_info(NDI_UNIQUE, 0,op,"There is something in the way."); 702 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
620 return 0; 703 return 0;
621 } 704 }
622 /* basically want to get proper map/coordinates for this object */ 705 /* basically want to get proper map/coordinates for this object */
623 706
624 if(!(tmp=fix_summon_pet(at,op,dir,GOLEM))) { 707 if (!(tmp = fix_summon_pet (at, op, dir, GOLEM)))
708 {
625 new_draw_info(NDI_UNIQUE, 0,op,"Your spell fails."); 709 new_draw_info (NDI_UNIQUE, 0, op, "Your spell fails.");
626 return 0; 710 return 0;
627 } 711 }
628 712
629 if(op->type==PLAYER) { 713 if (op->type == PLAYER)
714 {
630 tmp->type=GOLEM; 715 tmp->type = GOLEM;
631 set_owner(tmp,op); 716 set_owner (tmp, op);
632 set_spell_skill(op, caster, spob, tmp); 717 set_spell_skill (op, caster, spob, tmp);
633 op->contr->ranges[range_golem]=tmp; 718 op->contr->ranges[range_golem] = tmp;
634 op->contr->golem_count = tmp->count; 719 op->contr->golem_count = tmp->count;
635 /* give the player control of the golem */ 720 /* give the player control of the golem */
636 op->contr->shoottype=range_golem; 721 op->contr->shoottype = range_golem;
637 } else {
638 if(QUERY_FLAG(op, FLAG_FRIENDLY)) {
639 object *owner = get_owner(op);
640 if (owner != NULL) { /* For now, we transfer ownership */
641 set_owner (tmp, owner);
642 tmp->attack_movement = PETMOVE;
643 add_friendly_object (tmp);
644 SET_FLAG (tmp, FLAG_FRIENDLY);
645 } 722 }
646 } 723 else
724 {
725 if (QUERY_FLAG (op, FLAG_FRIENDLY))
726 {
727 object *owner = get_owner (op);
728
729 if (owner != NULL)
730 { /* For now, we transfer ownership */
731 set_owner (tmp, owner);
732 tmp->attack_movement = PETMOVE;
733 add_friendly_object (tmp);
734 SET_FLAG (tmp, FLAG_FRIENDLY);
735 }
736 }
737
647 SET_FLAG(tmp, FLAG_MONSTER); 738 SET_FLAG (tmp, FLAG_MONSTER);
648 } 739 }
649 740
650 /* make the speed positive.*/ 741 /* make the speed positive. */
651 tmp->speed = FABS(tmp->speed); 742 tmp->speed = FABS (tmp->speed);
652 743
653 /* This sets the level dependencies on dam and hp for monsters */ 744 /* This sets the level dependencies on dam and hp for monsters */
654 /* players can't cope with too strong summonings. */ 745 /* players can't cope with too strong summonings. */
655 /* but monsters can. reserve these for players. */ 746 /* but monsters can. reserve these for players. */
656 if(op->type==PLAYER) { 747 if (op->type == PLAYER)
657 tmp->stats.hp += spob->duration + 748 {
658 SP_level_duration_adjust(caster,spob); 749 tmp->stats.hp += spob->duration + SP_level_duration_adjust (caster, spob);
750
659 if (!spob->stats.dam) 751 if (!spob->stats.dam)
660 tmp->stats.dam += SP_level_dam_adjust(caster,spob); 752 tmp->stats.dam += SP_level_dam_adjust (caster, spob);
661 else 753 else
662 tmp->stats.dam= spob->stats.dam + 754 tmp->stats.dam = spob->stats.dam + SP_level_dam_adjust (caster, spob);
663 SP_level_dam_adjust(caster,spob); 755
664 tmp->speed += .02 * SP_level_range_adjust(caster,spob); 756 tmp->speed += .02 * SP_level_range_adjust (caster, spob);
665 tmp->speed = MIN(tmp->speed, 1.0); 757 tmp->speed = MIN (tmp->speed, 1.0);
666 if (spob->attacktype) tmp->attacktype = spob->attacktype; 758
759 if (spob->attacktype)
760 tmp->attacktype = spob->attacktype;
667 } 761 }
762
668 tmp->stats.wc -= SP_level_range_adjust(caster,spob); 763 tmp->stats.wc -= SP_level_range_adjust (caster, spob);
669 764
670 /* limit the speed to 0.3 for non-players, 1 for players. */ 765 /* limit the speed to 0.3 for non-players, 1 for players. */
671 766
672 /* make experience increase in proportion to the strength. 767 /* make experience increase in proportion to the strength.
673 * this is a bit simplistic - we are basically just looking at how 768 * this is a bit simplistic - we are basically just looking at how
674 * often the sp doubles and use that as the ratio. 769 * often the sp doubles and use that as the ratio.
675 */ 770 */
676 tmp->stats.exp *= 1 + (MAX(spob->stats.maxgrace, spob->stats.sp) / 771 tmp->stats.exp *= 1 + (MAX (spob->stats.maxgrace, spob->stats.sp) / caster_level (caster, spob));
677 caster_level(caster, spob));
678 tmp->speed_left= 0; 772 tmp->speed_left = 0;
679 tmp->direction=dir; 773 tmp->direction = dir;
680 774
681 /* Holy spell - some additional tailoring */ 775 /* Holy spell - some additional tailoring */
682 if (god) { 776 if (god)
777 {
683 object *tmp2; 778 object *tmp2;
684 779
685 sprintf(buf,"%s of %s",spob->name,god->name); 780 sprintf (buf, "%s of %s", &spob->name, &god->name);
686 buf[0] = toupper(buf[0]); 781 buf[0] = toupper (buf[0]);
782
687 for (tmp2=tmp; tmp2; tmp2=tmp2->more) { 783 for (tmp2 = tmp; tmp2; tmp2 = tmp2->more)
688 if (tmp2->name) free_string(tmp2->name); 784 tmp2->name = buf;
689 tmp2->name = add_string(buf); 785
690 }
691 tmp->attacktype |= god->attacktype; 786 tmp->attacktype |= god->attacktype;
692 memcpy(tmp->resist, god->resist, sizeof(tmp->resist)); 787 memcpy (tmp->resist, god->resist, sizeof (tmp->resist));
693 if (tmp->race) FREE_AND_CLEAR_STR(tmp->race); 788 tmp->race = god->race;
694 if (god->race) tmp->race = add_string(god->race); 789 tmp->slaying = god->slaying;
695 if (tmp->slaying) FREE_AND_CLEAR_STR(tmp->slaying); 790
696 if (god->slaying) tmp->slaying = add_string(god->slaying);
697 /* safety, we must allow a god's servants some reasonable attack */ 791 /* safety, we must allow a god's servants some reasonable attack */
698 if(!(tmp->attacktype&AT_PHYSICAL)) tmp->attacktype|=AT_PHYSICAL; 792 if (!(tmp->attacktype & AT_PHYSICAL))
793 tmp->attacktype |= AT_PHYSICAL;
699 } 794 }
700 795
701 insert_ob_in_map(tmp,tmp->map,op,0); 796 insert_ob_in_map (tmp, tmp->map, op, 0);
702 return 1; 797 return 1;
703} 798}
704 799
705 800
706/*************************************************************************** 801/***************************************************************************
707 * 802 *
713 * god) find acceptable. This checks level, races allowed by god, etc 808 * god) find acceptable. This checks level, races allowed by god, etc
714 * to determine what is acceptable. 809 * to determine what is acceptable.
715 * This returns NULL if no match was found. 810 * This returns NULL if no match was found.
716 */ 811 */
717 812
813object *
718object *choose_cult_monster(object *pl, object *god, int summon_level) { 814choose_cult_monster (object *pl, object *god, int summon_level)
815{
719 char buf[MAX_BUF]; 816 char buf[MAX_BUF];
720 const char *race; 817 const char *race;
721 int racenr, mon_nr,i; 818 int racenr, mon_nr, i;
722 racelink *list; 819 racelink *list;
723 objectlink *tobl; 820 objectlink *tobl;
724 object *otmp; 821 object *otmp;
725 822
726 /* Determine the number of races available */ 823 /* Determine the number of races available */
727 racenr=0; 824 racenr = 0;
728 strcpy(buf,god->race); 825 strcpy (buf, god->race);
729 race = strtok(buf,","); 826 race = strtok (buf, ",");
730 while(race) { 827 while (race)
731 racenr++; 828 {
829 racenr++;
732 race = strtok(NULL,","); 830 race = strtok (NULL, ",");
733 } 831 }
734 832
735 /* next, randomly select a race from the aligned_races string */ 833 /* next, randomly select a race from the aligned_races string */
736 if(racenr>1) { 834 if (racenr > 1)
835 {
737 racenr = rndm(0, racenr-1); 836 racenr = rndm (0, racenr - 1);
738 strcpy(buf,god->race); 837 strcpy (buf, god->race);
739 race = strtok(buf,","); 838 race = strtok (buf, ",");
740 for(i=0;i<racenr;i++) 839 for (i = 0; i < racenr; i++)
741 race = strtok(NULL,","); 840 race = strtok (NULL, ",");
742 } else 841 }
842 else
743 race = god->race; 843 race = god->race;
744 844
745 845
746 /* see if a we can match a race list of monsters. This should not 846 /* see if a we can match a race list of monsters. This should not
747 * happen, so graceful recovery isn't really needed, but this sanity 847 * happen, so graceful recovery isn't really needed, but this sanity
748 * checking is good for cases where the god archetypes mismatch the 848 * checking is good for cases where the god archetypes mismatch the
749 * race file 849 * race file
750 */ 850 */
751 if((list=find_racelink(race))==NULL) { 851 if ((list = find_racelink (race)) == NULL)
752 new_draw_info_format(NDI_UNIQUE, 0,pl, 852 {
753 "The spell fails! %s's creatures are beyond the range of your summons", 853 new_draw_info_format (NDI_UNIQUE, 0, pl, "The spell fails! %s's creatures are beyond the range of your summons", &god->name);
754 god->name);
755 LOG(llevDebug,"choose_cult_monster() requested non-existent aligned race!\n"); 854 LOG (llevDebug, "choose_cult_monster() requested non-existent aligned race!\n");
756 return 0; 855 return 0;
757 } 856 }
758 857
759 /* search for an apprplritate monster on this race list */ 858 /* search for an apprplritate monster on this race list */
760 mon_nr=0; 859 mon_nr = 0;
761 for(tobl=list->member;tobl;tobl=tobl->next) { 860 for (tobl = list->member; tobl; tobl = tobl->next)
762 otmp=tobl->ob;
763 if(!otmp||!QUERY_FLAG(otmp,FLAG_MONSTER)) continue;
764 if(otmp->level<=summon_level) mon_nr++;
765 } 861 {
862 otmp = tobl->ob;
863 if (!otmp || !QUERY_FLAG (otmp, FLAG_MONSTER))
864 continue;
865 if (otmp->level <= summon_level)
866 mon_nr++;
867 }
766 868
767 /* If this god has multiple race entries, we should really choose another. 869 /* If this god has multiple race entries, we should really choose another.
768 * But then we either need to track which ones we have tried, or just 870 * But then we either need to track which ones we have tried, or just
769 * make so many calls to this function, and if we get so many without 871 * make so many calls to this function, and if we get so many without
770 * a valid entry, assuming nothing is available and quit. 872 * a valid entry, assuming nothing is available and quit.
771 */ 873 */
772 if (!mon_nr) return NULL; 874 if (!mon_nr)
773
774 mon_nr = rndm(0, mon_nr-1);
775 for(tobl=list->member;tobl;tobl=tobl->next) {
776 otmp=tobl->ob;
777 if(!otmp||!QUERY_FLAG(otmp,FLAG_MONSTER)) continue;
778 if(otmp->level<=summon_level && !mon_nr--) return otmp;
779 }
780 /* This should not happen */
781 LOG(llevDebug,"choose_cult_monster() mon_nr was set, but did not find a monster\n");
782 return NULL; 875 return NULL;
783}
784 876
877 mon_nr = rndm (0, mon_nr - 1);
878 for (tobl = list->member; tobl; tobl = tobl->next)
879 {
880 otmp = tobl->ob;
881 if (!otmp || !QUERY_FLAG (otmp, FLAG_MONSTER))
882 continue;
883 if (otmp->level <= summon_level && !mon_nr--)
884 return otmp;
885 }
886 /* This should not happen */
887 LOG (llevDebug, "choose_cult_monster() mon_nr was set, but did not find a monster\n");
888 return NULL;
889}
785 890
786 891int
787int summon_object(object *op, object *caster, object *spell_ob, int dir, const char *stringarg) 892summon_object (object *op, object *caster, object *spell_ob, int dir, const char *stringarg)
788{ 893{
789 sint16 x,y, nrof=1, i; 894 sint16 x, y, nrof = 1, i;
790 archetype *summon_arch; 895 archetype *summon_arch;
791 int ndir; 896 int ndir;
792 897
793 if (spell_ob->other_arch) { 898 if (spell_ob->other_arch)
794 summon_arch = spell_ob->other_arch; 899 summon_arch = spell_ob->other_arch;
795 } else if (spell_ob->randomitems) { 900 else if (spell_ob->randomitems)
901 {
796 int level = caster_level(caster, spell_ob); 902 int level = caster_level (caster, spell_ob);
797 treasure *tr, *lasttr=NULL;; 903 treasure *tr, *lasttr = NULL;
798 904
905 shstr_cmp sparam (stringarg);
906
799 /* In old code, this was a very convuluted for statement, 907 /* In old code, this was a very convoluted for statement,
800 * with all the checks in the 'for' portion itself. Much 908 * with all the checks in the 'for' portion itself. Much
801 * more readable to break some of the conditions out. 909 * more readable to break some of the conditions out.
802 */ 910 */
803 for (tr=spell_ob->randomitems->items; tr; tr=tr->next) { 911 for (tr = spell_ob->randomitems->items; tr; tr = tr->next)
912 {
804 if (level < tr->magic) break; 913 if (level < tr->magic)
914 break;
915
805 lasttr = tr; 916 lasttr = tr;
806 if(stringarg && !strcmp(tr->item->name,stringarg)) break; 917
807 if (tr->next == NULL || tr->next->item == NULL) break; 918 if (tr->item->name == sparam)
808 } 919 break;
809 if (!lasttr) { 920
921 if (!tr->next || !tr->next->item)
922 break;
923 }
924
925 if (!lasttr)
926 {
810 LOG(llevError,"Treasurelist %s did not generate a valid entry in summon_object\n", 927 LOG (llevError, "Treasurelist %s did not generate a valid entry in summon_object\n", &spell_ob->randomitems->name);
811 spell_ob->randomitems->name);
812 new_draw_info(NDI_UNIQUE, 0, op, "The spell fails to summon any monsters."); 928 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to summon any monsters.");
813 return 0; 929 return 0;
814 } 930 }
931
815 summon_arch = lasttr->item; 932 summon_arch = lasttr->item;
816 nrof = lasttr->nrof; 933 nrof = lasttr->nrof;
817 934 }
818 } else if (spell_ob->race && !strcmp(spell_ob->race,"GODCULTMON")) { 935 else if (spell_ob->race && !strcmp (spell_ob->race, "GODCULTMON"))
936 {
819 object *god=find_god(determine_god(op)), *mon, *owner; 937 object *god = find_god (determine_god (op)), *mon, *owner;
820 int summon_level, tries; 938 int summon_level, tries;
821 939
822 if (!god && ((owner=get_owner(op))!=NULL)) { 940 if (!god && ((owner = get_owner (op)) != NULL))
823 god = find_god(determine_god(owner)); 941 god = find_god (determine_god (owner));
824 } 942
825 /* If we can't find a god, can't get what monster to summon */ 943 /* If we can't find a god, can't get what monster to summon */
826 if (!god) return 0; 944 if (!god)
827
828 if (!god->race) {
829 new_draw_info_format(NDI_UNIQUE, 0,op,
830 "%s has no creatures that you may summon!",god->name);
831 return 0; 945 return 0;
832 } 946
947 if (!god->race)
948 {
949 new_draw_info_format (NDI_UNIQUE, 0, op, "%s has no creatures that you may summon!", &god->name);
950 return 0;
951 }
952
833 /* the summon level */ 953 /* the summon level */
834 summon_level=caster_level(caster, spell_ob); 954 summon_level = caster_level (caster, spell_ob);
835 if (summon_level==0) summon_level=1; 955 if (summon_level == 0)
836 tries = 0; 956 summon_level = 1;
837 do { 957
958 tries = 0;
959 do
960 {
838 mon = choose_cult_monster(op, god,summon_level); 961 mon = choose_cult_monster (op, god, summon_level);
839 if (!mon) { 962 if (!mon)
840 new_draw_info_format(NDI_UNIQUE, 0,op, 963 {
841 "%s fails to send anything.",god->name); 964 new_draw_info_format (NDI_UNIQUE, 0, op, "%s fails to send anything.", &god->name);
842 return 0; 965 return 0;
843 } 966 }
967
844 ndir = dir; 968 ndir = dir;
969
845 if (!ndir) 970 if (!ndir)
846 ndir = find_free_spot(mon, op->map, op->x, op->y, 1, SIZEOFFREE); 971 ndir = find_free_spot (mon, op->map, op->x, op->y, 1, SIZEOFFREE);
972
847 if (ndir == -1 || ob_blocked(mon,op->map, op->x + freearr_x[ndir], op->y+freearr_y[ndir])) { 973 if (ndir == -1 || ob_blocked (mon, op->map, op->x + freearr_x[ndir], op->y + freearr_y[ndir]))
848 ndir=-1; 974 {
849 if (++tries == 5) { 975 ndir = -1;
976 if (++tries == 5)
977 {
850 new_draw_info(NDI_UNIQUE, 0,op, "There is something in the way."); 978 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
851 return 0; 979 return 0;
852 } 980 }
853 } 981 }
982 }
854 } while (ndir == -1); 983 while (ndir == -1);
984
855 if (mon->level > (summon_level/2)) 985 if (mon->level > (summon_level / 2))
856 nrof = random_roll(1, 2, op, PREFER_HIGH); 986 nrof = random_roll (1, 2, op, PREFER_HIGH);
857 else 987 else
858 nrof = die_roll(2, 2, op, PREFER_HIGH); 988 nrof = die_roll (2, 2, op, PREFER_HIGH);
989
859 summon_arch = mon->arch; 990 summon_arch = mon->arch;
860 } else { 991 }
992 else
861 summon_arch = NULL; 993 summon_arch = 0;
862 }
863 994
864 if (spell_ob->stats.dam) 995 if (spell_ob->stats.dam)
865 nrof += spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob); 996 nrof += spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
866 997
867 if (!summon_arch) { 998 if (!summon_arch)
999 {
868 new_draw_info(NDI_UNIQUE, 0, op, "There is no monsters available for summoning."); 1000 new_draw_info (NDI_UNIQUE, 0, op, "There is no monsters available for summoning.");
869 return 0; 1001 return 0;
870 } 1002 }
871 1003
872 for (i=1; i <= nrof; i++) { 1004 for (i = 1; i <= nrof; i++)
1005 {
873 archetype *atmp; 1006 archetype *atmp;
874 object *prev=NULL, *head=NULL, *tmp; 1007 object *prev = NULL, *head = NULL, *tmp;
875 1008
876 if (dir) { 1009 if (dir)
1010 {
877 ndir = dir; 1011 ndir = dir;
878 dir = absdir (dir+1); 1012 dir = absdir (dir + 1);
1013 }
879 } else 1014 else
880 ndir = find_free_spot(&summon_arch->clone, op->map, op->x, op->y, 1, SIZEOFFREE); 1015 ndir = find_free_spot (&summon_arch->clone, op->map, op->x, op->y, 1, SIZEOFFREE);
881 1016
882 if (ndir > 0) { 1017 if (ndir > 0)
1018 {
883 x = freearr_x[ndir]; 1019 x = freearr_x[ndir];
884 y = freearr_y[ndir]; 1020 y = freearr_y[ndir];
885 } 1021 }
886 1022
887 if (ndir == -1 || ob_blocked(&summon_arch->clone, op->map, op->x + x, op->y + y)){ 1023 if (ndir == -1 || ob_blocked (&summon_arch->clone, op->map, op->x + x, op->y + y))
1024 {
888 new_draw_info(NDI_UNIQUE, 0, op, "There is something in the way."); 1025 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
889 if (nrof > 1) 1026 if (nrof > 1)
890 new_draw_info(NDI_UNIQUE, 0,op, "No more pets for this casting."); 1027 new_draw_info (NDI_UNIQUE, 0, op, "No more pets for this casting.");
891 1028
892 return nrof > 1; 1029 return nrof > 1;
893 } 1030 }
894 1031
895 for (atmp = summon_arch; atmp!=NULL; atmp=atmp->more) { 1032 for (atmp = summon_arch; atmp != NULL; atmp = atmp->more)
1033 {
896 tmp = arch_to_object(atmp); 1034 tmp = arch_to_object (atmp);
897 if (atmp == summon_arch) { 1035 if (atmp == summon_arch)
1036 {
898 if (QUERY_FLAG(tmp, FLAG_MONSTER)) { 1037 if (QUERY_FLAG (tmp, FLAG_MONSTER))
899 set_owner(tmp, op); 1038 {
1039 set_owner (tmp, op);
900 set_spell_skill(op, caster, spell_ob, tmp); 1040 set_spell_skill (op, caster, spell_ob, tmp);
901 tmp->enemy = op->enemy; 1041 tmp->enemy = op->enemy;
902 tmp->type = 0; 1042 tmp->type = 0;
903 CLEAR_FLAG(tmp, FLAG_SLEEP); 1043 CLEAR_FLAG (tmp, FLAG_SLEEP);
1044
904 if (op->type == PLAYER || QUERY_FLAG(op, FLAG_FRIENDLY)) { 1045 if (op->type == PLAYER || QUERY_FLAG (op, FLAG_FRIENDLY))
1046 {
905 /* If this is not set, we make it friendly */ 1047 /* If this is not set, we make it friendly */
906 if (!QUERY_FLAG(spell_ob, FLAG_MONSTER)) { 1048 if (!QUERY_FLAG (spell_ob, FLAG_MONSTER))
907 SET_FLAG(tmp, FLAG_FRIENDLY); 1049 {
908 add_friendly_object(tmp); 1050 SET_FLAG (tmp, FLAG_FRIENDLY);
909 tmp->stats.exp = 0; 1051 add_friendly_object (tmp);
910 if (spell_ob->attack_movement) 1052 tmp->stats.exp = 0;
1053
1054 if (spell_ob->attack_movement)
911 tmp->attack_movement = spell_ob->attack_movement; 1055 tmp->attack_movement = spell_ob->attack_movement;
912 if (get_owner(op)) 1056
913 set_owner(tmp, get_owner(op)); 1057 if (get_owner (op))
914 } 1058 set_owner (tmp, get_owner (op));
915 } 1059 }
916 } 1060 }
917 if (tmp->speed > MIN_ACTIVE_SPEED) tmp->speed_left = -1; 1061 }
918 } 1062
919 if (head == NULL) head = tmp; 1063 if (tmp->speed > MIN_ACTIVE_SPEED)
920 else { 1064 tmp->speed_left = -1;
921 tmp->head = head; 1065 }
922 prev->more = tmp; 1066
923 } 1067 if (head == NULL)
1068 head = tmp;
1069 else
1070 {
1071 tmp->head = head;
1072 prev->more = tmp;
1073 }
1074
924 prev = tmp; 1075 prev = tmp;
925 tmp->x = op->x + x + tmp->arch->clone.x; 1076 tmp->x = op->x + x + tmp->arch->clone.x;
926 tmp->y = op->y + y + tmp->arch->clone.y; 1077 tmp->y = op->y + y + tmp->arch->clone.y;
927 tmp->map = op->map; 1078 tmp->map = op->map;
928 } 1079 }
1080
929 head->direction = freedir[ndir]; 1081 head->direction = freedir[ndir];
930 head->stats.exp = 0; 1082 head->stats.exp = 0;
931 head = insert_ob_in_map(head, head->map, op, 0); 1083 head = insert_ob_in_map (head, head->map, op, 0);
1084
932 if (head && head->randomitems) { 1085 if (head && head->randomitems)
1086 {
933 object *tmp; 1087 object *tmp;
1088
934 create_treasure(head->randomitems, head, GT_APPLY | GT_STARTEQUIP, 6, 0); 1089 create_treasure (head->randomitems, head, GT_APPLY | GT_STARTEQUIP, 6, 0);
935 for (tmp=head->inv; tmp; tmp=tmp->below) 1090 for (tmp = head->inv; tmp; tmp = tmp->below)
936 if (!tmp->nrof) SET_FLAG(tmp, FLAG_NO_DROP); 1091 if (!tmp->nrof)
937 } 1092 SET_FLAG (tmp, FLAG_NO_DROP);
938 } /* for i < nrof */ 1093 }
1094 } /* for i < nrof */
1095
939 return 1; 1096 return 1;
940} 1097}
941 1098
942/* recursively look through the owner property of objects until the real owner 1099/* recursively look through the owner property of objects until the real owner
943is found */ 1100is found */
1101object *
944object *get_real_owner(object *ob) { 1102get_real_owner (object *ob)
1103{
945 object *realowner = ob; 1104 object *realowner = ob;
946 1105
947 if (realowner == NULL) return NULL; 1106 if (realowner == NULL)
948 1107 return NULL;
1108
949 while(get_owner(realowner) != NULL) 1109 while (get_owner (realowner) != NULL)
950 { 1110 {
951 realowner = get_owner(realowner); 1111 realowner = get_owner (realowner);
952 } 1112 }
953 return realowner; 1113 return realowner;
954} 1114}
955 1115
956/* determines if checks so pets don't attack players or other pets should be 1116/* determines if checks so pets don't attack players or other pets should be
957overruled by the arena petmode */ 1117overruled by the arena petmode */
1118int
958int should_arena_attack(object *pet,object *owner,object *target) { 1119should_arena_attack (object *pet, object *owner, object *target)
1120{
959 object *rowner, *towner; 1121 object *rowner, *towner;
960 1122
961 /* exit if the target, pet, or owner is null. */ 1123 /* exit if the target, pet, or owner is null. */
962 if ((target == NULL) || (pet == NULL) || (owner == NULL)) return 0; 1124 if ((target == NULL) || (pet == NULL) || (owner == NULL))
963 1125 return 0;
1126
964 /* get the owners of itself and the target, this is to deal with pets of 1127 /* get the owners of itself and the target, this is to deal with pets of
965 pets */ 1128 pets */
966 rowner = get_real_owner(owner); 1129 rowner = get_real_owner (owner);
967 if (target->type != PLAYER) { 1130 if (target->type != PLAYER)
1131 {
968 towner = get_real_owner(target); 1132 towner = get_real_owner (target);
969 } else { 1133 }
970 towner = 0; 1134 else
971 } 1135 {
972 1136 towner = 0;
1137 }
1138
973 /* if the pet has now owner, exit with error */ 1139 /* if the pet has now owner, exit with error */
974 if (rowner == NULL) { 1140 if (rowner == NULL)
1141 {
975 LOG(llevError,"Pet has no owner.\n"); 1142 LOG (llevError, "Pet has no owner.\n");
976 return 0; 1143 return 0;
977 } 1144 }
978 1145
979 /* if the target is not a player, and has no owner, we shouldn't be here 1146 /* if the target is not a player, and has no owner, we shouldn't be here
980 */ 1147 */
981 if ((towner == NULL) && (target->type != PLAYER)) { 1148 if ((towner == NULL) && (target->type != PLAYER))
1149 {
982 LOG(llevError,"Target is not a player but has no owner. We should not be here.\n"); 1150 LOG (llevError, "Target is not a player but has no owner. We should not be here.\n");
983 return 0; 1151 return 0;
984 } 1152 }
985 1153
986 /* make sure that the owner is a player */ 1154 /* make sure that the owner is a player */
987 if (rowner->type != PLAYER) return 0; 1155 if (rowner->type != PLAYER)
988 1156 return 0;
1157
989 /* abort if the petmode is not arena */ 1158 /* abort if the petmode is not arena */
990 if (rowner->contr->petmode != pet_arena) return 0; 1159 if (rowner->contr->petmode != pet_arena)
991 1160 return 0;
1161
992 /* abort if the pet, it's owner, or the target is not on battleground*/ 1162 /* abort if the pet, it's owner, or the target is not on battleground */
993 if (!(op_on_battleground(pet, NULL, NULL) && 1163 if (!(op_on_battleground (pet, NULL, NULL) && op_on_battleground (owner, NULL, NULL) && op_on_battleground (target, NULL, NULL)))
994 op_on_battleground(owner, NULL, NULL) &&
995 op_on_battleground(target, NULL, NULL)))
996 return 0; 1164 return 0;
997 1165
998 /* if the target is a monster, make sure it's owner is not the same */ 1166 /* if the target is a monster, make sure it's owner is not the same */
999 if ((target->type != PLAYER) && (rowner == towner)) return 0; 1167 if ((target->type != PLAYER) && (rowner == towner))
1168 return 0;
1000 1169
1001 /* check if the target is a player which affects how it will handle 1170 /* check if the target is a player which affects how it will handle
1002 parties */ 1171 parties */
1003 if (target->type != PLAYER) { 1172 if (target->type != PLAYER)
1173 {
1004 /* if the target is owned by a player make sure than make sure 1174 /* if the target is owned by a player make sure than make sure
1005 it's not in the same party */ 1175 it's not in the same party */
1006 if ((towner->type == PLAYER) && (rowner->contr->party != NULL)) { 1176 if ((towner->type == PLAYER) && (rowner->contr->party != NULL))
1177 {
1007 if (rowner->contr->party == towner->contr->party) return 0; 1178 if (rowner->contr->party == towner->contr->party)
1008 } 1179 return 0;
1009 } else { 1180 }
1181 }
1182 else
1183 {
1010 /* if the target is a player make sure than make sure it's not 1184 /* if the target is a player make sure than make sure it's not
1011 in the same party */ 1185 in the same party */
1012 if (rowner->contr->party != NULL){ 1186 if (rowner->contr->party != NULL)
1187 {
1013 if (rowner->contr->party == target->contr->party) return 0; 1188 if (rowner->contr->party == target->contr->party)
1014 } 1189 return 0;
1015 } 1190 }
1016 1191 }
1192
1017 return 1; 1193 return 1;
1018} 1194}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines