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.3 by root, Sun Sep 3 00:18:42 2006 UTC vs.
Revision 1.19 by root, Wed Jan 3 20:32:13 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines