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.27 by elmex, Sun Apr 15 23:47:59 2007 UTC vs.
Revision 1.28 by elmex, Mon Apr 16 11:50:45 2007 UTC

42 int mflags; 42 int mflags;
43 43
44 attacker = pet->attacked_by; /*pointer to attacking enemy */ 44 attacker = pet->attacked_by; /*pointer to attacking enemy */
45 pet->attacked_by = NULL; /*clear this, since we are dealing with it */ 45 pet->attacked_by = NULL; /*clear this, since we are dealing with it */
46 46
47 if ((owner = pet->owner) != NULL) 47 if (owner = pet->owner)
48 { 48 {
49 /* If the owner has turned on the pet, make the pet 49 /* If the owner has turned on the pet, make the pet
50 * unfriendly. 50 * unfriendly.
51 */ 51 */
52 if ((check_enemy (owner, rv)) == pet) 52 if ((check_enemy (owner, rv)) == pet)
63 * pet no longer needs to be friendly. 63 * pet no longer needs to be friendly.
64 */ 64 */
65 CLEAR_FLAG (pet, FLAG_FRIENDLY); 65 CLEAR_FLAG (pet, FLAG_FRIENDLY);
66 remove_friendly_object (pet); 66 remove_friendly_object (pet);
67 pet->attack_movement &= ~PETMOVE; 67 pet->attack_movement &= ~PETMOVE;
68 return NULL; 68 return 0;
69 } 69 }
70 /* If they are not on the same map, the pet won't be agressive */ 70 /* If they are not on the same map, the pet won't be agressive */
71 if (!on_same_map (pet, owner)) 71 //if (!on_same_map (pet, owner))
72 return NULL; 72 // return 0;
73 73
74 /* See if the pet has an existing enemy. If so, don't start a new one */ 74 /* See if the pet has an existing enemy. If so, don't start a new one */
75 if ((tmp = check_enemy (pet, rv)) != NULL) 75 if (tmp = check_enemy (pet, rv))
76 { 76 {
77 if (tmp == owner && !QUERY_FLAG (pet, FLAG_CONFUSED) && QUERY_FLAG (pet, FLAG_FRIENDLY)) 77 if (tmp == owner && !QUERY_FLAG (pet, FLAG_CONFUSED) && QUERY_FLAG (pet, FLAG_FRIENDLY))
78 /* without this check, you can actually get pets with 78 /* without this check, you can actually get pets with
79 * enemy set to owner! 79 * enemy set to owner!
80 */ 80 */
81 pet->enemy = NULL; 81 pet->enemy = 0;
82 else 82 else
83 return tmp; 83 return tmp;
84 } 84 }
85 85
86 get_search_arr (search_arr); 86 get_search_arr (search_arr);
88 if (owner->type == PLAYER && owner->contr->petmode > pet_normal) 88 if (owner->type == PLAYER && owner->contr->petmode > pet_normal)
89 { 89 {
90 if (owner->contr->petmode == pet_sad) 90 if (owner->contr->petmode == pet_sad)
91 { 91 {
92 tmp = find_nearest_living_creature (pet); 92 tmp = find_nearest_living_creature (pet);
93 if (tmp != NULL) 93 if (tmp != 0)
94 { 94 {
95 get_rangevector (pet, tmp, rv, 0); 95 get_rangevector (pet, tmp, rv, 0);
96 if (check_enemy (pet, rv) != NULL) 96 if (check_enemy (pet, rv) != 0)
97 return tmp; 97 return tmp;
98 else 98 else
99 pet->enemy = NULL; 99 pet->enemy = 0;
100 } 100 }
101 /* if we got here we have no enemy */ 101 /* if we got here we have no enemy */
102 /* we return NULL to avoid heading back to the owner */ 102 /* we return 0 to avoid heading back to the owner */
103 pet->enemy = NULL; 103 pet->enemy = 0;
104 return NULL; 104 return 0;
105 } 105 }
106 } 106 }
107 107
108 /* Since the pet has no existing enemy, look for anything nasty 108 /* Since the pet has no existing enemy, look for anything nasty
109 * around the owner that it should go and attack. 109 * around the owner that it should go and attack. (if the owner is
110 * still on a map)
110 */ 111 */
111 tmp3 = NULL; 112 if (!owner->flag [FLAG_REMOVED])
113 {
114 tmp3 = 0;
115
112 for (i = 0; i < SIZEOFFREE; i++) 116 for (i = 0; i < SIZEOFFREE; i++)
113 { 117 {
114 x = owner->x + freearr_x[search_arr[i]]; 118 x = owner->x + freearr_x[search_arr[i]];
115 y = owner->y + freearr_y[search_arr[i]]; 119 y = owner->y + freearr_y[search_arr[i]];
116 nm = owner->map; 120 nm = owner->map;
117 /* Only look on the space if there is something alive there. */ 121 /* Only look on the space if there is something alive there. */
118 mflags = get_map_flags (nm, &nm, x, y, &x, &y); 122 mflags = get_map_flags (nm, &nm, x, y, &x, &y);
119 123
120 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) 124 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE)
121 { 125 {
122 for (tmp = GET_MAP_OB (nm, x, y); tmp != NULL; tmp = tmp->above) 126 for (tmp = GET_MAP_OB (nm, x, y); tmp != 0; 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 { 127 {
128 object *tmp2 = tmp->head == 0 ? tmp : tmp->head;
131 129
132 if (!can_see_enemy (pet, tmp2)) 130 if (QUERY_FLAG (tmp2, FLAG_ALIVE) && ((!QUERY_FLAG (tmp2, FLAG_FRIENDLY) &&
131 (tmp2->type != PLAYER)) ||
132 should_arena_attack (pet, owner, tmp2))
133 && !QUERY_FLAG (tmp2, FLAG_UNAGGRESSIVE) && tmp2 != pet && tmp2 != owner && can_detect_enemy (pet, tmp2, rv))
133 { 134 {
135
136 if (!can_see_enemy (pet, tmp2))
137 {
134 if (tmp3 != NULL) 138 if (tmp3 != 0)
135 tmp3 = tmp2; 139 tmp3 = tmp2;
136 } 140 }
137 else
138 {
139 pet->enemy = tmp2;
140 if (check_enemy (pet, rv) != NULL)
141 return tmp2;
142 else 141 else
142 {
143 pet->enemy = tmp2;
144 if (check_enemy (pet, rv) != 0)
145 return tmp2;
146 else
143 pet->enemy = NULL; 147 pet->enemy = 0;
144 } 148 }
145 } /* if this is a valid enemy */ 149 } /* if this is a valid enemy */
146 } /* for objects on this space */ 150 } /* for objects on this space */
147 } /* if there is something living on this space */ 151 } /* if there is something living on this space */
148 } /* for loop of spaces around the owner */ 152 } /* for loop of spaces around the owner */
149 153
150 /* fine, we went through the whole loop and didn't find one we could 154 /* fine, we went through the whole loop and didn't find one we could
151 see, take what we have */ 155 see, take what we have */
152 if (tmp3 != NULL) 156 if (tmp3 != 0)
153 { 157 {
154 pet->enemy = tmp3; 158 pet->enemy = tmp3;
155 if (check_enemy (pet, rv) != NULL) 159 if (check_enemy (pet, rv) != 0)
156 return tmp3; 160 return tmp3;
157 else 161 else
158 pet->enemy = NULL; 162 pet->enemy = 0;
163 }
159 } 164 }
160 165
161 /* No threat to owner, check to see if the pet has an attacker */ 166 /* No threat to owner, check to see if the pet has an attacker */
162 if (attacker) 167 if (attacker)
163 { 168 {
165 /* or otherwise non-hostile, and is an appropriate target */ 170 /* or otherwise non-hostile, and is an appropriate target */
166 if (!QUERY_FLAG (attacker, FLAG_FRIENDLY) && on_same_map (pet, attacker)) 171 if (!QUERY_FLAG (attacker, FLAG_FRIENDLY) && on_same_map (pet, attacker))
167 { 172 {
168 pet->enemy = attacker; 173 pet->enemy = attacker;
169 174
170 if (check_enemy (pet, rv) != NULL) 175 if (check_enemy (pet, rv) != 0)
171 return attacker; 176 return attacker;
172 else 177 else
173 pet->enemy = NULL; 178 pet->enemy = 0;
174 } 179 }
175 } 180 }
176 181
177 /* Don't have an attacker or legal enemy, so look for a new one!. 182 /* Don't have an attacker or legal enemy, so look for a new one!.
178 * This looks for one around where the pet is. Thus, you could lead 183 * This looks for one around where the pet is. Thus, you could lead
179 * a pet to danger, then take a few steps back. This code is basically 184 * a pet to danger, then take a few steps back. This code is basically
180 * the same as the code that looks around the owner. 185 * the same as the code that looks around the owner.
181 */ 186 */
182 if (owner->type == PLAYER && owner->contr->petmode != pet_defend) 187 if (owner->type == PLAYER && owner->contr->petmode != pet_defend)
183 { 188 {
184 tmp3 = NULL; 189 tmp3 = 0;
185 for (i = 0; i < SIZEOFFREE; i++) 190 for (i = 0; i < SIZEOFFREE; i++)
186 { 191 {
187 x = pet->x + freearr_x[search_arr[i]]; 192 x = pet->x + freearr_x[search_arr[i]];
188 y = pet->y + freearr_y[search_arr[i]]; 193 y = pet->y + freearr_y[search_arr[i]];
189 nm = pet->map; 194 nm = pet->map;
190 /* Only look on the space if there is something alive there. */ 195 /* Only look on the space if there is something alive there. */
191 mflags = get_map_flags (nm, &nm, x, y, &x, &y); 196 mflags = get_map_flags (nm, &nm, x, y, &x, &y);
192 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) 197 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE)
193 { 198 {
194 for (tmp = GET_MAP_OB (nm, x, y); tmp != NULL; tmp = tmp->above) 199 for (tmp = GET_MAP_OB (nm, x, y); tmp != 0; tmp = tmp->above)
195 { 200 {
196 object *tmp2 = tmp->head == NULL ? tmp : tmp->head; 201 object *tmp2 = tmp->head == 0 ? tmp : tmp->head;
197 202
198 if (QUERY_FLAG (tmp2, FLAG_ALIVE) && ((!QUERY_FLAG (tmp2, FLAG_FRIENDLY) && 203 if (QUERY_FLAG (tmp2, FLAG_ALIVE) && ((!QUERY_FLAG (tmp2, FLAG_FRIENDLY) &&
199 (tmp2->type != PLAYER)) || 204 (tmp2->type != PLAYER)) ||
200 should_arena_attack (pet, owner, tmp2)) 205 should_arena_attack (pet, owner, tmp2))
201 && !QUERY_FLAG (tmp2, FLAG_UNAGGRESSIVE) && tmp2 != pet && tmp2 != owner && can_detect_enemy (pet, tmp2, rv)) 206 && !QUERY_FLAG (tmp2, FLAG_UNAGGRESSIVE) && tmp2 != pet && tmp2 != owner && can_detect_enemy (pet, tmp2, rv))
202 { 207 {
203 208
204 if (!can_see_enemy (pet, tmp2)) 209 if (!can_see_enemy (pet, tmp2))
205 { 210 {
206 if (tmp3 != NULL) 211 if (tmp3 != 0)
207 tmp3 = tmp2; 212 tmp3 = tmp2;
208 } 213 }
209 else 214 else
210 { 215 {
211 pet->enemy = tmp2; 216 pet->enemy = tmp2;
212 if (check_enemy (pet, rv) != NULL) 217 if (check_enemy (pet, rv) != 0)
213 return tmp2; 218 return tmp2;
214 else 219 else
215 pet->enemy = NULL; 220 pet->enemy = 0;
216 } 221 }
217 } /* make sure we can get to the bugger */ 222 } /* make sure we can get to the bugger */
218 } /* for objects on this space */ 223 } /* for objects on this space */
219 } /* if there is something living on this space */ 224 } /* if there is something living on this space */
220 } /* for loop of spaces around the pet */ 225 } /* for loop of spaces around the pet */
226
227 /* fine, we went through the whole loop and didn't find one we could
228 see, take what we have */
229 if (tmp3 != 0)
230 {
231 pet->enemy = tmp3;
232 if (check_enemy (pet, rv) != 0)
233 return tmp3;
234 else
235 pet->enemy = 0;
236 }
221 } /* pet in defence mode */ 237 } /* pet in defence mode */
222 238
223 /* fine, we went through the whole loop and didn't find one we could 239 object *enemy = check_enemy (pet, rv);
224 see, take what we have */ 240 // we have a summoned pet here and the owners enemy isn't set or can't
225 if (tmp3 != NULL) 241 // be reached => search for a player around us and set it as our new enemy!!
226 { 242 if (!enemy && pet->owner && pet->owner->type != PLAYER)
227 pet->enemy = tmp3; 243 enemy = get_nearest_player (pet);
228 if (check_enemy (pet, rv) != NULL)
229 return tmp3;
230 else
231 pet->enemy = NULL;
232 }
233 244
234 /* Didn't find anything - return the owner's enemy or NULL */ 245 /* Didn't find anything - return the owner's enemy or 0 */
235 return check_enemy (pet, rv); 246 return enemy;
236} 247}
237 248
238void 249void
239terminate_all_pets (object *owner) 250terminate_all_pets (object *owner)
240{ 251{
285} 296}
286 297
287int 298int
288follow_owner (object *ob, object *owner) 299follow_owner (object *ob, object *owner)
289{ 300{
290 if (!owner->map) 301 if (owner->flag [FLAG_REMOVED])
291 LOG (llevError, "Can't follow owner (%d): no map.\n", &owner->name); 302 return 0; // do nothing if the owner is removed
292 else if (owner->map->in_memory != MAP_IN_MEMORY) 303 else if (owner->map->in_memory != MAP_IN_MEMORY)
293 LOG (llevError, "Owner of the pet not on a map in memory!?\n"); 304 LOG (llevError, "Owner of the pet not on a map in memory!?\n");
294 else 305 else
295 { 306 {
296 int dir = find_free_spot (ob, owner->map, owner->x, owner->y, 1, SIZEOFFREE); 307 int dir = find_free_spot (ob, owner->map, owner->x, owner->y, 1, SIZEOFFREE);
311} 322}
312 323
313void 324void
314pet_move (object *ob) 325pet_move (object *ob)
315{ 326{
316 int dir, i; 327 int dir = 0, i;
317 sint16 dx, dy; 328 sint16 dx, dy;
318 object *ob2, *owner; 329 object *ob2, *owner;
319 maptile *m; 330 maptile *m;
320 331
321 /* Check to see if player pulled out */ 332 /* Check to see if player pulled out */
326 ob->destroy (); 337 ob->destroy ();
327 LOG (llevMonster, "Pet: no owner, leaving.\n"); 338 LOG (llevMonster, "Pet: no owner, leaving.\n");
328 return; 339 return;
329 } 340 }
330 341
331 /* move monster into the owners map if not in the same map */ 342 /* move monster into the owners map if not in the same map
332 if (!on_same_map (ob, owner)) 343 * except when the owner is removed.
344 */
345 if (!on_same_map (ob, owner) && !owner->flag [FLAG_REMOVED])
333 { 346 {
334 follow_owner (ob, owner); 347 follow_owner (ob, owner);
335 return; 348 return;
336 } 349 }
337 /* Calculate Direction */ 350 /* Calculate Direction */
350 continue; 363 continue;
351 else 364 else
352 break; 365 break;
353 } 366 }
354 } 367 }
355 else 368 else if (!owner->flag [FLAG_REMOVED]) // only get vector to owner when owner not removed
356 { 369 {
357 struct rv_vector rv; 370 struct rv_vector rv;
358 371
359 get_rangevector (ob, ob->owner, &rv, 0); 372 get_rangevector (ob, ob->owner, &rv, 0);
360 dir = rv.direction; 373 dir = rv.direction;
713 tmp->set_owner (owner); 726 tmp->set_owner (owner);
714 tmp->attack_movement = PETMOVE; 727 tmp->attack_movement = PETMOVE;
715 add_friendly_object (tmp); 728 add_friendly_object (tmp);
716 } 729 }
717 } 730 }
718 else if (caster->type == RUNE || caster->type == TRAP)
719 {
720 // if the caster is a RUNE or a TRAP remove the owner
721 // because the trap or the op (a DOOR for example) can
722 // go away. And in these cases we don't want to the pets
723 // to disappear with the owner. So: give them no owner.
724 // - this hopefully also fixes other weirdnesses with summoned golems/monsters
725 // <elmex> I'm not entirely sure whether attackmovement has to be
726 // reset to something else than PETMOVE (I don't know whether it
727 // is PETMOVE here). but at least the monsters worked when I tested.
728
729 tmp->owner = NULL;
730 }
731 731
732 SET_FLAG (tmp, FLAG_MONSTER); 732 SET_FLAG (tmp, FLAG_MONSTER);
733 } 733 }
734 734
735 /* make the speed positive. */ 735 /* make the speed positive. */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines