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

Comparing deliantra/server/server/time.C (file contents):
Revision 1.1 by elmex, Sun Aug 13 17:16:05 2006 UTC vs.
Revision 1.8 by root, Sun Sep 3 00:18:42 2006 UTC

1/* 1/*
2 * static char *rcsid_time_c = 2 * static char *rcsid_time_c =
3 * "$Id: time.C,v 1.1 2006/08/13 17:16:05 elmex Exp $"; 3 * "$Id: time.C,v 1.8 2006/09/03 00:18:42 root Exp $";
4 */ 4 */
5 5
6/* 6/*
7 CrossFire, A Multiplayer game for X-windows 7 CrossFire, A Multiplayer game for X-windows
8 8
94 /* Code below assumes the generator is on a map, as it tries 94 /* Code below assumes the generator is on a map, as it tries
95 * to place the monster on the map. So if the generator 95 * to place the monster on the map. So if the generator
96 * isn't on a map, complain and exit. 96 * isn't on a map, complain and exit.
97 */ 97 */
98 if (gen->map == NULL) { 98 if (gen->map == NULL) {
99 //LOG(llevError,"Generator (%s) not on a map?\n", gen->name); 99 //LOG(llevError,"Generator (%s) not on a map?\n", gen->name);
100 return; 100 return;
101 } 101 }
102 /*First count numer of objects in inv*/ 102 /*First count numer of objects in inv*/
103 for (op=gen->inv;op;op=op->below) 103 for (op=gen->inv;op;op=op->below)
104 qty++; 104 qty++;
105 if (!qty){ 105 if (!qty){
106 LOG(llevError,"Generator (%s) has no inventory in generate_monster_inv?\n", gen->name); 106 LOG(llevError,"Generator (%s) has no inventory in generate_monster_inv?\n", &gen->name);
107 return;/*No inventory*/ 107 return;/*No inventory*/
108 } 108 }
109 qty=rndm(0,qty-1); 109 qty=rndm(0,qty-1);
110 for (op=gen->inv;qty;qty--) 110 for (op=gen->inv;qty;qty--)
111 op=op->below; 111 op=op->below;
128 int i; 128 int i;
129 object *op,*head=NULL,*prev=NULL; 129 object *op,*head=NULL,*prev=NULL;
130 archetype *at=gen->other_arch; 130 archetype *at=gen->other_arch;
131 131
132 if(gen->other_arch==NULL) { 132 if(gen->other_arch==NULL) {
133 //LOG(llevError,"Generator without other_arch: %s\n",gen->name); 133 //LOG(llevError,"Generator without other_arch: %s\n",gen->name);
134 return; 134 return;
135 } 135 }
136 /* Code below assumes the generator is on a map, as it tries 136 /* Code below assumes the generator is on a map, as it tries
137 * to place the monster on the map. So if the generator 137 * to place the monster on the map. So if the generator
138 * isn't on a map, complain and exit. 138 * isn't on a map, complain and exit.
139 */ 139 */
140 if (gen->map == NULL) { 140 if (gen->map == NULL) {
141 //LOG(llevError,"Generator (%s) not on a map?\n", gen->name); 141 //LOG(llevError,"Generator (%s) not on a map?\n", gen->name);
142 return; 142 return;
143 } 143 }
144 i=find_free_spot(&at->clone,gen->map,gen->x,gen->y,1,9); 144 i=find_free_spot(&at->clone,gen->map,gen->x,gen->y,1,9);
145 if (i==-1) return; 145 if (i==-1) return;
146 while(at!=NULL) { 146 while(at!=NULL) {
147 op=arch_to_object(at); 147 op=arch_to_object(at);
148 op->x=gen->x+freearr_x[i]+at->clone.x; 148 op->x=gen->x+freearr_x[i]+at->clone.x;
149 op->y=gen->y+freearr_y[i]+at->clone.y; 149 op->y=gen->y+freearr_y[i]+at->clone.y;
150 150
151 if(head!=NULL) 151 if(head!=NULL)
152 op->head=head,prev->more=op; 152 op->head=head,prev->more=op;
153 153
154 if (rndm(0, 9)) generate_artifact(op, gen->map->difficulty); 154 if (rndm(0, 9)) generate_artifact(op, gen->map->difficulty);
155 insert_ob_in_map(op,gen->map,gen,0); 155 insert_ob_in_map(op,gen->map,gen,0);
156 if (QUERY_FLAG(op, FLAG_FREED)) return; 156 if (QUERY_FLAG(op, FLAG_FREED)) return;
157 if(HAS_RANDOM_ITEMS(op)) 157 if(HAS_RANDOM_ITEMS(op))
158 create_treasure(op->randomitems,op,GT_APPLY, 158 create_treasure(op->randomitems,op,GT_APPLY,
159 gen->map->difficulty,0); 159 gen->map->difficulty,0);
160 if(head==NULL) 160 if(head==NULL)
161 head=op; 161 head=op;
162 prev=op; 162 prev=op;
163 at=at->more; 163 at=at->more;
164 } 164 }
165} 165}
166 166
167void generate_monster(object *gen) { 167void generate_monster(object *gen) {
168 168
177 177
178void remove_force(object *op) { 178void remove_force(object *op) {
179 if (--op->duration > 0) return; 179 if (--op->duration > 0) return;
180 180
181 switch (op->subtype) { 181 switch (op->subtype) {
182 case FORCE_CONFUSION: 182 case FORCE_CONFUSION:
183 if(op->env!=NULL) { 183 if(op->env!=NULL) {
184 CLEAR_FLAG(op->env, FLAG_CONFUSED); 184 CLEAR_FLAG(op->env, FLAG_CONFUSED);
185 new_draw_info(NDI_UNIQUE, 0,op->env, "You regain your senses.\n"); 185 new_draw_info(NDI_UNIQUE, 0,op->env, "You regain your senses.\n");
186 } 186 }
187 187
188 default: 188 default:
189 if(op->env!=NULL) { 189 if(op->env!=NULL) {
190 CLEAR_FLAG(op, FLAG_APPLIED); 190 CLEAR_FLAG(op, FLAG_APPLIED);
191 change_abil(op->env,op); 191 change_abil(op->env,op);
192 fix_player(op->env); 192 fix_player(op->env);
193 } 193 }
194 } 194 }
195 remove_ob(op); 195 remove_ob(op);
196 free_object(op); 196 free_object(op);
197} 197}
198 198
239 239
240void move_gate(object *op) { /* 1 = going down, 0 = goind up */ 240void move_gate(object *op) { /* 1 = going down, 0 = goind up */
241 object *tmp; 241 object *tmp;
242 242
243 if(op->stats.wc < 0 || (int)op->stats.wc >= NUM_ANIMATIONS(op)) { 243 if(op->stats.wc < 0 || (int)op->stats.wc >= NUM_ANIMATIONS(op)) {
244 LOG(llevError,"Gate error: animation was %d, max=%d\n",op->stats.wc, 244 LOG(llevError,"Gate error: animation was %d, max=%d\n",op->stats.wc,
245 NUM_ANIMATIONS(op)); 245 NUM_ANIMATIONS(op));
246 dump_object(op); 246 dump_object(op);
247 LOG(llevError,"%s\n",errmsg); 247 LOG(llevError,"%s\n",errmsg);
248 op->stats.wc=0; 248 op->stats.wc=0;
249 } 249 }
250 250
251 /* We're going down */ 251 /* We're going down */
252 if(op->value) { 252 if(op->value) {
253 if(--op->stats.wc<=0) { /* Reached bottom, let's stop */ 253 if(--op->stats.wc<=0) { /* Reached bottom, let's stop */
254 op->stats.wc=0; 254 op->stats.wc=0;
255 if(op->arch->clone.speed) 255 if(op->arch->clone.speed)
256 op->value=0; 256 op->value=0;
257 else { 257 else {
258 op->speed = 0; 258 op->speed = 0;
259 update_ob_speed(op); 259 update_ob_speed(op);
260 } 260 }
261 } 261 }
262 if((int)op->stats.wc < (NUM_ANIMATIONS(op)/2+1)) { 262 if((int)op->stats.wc < (NUM_ANIMATIONS(op)/2+1)) {
263 op->move_block = 0; 263 op->move_block = 0;
264 CLEAR_FLAG(op, FLAG_BLOCKSVIEW); 264 CLEAR_FLAG(op, FLAG_BLOCKSVIEW);
265 update_all_los(op->map, op->x, op->y); 265 update_all_los(op->map, op->x, op->y);
266 } 266 }
267 SET_ANIMATION(op, op->stats.wc); 267 SET_ANIMATION(op, op->stats.wc);
268 update_object(op,UP_OBJ_CHANGE); 268 update_object(op,UP_OBJ_CHANGE);
269 return; 269 return;
270 } 270 }
271 271
272 /* We're going up */ 272 /* We're going up */
273 273
274 /* First, lets see if we are already at the top */ 274 /* First, lets see if we are already at the top */
275 if((unsigned char) op->stats.wc==(NUM_ANIMATIONS(op)-1)) { 275 if((unsigned char) op->stats.wc==(NUM_ANIMATIONS(op)-1)) {
276 276
277 /* Check to make sure that only non pickable and non rollable 277 /* Check to make sure that only non pickable and non rollable
278 * objects are above the gate. If so, we finish closing the gate, 278 * objects are above the gate. If so, we finish closing the gate,
279 * otherwise, we fall through to the code below which should lower 279 * otherwise, we fall through to the code below which should lower
280 * the gate slightly. 280 * the gate slightly.
281 */ 281 */
282 282
283 for (tmp=op->above; tmp!=NULL; tmp=tmp->above) 283 for (tmp=op->above; tmp!=NULL; tmp=tmp->above)
284 if (!QUERY_FLAG(tmp, FLAG_NO_PICK) 284 if (!QUERY_FLAG(tmp, FLAG_NO_PICK)
285 || QUERY_FLAG(tmp, FLAG_CAN_ROLL) 285 || QUERY_FLAG(tmp, FLAG_CAN_ROLL)
286 || QUERY_FLAG(tmp, FLAG_ALIVE)) 286 || QUERY_FLAG(tmp, FLAG_ALIVE))
287 break; 287 break;
288 288
289 if (tmp==NULL) { 289 if (tmp==NULL) {
290 if(op->arch->clone.speed) 290 if(op->arch->clone.speed)
291 op->value=1; 291 op->value=1;
292 else { 292 else {
293 op->speed = 0; 293 op->speed = 0;
294 update_ob_speed(op); /* Reached top, let's stop */ 294 update_ob_speed(op); /* Reached top, let's stop */
295 } 295 }
296 return; 296 return;
297 } 297 }
298 } 298 }
299 299
300 if(op->stats.food) { /* The gate is going temporarily down */ 300 if(op->stats.food) { /* The gate is going temporarily down */
301 if(--op->stats.wc<=0) { /* Gone all the way down? */ 301 if(--op->stats.wc<=0) { /* Gone all the way down? */
302 op->stats.food=0; /* Then let's try again */ 302 op->stats.food=0; /* Then let's try again */
303 op->stats.wc=0; 303 op->stats.wc=0;
304 } 304 }
305 } else { /* The gate is still going up */ 305 } else { /* The gate is still going up */
306 op->stats.wc++; 306 op->stats.wc++;
307 307
308 if((int)op->stats.wc >= (NUM_ANIMATIONS(op))) 308 if((int)op->stats.wc >= (NUM_ANIMATIONS(op)))
309 op->stats.wc=(signed char)NUM_ANIMATIONS(op)-1; 309 op->stats.wc=(signed char)NUM_ANIMATIONS(op)-1;
310 310
311 /* If there is something on top of the gate, we try to roll it off. 311 /* If there is something on top of the gate, we try to roll it off.
312 * If a player/monster, we don't roll, we just hit them with damage 312 * If a player/monster, we don't roll, we just hit them with damage
313 */ 313 */
314 if((int)op->stats.wc >= NUM_ANIMATIONS(op)/2) { 314 if((int)op->stats.wc >= NUM_ANIMATIONS(op)/2) {
315 /* Halfway or further, check blocks */ 315 /* Halfway or further, check blocks */
316 /* First, get the top object on the square. */ 316 /* First, get the top object on the square. */
317 for(tmp=op->above;tmp!=NULL && tmp->above!=NULL;tmp=tmp->above); 317 for(tmp=op->above;tmp!=NULL && tmp->above!=NULL;tmp=tmp->above);
318 318
319 if(tmp!=NULL) { 319 if(tmp!=NULL) {
320 if(QUERY_FLAG(tmp, FLAG_ALIVE)) { 320 if(QUERY_FLAG(tmp, FLAG_ALIVE)) {
321 hit_player(tmp, random_roll(1, op->stats.dam, tmp, PREFER_LOW), op, AT_PHYSICAL, 1); 321 hit_player(tmp, random_roll(1, op->stats.dam, tmp, PREFER_LOW), op, AT_PHYSICAL, 1);
322 if(tmp->type==PLAYER) 322 if(tmp->type==PLAYER)
323 new_draw_info_format(NDI_UNIQUE, 0, tmp, 323 new_draw_info_format(NDI_UNIQUE, 0, tmp,
324 "You are crushed by the %s!",op->name); 324 "You are crushed by the %s!", &op->name);
325 } else 325 } else
326 /* If the object is not alive, and the object either can 326 /* If the object is not alive, and the object either can
327 * be picked up or the object rolls, move the object 327 * be picked up or the object rolls, move the object
328 * off the gate. 328 * off the gate.
329 */ 329 */
330 if(!QUERY_FLAG(tmp, FLAG_ALIVE) 330 if(!QUERY_FLAG(tmp, FLAG_ALIVE)
331 && (!QUERY_FLAG(tmp, FLAG_NO_PICK) 331 && (!QUERY_FLAG(tmp, FLAG_NO_PICK)
332 ||QUERY_FLAG(tmp,FLAG_CAN_ROLL))) { 332 ||QUERY_FLAG(tmp,FLAG_CAN_ROLL))) {
333 /* If it has speed, it should move itself, otherwise: */ 333 /* If it has speed, it should move itself, otherwise: */
334 int i=find_free_spot(tmp,op->map,op->x,op->y,1,9); 334 int i=find_free_spot(tmp,op->map,op->x,op->y,1,9);
335 335
336 /* If there is a free spot, move the object someplace */ 336 /* If there is a free spot, move the object someplace */
337 if (i!=-1) { 337 if (i!=-1) {
338 remove_ob(tmp); 338 remove_ob(tmp);
339 tmp->x+=freearr_x[i],tmp->y+=freearr_y[i]; 339 tmp->x+=freearr_x[i],tmp->y+=freearr_y[i];
340 insert_ob_in_map(tmp,op->map,op,0); 340 insert_ob_in_map(tmp,op->map,op,0);
341 } 341 }
342 } 342 }
343 } 343 }
344 344
345 /* See if there is still anything blocking the gate */ 345 /* See if there is still anything blocking the gate */
346 for (tmp=op->above; tmp!=NULL; tmp=tmp->above) 346 for (tmp=op->above; tmp!=NULL; tmp=tmp->above)
347 if (!QUERY_FLAG(tmp, FLAG_NO_PICK) 347 if (!QUERY_FLAG(tmp, FLAG_NO_PICK)
348 || QUERY_FLAG(tmp, FLAG_CAN_ROLL) 348 || QUERY_FLAG(tmp, FLAG_CAN_ROLL)
349 || QUERY_FLAG(tmp, FLAG_ALIVE)) 349 || QUERY_FLAG(tmp, FLAG_ALIVE))
350 break; 350 break;
351 351
352 /* IF there is, start putting the gate down */ 352 /* IF there is, start putting the gate down */
353 if(tmp) { 353 if(tmp) {
354 op->stats.food=1; 354 op->stats.food=1;
355 } else { 355 } else {
356 op->move_block = MOVE_ALL; 356 op->move_block = MOVE_ALL;
357 if(!op->arch->clone.stats.ac) 357 if(!op->arch->clone.stats.ac)
358 SET_FLAG(op, FLAG_BLOCKSVIEW); 358 SET_FLAG(op, FLAG_BLOCKSVIEW);
359 update_all_los(op->map, op->x, op->y); 359 update_all_los(op->map, op->x, op->y);
360 } 360 }
361 } /* gate is halfway up */ 361 } /* gate is halfway up */
362 362
363 SET_ANIMATION(op, op->stats.wc); 363 SET_ANIMATION(op, op->stats.wc);
364 update_object(op,UP_OBJ_CHANGE); 364 update_object(op,UP_OBJ_CHANGE);
365 } /* gate is going up */ 365 } /* gate is going up */
366} 366}
367 367
368/* hp : how long door is open/closed 368/* hp : how long door is open/closed
369 * maxhp : initial value for hp 369 * maxhp : initial value for hp
380 return; 380 return;
381 } 381 }
382 if (--op->stats.hp <= 0) { /* keep gate down */ 382 if (--op->stats.hp <= 0) { /* keep gate down */
383 move_gate(op); 383 move_gate(op);
384 if (op->value != v) { /* ready ? */ 384 if (op->value != v) { /* ready ? */
385 op->speed = 0; 385 op->speed = 0;
386 update_ob_speed(op); 386 update_ob_speed(op);
387 } 387 }
388 } 388 }
389} 389}
390 390
391/* slaying: name of the thing the detector is to look for 391/* slaying: name of the thing the detector is to look for
401 int last = op->value; 401 int last = op->value;
402 int detected; 402 int detected;
403 detected = 0; 403 detected = 0;
404 404
405 for(tmp = get_map_ob(op->map,op->x,op->y);tmp!=NULL&&!detected;tmp=tmp->above) { 405 for(tmp = get_map_ob(op->map,op->x,op->y);tmp!=NULL&&!detected;tmp=tmp->above) {
406 object *tmp2; 406 object *tmp2;
407 if(op->stats.hp) { 407 if(op->stats.hp) {
408 for(tmp2= tmp->inv;tmp2;tmp2=tmp2->below) { 408 for(tmp2= tmp->inv;tmp2;tmp2=tmp2->below) {
409 if(op->slaying && !strcmp(op->slaying,tmp->name)) detected=1; 409 if(op->slaying && !strcmp(op->slaying,tmp->name)) detected=1;
410 if(tmp2->type==FORCE &&tmp2->slaying && !strcmp(tmp2->slaying,op->slaying)) detected=1; 410 if(tmp2->type==FORCE &&tmp2->slaying && !strcmp(tmp2->slaying,op->slaying)) detected=1;
411 } 411 }
412 } 412 }
413 if (op->slaying && !strcmp(op->slaying,tmp->name)) { 413 if (op->slaying && !strcmp(op->slaying,tmp->name)) {
414 detected = 1; 414 detected = 1;
415 } 415 }
416 else if (tmp->type==SPECIAL_KEY && tmp->slaying==op->slaying) 416 else if (tmp->type==SPECIAL_KEY && tmp->slaying==op->slaying)
417 detected=1; 417 detected=1;
418 } 418 }
419 419
420 /* the detector sets the button if detection is found */ 420 /* the detector sets the button if detection is found */
421 if(op->stats.sp == 1) { 421 if(op->stats.sp == 1) {
422 if(detected && last == 0) { 422 if(detected && last == 0) {
423 op->value = 1; 423 op->value = 1;
424 push_button(op); 424 push_button(op);
425 } 425 }
426 if(!detected && last == 1) { 426 if(!detected && last == 1) {
427 op->value = 0; 427 op->value = 0;
428 push_button(op); 428 push_button(op);
429 } 429 }
430 } 430 }
431 else { /* in this case, we unset buttons */ 431 else { /* in this case, we unset buttons */
432 if(detected && last == 1) { 432 if(detected && last == 1) {
433 op->value = 0; 433 op->value = 0;
434 push_button(op); 434 push_button(op);
435 } 435 }
436 if(!detected && last == 0) { 436 if(!detected && last == 0) {
437 op->value = 1; 437 op->value = 1;
438 push_button(op); 438 push_button(op);
439 } 439 }
440 } 440 }
441} 441}
442 442
443 443
444void animate_trigger (object *op) 444void animate_trigger (object *op)
454 454
455void move_hole(object *op) { /* 1 = opening, 0 = closing */ 455void move_hole(object *op) { /* 1 = opening, 0 = closing */
456 object *next,*tmp; 456 object *next,*tmp;
457 457
458 if(op->value) { /* We're opening */ 458 if(op->value) { /* We're opening */
459 if(--op->stats.wc<=0) { /* Opened, let's stop */ 459 if(--op->stats.wc<=0) { /* Opened, let's stop */
460 op->stats.wc=0; 460 op->stats.wc=0;
461 op->speed = 0; 461 op->speed = 0;
462 update_ob_speed(op); 462 update_ob_speed(op);
463 463
464 /* Hard coding this makes sense for holes I suppose */ 464 /* Hard coding this makes sense for holes I suppose */
465 op->move_on = MOVE_WALK; 465 op->move_on = MOVE_WALK;
466 for (tmp=op->above; tmp!=NULL; tmp=next) { 466 for (tmp=op->above; tmp!=NULL; tmp=next) {
467 next=tmp->above; 467 next=tmp->above;
468 move_apply(op,tmp,tmp); 468 move_apply(op,tmp,tmp);
469 } 469 }
470 } 470 }
471 SET_ANIMATION(op, op->stats.wc); 471 SET_ANIMATION(op, op->stats.wc);
472 update_object(op,UP_OBJ_FACE); 472 update_object(op,UP_OBJ_FACE);
473 return; 473 return;
474 } 474 }
475 /* We're closing */ 475 /* We're closing */
476 op->move_on = 0; 476 op->move_on = 0;
477 477
478 op->stats.wc++; 478 op->stats.wc++;
479 if((int)op->stats.wc >= NUM_ANIMATIONS(op)) 479 if((int)op->stats.wc >= NUM_ANIMATIONS(op))
480 op->stats.wc=NUM_ANIMATIONS(op)-1; 480 op->stats.wc=NUM_ANIMATIONS(op)-1;
481 SET_ANIMATION(op, op->stats.wc); 481 SET_ANIMATION(op, op->stats.wc);
482 update_object(op,UP_OBJ_FACE); 482 update_object(op,UP_OBJ_FACE);
483 if((unsigned char) op->stats.wc==(NUM_ANIMATIONS(op)-1)) { 483 if((unsigned char) op->stats.wc==(NUM_ANIMATIONS(op)-1)) {
484 op->speed = 0; 484 op->speed = 0;
485 update_ob_speed(op); /* closed, let's stop */ 485 update_ob_speed(op); /* closed, let's stop */
486 return; 486 return;
487 } 487 }
488} 488}
489 489
490 490
491/* stop_item() returns a pointer to the stopped object. The stopped object 491/* stop_item() returns a pointer to the stopped object. The stopped object
545 545
546 546
547object *fix_stopped_arrow (object *op) 547object *fix_stopped_arrow (object *op)
548{ 548{
549 if(rndm(0, 99) < op->stats.food) { 549 if(rndm(0, 99) < op->stats.food) {
550 /* Small chance of breaking */ 550 /* Small chance of breaking */
551 remove_ob (op); 551 remove_ob (op);
552 free_object(op); 552 free_object(op);
553 return NULL; 553 return NULL;
554 } 554 }
555 555
556 op->direction=0; 556 op->direction=0;
557 op->move_on=0; 557 op->move_on=0;
558 op->move_type=0; 558 op->move_type=0;
559 op->speed = 0; 559 op->speed = 0;
560 update_ob_speed(op); 560 update_ob_speed(op);
561 op->stats.wc = op->stats.sp; 561 op->stats.wc = op->stats.sp;
562 op->stats.dam= op->stats.hp; 562 op->stats.dam= op->stats.hp;
563 op->attacktype = op->stats.grace; 563 op->attacktype = op->stats.grace;
564 if (op->slaying != NULL) 564 op->slaying = 0;
565 FREE_AND_CLEAR_STR(op->slaying); 565 op->skill = 0;
566
567 if (op->skill != NULL)
568 FREE_AND_CLEAR_STR(op->skill);
569 566
570 if (op->spellarg != NULL) { 567 if (op->spellarg != NULL) {
571 op->slaying = add_string(op->spellarg); 568 op->slaying = op->spellarg;
572 free(op->spellarg); 569 free(op->spellarg);
573 op->spellarg = NULL; 570 op->spellarg = NULL;
574 } else 571 } else
575 op->slaying = NULL; 572 op->slaying = NULL;
576 573
577 /* Reset these to zero, so that CAN_MERGE will work properly */ 574 /* Reset these to zero, so that CAN_MERGE will work properly */
578 op->spellarg = NULL; 575 op->spellarg = NULL;
579 op->stats.sp = 0; 576 op->stats.sp = 0;
580 op->stats.hp = 0; 577 op->stats.hp = 0;
594 * from maps or inventories), or NULL if was destroyed. 591 * from maps or inventories), or NULL if was destroyed.
595 */ 592 */
596 593
597static void stop_arrow (object *op) 594static void stop_arrow (object *op)
598{ 595{
599 /* Lauwenmark: Handle for plugin stop event */ 596 if (INVOKE_OBJECT (STOP, op))
600 execute_event(op, EVENT_STOP,NULL,NULL,NULL,SCRIPT_FIX_NOTHING); 597 return;
598
601 if (op->inv) { 599 if (op->inv) {
602 object *payload = op->inv; 600 object *payload = op->inv;
603 remove_ob (payload); 601 remove_ob (payload);
604 clear_owner(payload); 602 clear_owner(payload);
605 insert_ob_in_map (payload, op->map, payload,0); 603 insert_ob_in_map (payload, op->map, payload,0);
606 remove_ob (op); 604 remove_ob (op);
607 free_object (op); 605 free_object (op);
608 } else { 606 } else {
609 op = fix_stopped_arrow (op); 607 op = fix_stopped_arrow (op);
610 if (op) 608 if (op)
611 merge_ob (op, NULL); 609 merge_ob (op, NULL);
612 } 610 }
620 sint16 new_x, new_y; 618 sint16 new_x, new_y;
621 int was_reflected, mflags; 619 int was_reflected, mflags;
622 mapstruct *m; 620 mapstruct *m;
623 621
624 if(op->map==NULL) { 622 if(op->map==NULL) {
625 LOG (llevError, "BUG: Arrow had no map.\n"); 623 LOG (llevError, "BUG: Arrow had no map.\n");
626 remove_ob(op); 624 remove_ob(op);
627 free_object(op); 625 free_object(op);
628 return; 626 return;
629 } 627 }
630 628
631 /* we need to stop thrown objects at some point. Like here. */ 629 /* we need to stop thrown objects at some point. Like here. */
632 if(op->type==THROWN_OBJ) { 630 if(op->type==THROWN_OBJ) {
633 /* If the object that the THROWN_OBJ encapsulates disappears, 631 /* If the object that the THROWN_OBJ encapsulates disappears,
634 * we need to have this object go away also - otherwise, you get 632 * we need to have this object go away also - otherwise, you get
635 * left over remnants on the map. Where this currently happens 633 * left over remnants on the map. Where this currently happens
636 * is if the player throws a bomb - the bomb explodes on its own, 634 * is if the player throws a bomb - the bomb explodes on its own,
637 * but this object sticks around. We could handle the cleanup in the 635 * but this object sticks around. We could handle the cleanup in the
638 * bomb code, but there are potential other cases where that could happen, 636 * bomb code, but there are potential other cases where that could happen,
639 * and it is easy enough to clean it up here. 637 * and it is easy enough to clean it up here.
640 */ 638 */
641 if (op->inv == NULL) { 639 if (op->inv == NULL) {
642 remove_ob(op); 640 remove_ob(op);
643 free_object(op); 641 free_object(op);
644 return; 642 return;
645 } 643 }
646 if(op->last_sp-- < 0) { 644 if(op->last_sp-- < 0) {
647 stop_arrow (op); 645 stop_arrow (op);
648 return; 646 return;
649 } 647 }
650 } 648 }
651 649
652 /* if the arrow is moving too slow.. stop it. 0.5 was chosen as lower 650 /* if the arrow is moving too slow.. stop it. 0.5 was chosen as lower
653 values look rediculous. */ 651 values look rediculous. */
654 if (op->speed < 0.5 && op->type==ARROW) { 652 if (op->speed < 0.5 && op->type==ARROW) {
655 stop_arrow(op); 653 stop_arrow(op);
656 return; 654 return;
657 } 655 }
658 656
659 /* Calculate target map square */ 657 /* Calculate target map square */
660 new_x = op->x + DIRX(op); 658 new_x = op->x + DIRX(op);
661 new_y = op->y + DIRY(op); 659 new_y = op->y + DIRY(op);
663 661
664 m = op->map; 662 m = op->map;
665 mflags = get_map_flags(m, &m, new_x, new_y, &new_x, &new_y); 663 mflags = get_map_flags(m, &m, new_x, new_y, &new_x, &new_y);
666 664
667 if (mflags & P_OUT_OF_MAP) { 665 if (mflags & P_OUT_OF_MAP) {
668 stop_arrow(op); 666 stop_arrow(op);
669 return; 667 return;
670 } 668 }
671 669
672 /* only need to look for living creatures if this flag is set */ 670 /* only need to look for living creatures if this flag is set */
673 if (mflags & P_IS_ALIVE) { 671 if (mflags & P_IS_ALIVE) {
674 for (tmp = get_map_ob(m, new_x, new_y); tmp != NULL; tmp=tmp->above) 672 for (tmp = get_map_ob(m, new_x, new_y); tmp != NULL; tmp=tmp->above)
675 if (QUERY_FLAG(tmp, FLAG_ALIVE)) break; 673 if (QUERY_FLAG(tmp, FLAG_ALIVE)) break;
676 674
677 675
678 /* Not really fair, but don't let monsters hit themselves with 676 /* Not really fair, but don't let monsters hit themselves with
679 * their own arrow - this can be because they fire it then 677 * their own arrow - this can be because they fire it then
680 * move into it. 678 * move into it.
681 */ 679 */
682 680
683 if (tmp != NULL && tmp != op->owner) { 681 if (tmp != NULL && tmp != op->owner) {
684 /* Found living object, but it is reflecting the missile. Update 682 /* Found living object, but it is reflecting the missile. Update
685 * as below. (Note that for living creatures there is a small 683 * as below. (Note that for living creatures there is a small
686 * chance that reflect_missile fails.) 684 * chance that reflect_missile fails.)
687 */ 685 */
688 686
689 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) && 687 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) &&
690 (rndm(0, 99)) < (90-op->level/10)) { 688 (rndm(0, 99)) < (90-op->level/10)) {
691 689
692 int number = op->face->number; 690 int number = op->face->number;
693 691
694 op->direction = absdir (op->direction + 4); 692 op->direction = absdir (op->direction + 4);
695 op->state = 0; 693 op->state = 0;
696 if (GET_ANIM_ID (op)) { 694 if (GET_ANIM_ID (op)) {
697 number += 4; 695 number += 4;
698 if (number > GET_ANIMATION (op, 8)) 696 if (number > GET_ANIMATION (op, 8))
699 number -= 8; 697 number -= 8;
700 op->face = &new_faces[number]; 698 op->face = &new_faces[number];
701 } 699 }
702 was_reflected = 1; /* skip normal movement calculations */ 700 was_reflected = 1; /* skip normal movement calculations */
703 } 701 }
704 else { 702 else {
705 /* Attack the object. */ 703 /* Attack the object. */
706 op = hit_with_arrow (op, tmp); 704 op = hit_with_arrow (op, tmp);
707 if (op == NULL) 705 if (op == NULL)
708 return; 706 return;
709 } 707 }
710 } /* if this is not hitting its owner */ 708 } /* if this is not hitting its owner */
711 } /* if there is something alive on this space */ 709 } /* if there is something alive on this space */
712 710
713 711
714 if (OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, new_x, new_y))) { 712 if (OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, new_x, new_y))) {
715 int retry=0; 713 int retry=0;
716 714
717 /* if the object doesn't reflect, stop the arrow from moving 715 /* if the object doesn't reflect, stop the arrow from moving
718 * note that this code will now catch cases where a monster is 716 * note that this code will now catch cases where a monster is
719 * on a wall but has reflecting - the arrow won't reflect. 717 * on a wall but has reflecting - the arrow won't reflect.
720 * Mapmakers shouldn't put monsters on top of wall in the first 718 * Mapmakers shouldn't put monsters on top of wall in the first
721 * place, so I don't consider that a problem. 719 * place, so I don't consider that a problem.
722 */ 720 */
723 if(!QUERY_FLAG(op, FLAG_REFLECTING) || !(rndm(0, 19))) { 721 if(!QUERY_FLAG(op, FLAG_REFLECTING) || !(rndm(0, 19))) {
724 stop_arrow (op); 722 stop_arrow (op);
725 return; 723 return;
726 } else { 724 } else {
727 /* If one of the major directions (n,s,e,w), just reverse it */ 725 /* If one of the major directions (n,s,e,w), just reverse it */
728 if(op->direction&1) { 726 if(op->direction&1) {
729 op->direction=absdir(op->direction+4); 727 op->direction=absdir(op->direction+4);
730 retry=1; 728 retry=1;
731 } 729 }
732 /* There were two blocks with identical code - 730 /* There were two blocks with identical code -
733 * use this retry here to make this one block 731 * use this retry here to make this one block
734 * that did the same thing. 732 * that did the same thing.
735 */ 733 */
736 while (retry<2) { 734 while (retry<2) {
737 int left, right, mflags; 735 int left, right, mflags;
738 mapstruct *m1; 736 mapstruct *m1;
739 sint16 x1, y1; 737 sint16 x1, y1;
740 738
741 retry++; 739 retry++;
742 740
743 /* Need to check for P_OUT_OF_MAP: if the arrow is tavelling 741 /* Need to check for P_OUT_OF_MAP: if the arrow is tavelling
744 * over a corner in a tiled map, it is possible that 742 * over a corner in a tiled map, it is possible that
745 * op->direction is within an adjacent map but either 743 * op->direction is within an adjacent map but either
746 * op->direction-1 or op->direction+1 does not exist. 744 * op->direction-1 or op->direction+1 does not exist.
747 */ 745 */
748 mflags = get_map_flags(op->map,&m1, op->x+freearr_x[absdir(op->direction-1)], 746 mflags = get_map_flags(op->map,&m1, op->x+freearr_x[absdir(op->direction-1)],
749 op->y+freearr_y[absdir(op->direction-1)], &x1, &y1); 747 op->y+freearr_y[absdir(op->direction-1)], &x1, &y1);
750 left = (mflags & P_OUT_OF_MAP) ? 0 : OB_TYPE_MOVE_BLOCK(op, (GET_MAP_MOVE_BLOCK(m1, x1, y1))); 748 left = (mflags & P_OUT_OF_MAP) ? 0 : OB_TYPE_MOVE_BLOCK(op, (GET_MAP_MOVE_BLOCK(m1, x1, y1)));
751 749
752 mflags = get_map_flags(op->map,&m1, op->x+freearr_x[absdir(op->direction+1)], 750 mflags = get_map_flags(op->map,&m1, op->x+freearr_x[absdir(op->direction+1)],
753 op->y+freearr_y[absdir(op->direction+1)], &x1, &y1); 751 op->y+freearr_y[absdir(op->direction+1)], &x1, &y1);
754 right = (mflags & P_OUT_OF_MAP) ? 0 : OB_TYPE_MOVE_BLOCK(op, (GET_MAP_MOVE_BLOCK(m1, x1, y1))); 752 right = (mflags & P_OUT_OF_MAP) ? 0 : OB_TYPE_MOVE_BLOCK(op, (GET_MAP_MOVE_BLOCK(m1, x1, y1)));
755 753
756 if(left==right) 754 if(left==right)
757 op->direction=absdir(op->direction+4); 755 op->direction=absdir(op->direction+4);
758 else if(left) 756 else if(left)
759 op->direction=absdir(op->direction+2); 757 op->direction=absdir(op->direction+2);
760 else if(right) 758 else if(right)
761 op->direction=absdir(op->direction-2); 759 op->direction=absdir(op->direction-2);
762 760
763 mflags = get_map_flags(op->map,&m1, op->x+DIRX(op),op->y+DIRY(op), &x1, &y1); 761 mflags = get_map_flags(op->map,&m1, op->x+DIRX(op),op->y+DIRY(op), &x1, &y1);
764 762
765 /* If this space is not out of the map and not blocked, valid space - 763 /* If this space is not out of the map and not blocked, valid space -
766 * don't need to retry again. 764 * don't need to retry again.
767 */ 765 */
768 if (!(mflags & P_OUT_OF_MAP) && 766 if (!(mflags & P_OUT_OF_MAP) &&
769 !OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m1, x1, y1))) break; 767 !OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m1, x1, y1))) break;
770 768
771 } 769 }
772 /* Couldn't find a direction to move the arrow to - just 770 /* Couldn't find a direction to move the arrow to - just
773 * top it from moving. 771 * top it from moving.
774 */ 772 */
775 if (retry==2) { 773 if (retry==2) {
776 stop_arrow (op); 774 stop_arrow (op);
777 return; 775 return;
778 } 776 }
779 /* update object image for new facing */ 777 /* update object image for new facing */
780 /* many thrown objects *don't* have more than one face */ 778 /* many thrown objects *don't* have more than one face */
781 if(GET_ANIM_ID(op)) 779 if(GET_ANIM_ID(op))
782 SET_ANIMATION(op, op->direction); 780 SET_ANIMATION(op, op->direction);
783 } /* object is reflected */ 781 } /* object is reflected */
784 } /* object ran into a wall */ 782 } /* object ran into a wall */
785 783
786 /* Move the arrow. */ 784 /* Move the arrow. */
787 remove_ob (op); 785 remove_ob (op);
788 op->x = new_x; 786 op->x = new_x;
802void change_object(object *op) { /* Doesn`t handle linked objs yet */ 800void change_object(object *op) { /* Doesn`t handle linked objs yet */
803 object *tmp,*env,*pl; 801 object *tmp,*env,*pl;
804 int i,j; 802 int i,j;
805 803
806 if(op->other_arch==NULL) { 804 if(op->other_arch==NULL) {
807 LOG(llevError,"Change object (%s) without other_arch error.\n", op->name); 805 LOG(llevError,"Change object (%s) without other_arch error.\n", &op->name);
808 return; 806 return;
809 } 807 }
810 808
811 /* In non-living items only change when food value is 0 */ 809 /* In non-living items only change when food value is 0 */
812 if(!QUERY_FLAG(op,FLAG_ALIVE)) { 810 if(!QUERY_FLAG(op,FLAG_ALIVE)) {
813 if(op->stats.food-- > 0) return; 811 if(op->stats.food-- > 0) return;
814 else op->stats.food=1; /* so 1 other_arch is made */ 812 else op->stats.food=1; /* so 1 other_arch is made */
815 } 813 }
816 env=op->env; 814 env=op->env;
817 remove_ob(op); 815 remove_ob(op);
818 for(i=0;i<NROFNEWOBJS(op);i++) { 816 for(i=0;i<NROFNEWOBJS(op);i++) {
819 tmp=arch_to_object(op->other_arch); 817 tmp=arch_to_object(op->other_arch);
820 if (op->type == LAMP) 818 if (op->type == LAMP)
821 tmp->stats.food = op->stats.food-1; 819 tmp->stats.food = op->stats.food-1;
822 tmp->stats.hp=op->stats.hp; /* The only variable it keeps. */ 820 tmp->stats.hp=op->stats.hp; /* The only variable it keeps. */
823 if(env) { 821 if(env) {
824 tmp->x=env->x,tmp->y=env->y; 822 tmp->x=env->x,tmp->y=env->y;
825 tmp=insert_ob_in_ob(tmp,env); 823 tmp=insert_ob_in_ob(tmp,env);
826 /* If this object is the players inventory, we need to tell the 824 /* If this object is the players inventory, we need to tell the
827 * client of the change. Insert_ob_in_map takes care of the 825 * client of the change. Insert_ob_in_map takes care of the
828 * updating the client, so we don't need to do that below. 826 * updating the client, so we don't need to do that below.
829 */ 827 */
830 if ((pl=is_player_inv(env))!=NULL) { 828 if ((pl=is_player_inv(env))!=NULL) {
831 esrv_del_item(pl->contr, op->count); 829 esrv_del_item(pl->contr, op->count);
832 esrv_send_item(pl, tmp); 830 esrv_send_item(pl, tmp);
833 } 831 }
834 } else { 832 } else {
835 j=find_first_free_spot(tmp,op->map,op->x,op->y); 833 j=find_first_free_spot(tmp,op->map,op->x,op->y);
836 if (j==-1) /* No free spot */ 834 if (j==-1) /* No free spot */
837 free_object(tmp); 835 free_object(tmp);
838 else { 836 else {
839 tmp->x=op->x+freearr_x[j],tmp->y=op->y+freearr_y[j]; 837 tmp->x=op->x+freearr_x[j],tmp->y=op->y+freearr_y[j];
840 insert_ob_in_map(tmp,op->map,op,0); 838 insert_ob_in_map(tmp,op->map,op,0);
841 } 839 }
842 } 840 }
843 } 841 }
844 free_object(op); 842 free_object(op);
845} 843}
846 844
857 if (op->more && FABS(op->more->speed)<MIN_ACTIVE_SPEED) move_teleporter(op->more); 855 if (op->more && FABS(op->more->speed)<MIN_ACTIVE_SPEED) move_teleporter(op->more);
858 856
859 if (op->head) head=op->head; 857 if (op->head) head=op->head;
860 858
861 for (tmp=op->above; tmp!=NULL; tmp=tmp->above) 859 for (tmp=op->above; tmp!=NULL; tmp=tmp->above)
862 if (!QUERY_FLAG(tmp, FLAG_IS_FLOOR)) break; 860 if (!QUERY_FLAG(tmp, FLAG_IS_FLOOR)) break;
863 861
864 /* If nothing above us to move, nothing to do */ 862 /* If nothing above us to move, nothing to do */
865 if (!tmp || QUERY_FLAG(tmp, FLAG_WIZPASS)) return; 863 if (!tmp || QUERY_FLAG(tmp, FLAG_WIZPASS)) return;
866 864
867 if(EXIT_PATH(head)) { 865 if(EXIT_PATH(head)) {
868 if(tmp->type==PLAYER) { 866 if(tmp->type==PLAYER) {
869 /* Lauwenmark: Handle for plugin TRIGGER event */ 867 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp)))
870 if (execute_event(op, EVENT_TRIGGER, tmp, NULL, NULL, SCRIPT_FIX_ALL) != 0)
871 return; 868 return;
869
872 enter_exit(tmp, head); 870 enter_exit(tmp, head);
873 } 871 }
874 else 872 else
875 /* Currently only players can transfer maps */ 873 /* Currently only players can transfer maps */
876 return; 874 return;
877 } 875 }
878 else if(EXIT_X(head)||EXIT_Y(head)) { 876 else if(EXIT_X(head)||EXIT_Y(head)) {
879 if (out_of_map(head->map, EXIT_X(head), EXIT_Y(head))) { 877 if (out_of_map(head->map, EXIT_X(head), EXIT_Y(head))) {
880 LOG(llevError, "Removed illegal teleporter.\n"); 878 LOG(llevError, "Removed illegal teleporter.\n");
881 remove_ob(head); 879 remove_ob(head);
882 free_object(head); 880 free_object(head);
883 return;
884 }
885 /* Lauwenmark: Handle for plugin TRIGGER event */
886 if (execute_event(op, EVENT_TRIGGER, tmp, NULL, NULL, SCRIPT_FIX_ALL) != 0)
887 return; 881 return;
882 }
883 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp)))
884 return;
888 transfer_ob(tmp,EXIT_X(head),EXIT_Y(head),0,head); 885 transfer_ob(tmp,EXIT_X(head),EXIT_Y(head),0,head);
889 } 886 }
890 else { 887 else {
891 /* Random teleporter */ 888 /* Random teleporter */
892 /* Lauwenmark: Handle for plugin TRIGGER event */ 889 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp)))
893 if (execute_event(op, EVENT_TRIGGER, tmp, NULL, NULL, SCRIPT_FIX_ALL) != 0)
894 return; 890 return;
895 teleport(head, TELEPORTER, tmp); 891 teleport(head, TELEPORTER, tmp);
896 } 892 }
897} 893}
898 894
899 895
900/* This object will teleport someone to a different map 896/* This object will teleport someone to a different map
912 908
913 /* This isn't all that great - means that the player_mover 909 /* This isn't all that great - means that the player_mover
914 * needs to be on top. 910 * needs to be on top.
915 */ 911 */
916 if(op->above->type==PLAYER) { 912 if(op->above->type==PLAYER) {
917 /* Lauwenmark: Handle for plugin TRIGGER event */ 913 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (player)))
918 if (execute_event(op, EVENT_TRIGGER,op->above,NULL,NULL,SCRIPT_FIX_NOTHING)!=0)
919 return; 914 return;
920 player=op->above; 915 player=op->above;
921 for(walk=op->inv;walk!=NULL;walk=walk->below) 916 for(walk=op->inv;walk!=NULL;walk=walk->below)
922 apply_changes_to_player(player,walk); 917 apply_changes_to_player(player,walk);
923 918
924 fix_player(player); 919 fix_player(player);
925 esrv_send_inventory(op->above,op->above); 920 esrv_send_inventory(op->above,op->above);
926 esrv_update_item(UPD_FACE, op->above, op->above); 921 esrv_update_item(UPD_FACE, op->above, op->above);
927 922
928 /* update players death & WoR home-position */ 923 /* update players death & WoR home-position */
929 sscanf(EXIT_PATH(op), "%c", &c); 924 sscanf(EXIT_PATH(op), "%c", &c);
930 if (c == '/') { 925 if (c == '/') {
931 strcpy(player->contr->savebed_map, EXIT_PATH(op)); 926 strcpy(player->contr->savebed_map, EXIT_PATH(op));
932 player->contr->bed_x = EXIT_X(op); 927 player->contr->bed_x = EXIT_X(op);
933 player->contr->bed_y = EXIT_Y(op); 928 player->contr->bed_y = EXIT_Y(op);
934 } 929 }
935 else 930 else
936 LOG(llevDebug, 931 LOG(llevDebug,
937 "WARNING: destination '%s' in player_changer must be an absolute path!\n", 932 "WARNING: destination '%s' in player_changer must be an absolute path!\n",
938 EXIT_PATH(op)); 933 &EXIT_PATH(op));
939 934
940 enter_exit(op->above,op); 935 enter_exit(op->above,op);
941 save_player(player, 1); 936 save_player(player, 1);
942 } 937 }
943} 938}
944 939
945/* firewalls fire other spells. 940/* firewalls fire other spells.
946 * The direction of the wall is stored in op->stats.sp. 941 * The direction of the wall is stored in op->stats.sp.
948 */ 943 */
949void move_firewall(object *op) { 944void move_firewall(object *op) {
950 object *spell; 945 object *spell;
951 946
952 if ( ! op->map) 947 if ( ! op->map)
953 return; /* dm has created a firewall in his inventory */ 948 return; /* dm has created a firewall in his inventory */
954 949
955 spell = op->inv; 950 spell = op->inv;
956 if (!spell || spell->type != SPELL) spell=&op->other_arch->clone; 951 if (!spell || spell->type != SPELL) spell=&op->other_arch->clone;
957 if (!spell) { 952 if (!spell) {
958 LOG(llevError,"move_firewall: no spell specified (%s, %s, %d, %d)\n", 953 LOG(llevError,"move_firewall: no spell specified (%s, %s, %d, %d)\n",
959 op->name, op->map->name, op->x, op->y); 954 &op->name, op->map->name, op->x, op->y);
960 return; 955 return;
961 } 956 }
962 957
963 cast_spell(op,op,op->stats.sp?op->stats.sp:rndm(1, 8),spell, NULL); 958 cast_spell(op,op,op->stats.sp?op->stats.sp:rndm(1, 8),spell, NULL);
964} 959}
965 960
981 976
982 /* Determine direction now for random movers so we do the right thing */ 977 /* Determine direction now for random movers so we do the right thing */
983 if (!dir) dir=rndm(1, 8); 978 if (!dir) dir=rndm(1, 8);
984 979
985 for(victim=get_map_ob(op->map,op->x,op->y); victim !=NULL; victim=victim->above) { 980 for(victim=get_map_ob(op->map,op->x,op->y); victim !=NULL; victim=victim->above) {
986 if(QUERY_FLAG(victim, FLAG_ALIVE) && !QUERY_FLAG(victim, FLAG_WIZPASS) && 981 if(QUERY_FLAG(victim, FLAG_ALIVE) && !QUERY_FLAG(victim, FLAG_WIZPASS) &&
987 (victim->move_type & op->move_type || !victim->move_type)) { 982 (victim->move_type & op->move_type || !victim->move_type)) {
988 983
989 if (victim->head) victim = victim->head; 984 if (victim->head) victim = victim->head;
990 985
991 if(QUERY_FLAG(op,FLAG_LIFESAVE)&&op->stats.hp--<0) { 986 if(QUERY_FLAG(op,FLAG_LIFESAVE)&&op->stats.hp--<0) {
992 remove_ob(op); 987 remove_ob(op);
993 free_object(op); 988 free_object(op);
994 return; 989 return;
995 } 990 }
996 nx = op->x+freearr_x[dir]; 991 nx = op->x+freearr_x[dir];
997 ny = op->y+freearr_y[dir]; 992 ny = op->y+freearr_y[dir];
998 m = op->map; 993 m = op->map;
999 if (get_map_flags(m, &m, nx, ny, &nx, &ny) & P_OUT_OF_MAP) { 994 if (get_map_flags(m, &m, nx, ny, &nx, &ny) & P_OUT_OF_MAP) {
1000 LOG(llevError,"move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n", 995 LOG(llevError,"move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n",
1001 m->path, op->x, op->y); 996 m->path, op->x, op->y);
1002 return ; 997 return ;
1003 } 998 }
1004 999
1005 if (should_director_abort(op, victim)) return ; 1000 if (should_director_abort(op, victim)) return ;
1006 1001
1007 for(nextmover=get_map_ob(m,nx, ny); nextmover !=NULL; nextmover=nextmover->above) { 1002 for(nextmover=get_map_ob(m,nx, ny); nextmover !=NULL; nextmover=nextmover->above) {
1008 if(nextmover->type == PLAYERMOVER) 1003 if(nextmover->type == PLAYERMOVER)
1009 nextmover->speed_left=-.99; 1004 nextmover->speed_left=-.99;
1010 if(QUERY_FLAG(nextmover,FLAG_ALIVE)) { 1005 if(QUERY_FLAG(nextmover,FLAG_ALIVE)) {
1011 op->speed_left=-1.1; /* wait until the next thing gets out of the way */ 1006 op->speed_left=-1.1; /* wait until the next thing gets out of the way */
1012 } 1007 }
1013 } 1008 }
1014 1009
1015 if(victim->type==PLAYER) { 1010 if(victim->type==PLAYER) {
1016 /* only level >=1 movers move people */ 1011 /* only level >=1 movers move people */
1017 if(op->level) { 1012 if(op->level) {
1018 /* Following is a bit of hack. We need to make sure it 1013 /* Following is a bit of hack. We need to make sure it
1019 * is cleared, otherwise the player will get stuck in 1014 * is cleared, otherwise the player will get stuck in
1020 * place. This can happen if the player used a spell to 1015 * place. This can happen if the player used a spell to
1021 * get to this space. 1016 * get to this space.
1022 */ 1017 */
1023 victim->contr->fire_on=0; 1018 victim->contr->fire_on=0;
1024 victim->speed_left=-FABS(victim->speed); 1019 victim->speed_left=-FABS(victim->speed);
1025 move_player(victim, dir); 1020 move_player(victim, dir);
1026 } 1021 }
1027 else return; 1022 else return;
1028 } 1023 }
1029 else move_object(victim,dir); 1024 else move_object(victim,dir);
1030 1025
1031 if(!op->stats.maxsp&&op->attacktype) op->stats.maxsp=2; 1026 if(!op->stats.maxsp&&op->attacktype) op->stats.maxsp=2;
1032 1027
1033 if(op->attacktype) { /* flag to paralyze the player */ 1028 if(op->attacktype) { /* flag to paralyze the player */
1034 1029
1035 victim->speed_left= -FABS(op->stats.maxsp*victim->speed/op->speed); 1030 victim->speed_left= -FABS(op->stats.maxsp*victim->speed/op->speed);
1036 /* Not sure why, but for some chars on metalforge, they 1031 /* Not sure why, but for some chars on metalforge, they
1037 * would sometimes get -inf speed_left, and from the 1032 * would sometimes get -inf speed_left, and from the
1038 * description, it could only happen here, so just put 1033 * description, it could only happen here, so just put
1039 * a lower sanity limit. My only guess is that the 1034 * a lower sanity limit. My only guess is that the
1040 * mover has 0 speed. 1035 * mover has 0 speed.
1041 */ 1036 */
1042 if (victim->speed_left < -5.0) victim->speed_left=-5.0; 1037 if (victim->speed_left < -5.0) victim->speed_left=-5.0;
1043 } 1038 }
1044 } 1039 }
1045 } 1040 }
1046} 1041}
1047 1042
1048/* 1043/*
1049 * Will duplicate a specified object placed on top of it. 1044 * Will duplicate a specified object placed on top of it.
1059 LOG(llevInfo, "Duplicator with no other_arch! %d %d %s\n", op->x, op->y, op->map ? op->map->path : "nullmap"); 1054 LOG(llevInfo, "Duplicator with no other_arch! %d %d %s\n", op->x, op->y, op->map ? op->map->path : "nullmap");
1060 return; 1055 return;
1061 } 1056 }
1062 1057
1063 if (op->above == NULL) 1058 if (op->above == NULL)
1064 return; 1059 return;
1065 for (tmp=op->above; tmp != NULL; tmp=tmp->above) { 1060 for (tmp=op->above; tmp != NULL; tmp=tmp->above) {
1066 if (strcmp(op->other_arch->name, tmp->arch->name) == 0) { 1061 if (strcmp(op->other_arch->name, tmp->arch->name) == 0) {
1067 if (op->level <= 0) { 1062 if (op->level <= 0) {
1068 remove_ob(tmp); 1063 remove_ob(tmp);
1069 free_object(tmp); 1064 free_object(tmp);
1070 } else { 1065 } else {
1071 uint64 new_nrof = (uint64)tmp->nrof*op->level; 1066 uint64 new_nrof = (uint64)tmp->nrof*op->level;
1072 if (new_nrof >= 1UL<<31) 1067 if (new_nrof >= 1UL<<31)
1073 new_nrof = 1UL<<31; 1068 new_nrof = 1UL<<31;
1074 tmp->nrof = new_nrof; 1069 tmp->nrof = new_nrof;
1075 } 1070 }
1076 break; 1071 break;
1077 } 1072 }
1078 } 1073 }
1079} 1074}
1080 1075
1081/* move_creator (by peterm) 1076/* move_creator (by peterm)
1082 * it has the creator object create it's other_arch right on top of it. 1077 * it has the creator object create it's other_arch right on top of it.
1094 1089
1095void move_creator(object *creator) { 1090void move_creator(object *creator) {
1096 object *new_ob; 1091 object *new_ob;
1097 1092
1098 if(!QUERY_FLAG(creator, FLAG_LIFESAVE) && --creator->stats.hp < 0) { 1093 if(!QUERY_FLAG(creator, FLAG_LIFESAVE) && --creator->stats.hp < 0) {
1099 creator->stats.hp=-1; 1094 creator->stats.hp=-1;
1100 return; 1095 return;
1101 } 1096 }
1102 1097
1103 if (creator->inv != NULL) { 1098 if (creator->inv != NULL) {
1104 object *ob; 1099 object *ob;
1105 int i; 1100 int i;
1106 object *ob_to_copy; 1101 object *ob_to_copy;
1107 1102
1108 /* select random object from inventory to copy */ 1103 /* select random object from inventory to copy */
1109 ob_to_copy = creator->inv; 1104 ob_to_copy = creator->inv;
1110 for (ob = creator->inv->below, i = 1; ob != NULL; ob = ob->below, i++) { 1105 for (ob = creator->inv->below, i = 1; ob != NULL; ob = ob->below, i++) {
1111 if (rndm(0, i) == 0) { 1106 if (rndm(0, i) == 0) {
1112 ob_to_copy = ob; 1107 ob_to_copy = ob;
1113 } 1108 }
1114 } 1109 }
1115 new_ob = object_create_clone(ob_to_copy); 1110 new_ob = object_create_clone(ob_to_copy);
1116 CLEAR_FLAG(new_ob, FLAG_IS_A_TEMPLATE); 1111 CLEAR_FLAG(new_ob, FLAG_IS_A_TEMPLATE);
1117 unflag_inv(new_ob, FLAG_IS_A_TEMPLATE); 1112 unflag_inv(new_ob, FLAG_IS_A_TEMPLATE);
1118 } else { 1113 } else {
1119 if (creator->other_arch == NULL) { 1114 if (creator->other_arch == NULL) {
1120 LOG(llevError,"move_creator: Creator doesn't have other arch set: %s (%s, %d, %d)\n", creator->name ? creator->name : "(null)", creator->map->path, creator->x, creator->y); 1115 LOG(llevError,"move_creator: Creator doesn't have other arch set: %s (%s, %d, %d)\n", &creator->name, creator->map->path, creator->x, creator->y);
1121 return; 1116 return;
1122 } 1117 }
1123 1118
1124 new_ob = object_create_arch(creator->other_arch); 1119 new_ob = object_create_arch(creator->other_arch);
1125 fix_generated_item(new_ob, creator, 0, 0, GT_MINIMAL); 1120 fix_generated_item(new_ob, creator, 0, 0, GT_MINIMAL);
1126 } 1121 }
1127 1122
1128 /* Make sure this multipart object fits */ 1123 /* Make sure this multipart object fits */
1129 if (new_ob->arch->more && ob_blocked(new_ob, creator->map, creator->x, creator->y)) { 1124 if (new_ob->arch->more && ob_blocked(new_ob, creator->map, creator->x, creator->y)) {
1130 free_object(new_ob); 1125 free_object(new_ob);
1131 return; 1126 return;
1132 } 1127 }
1133 1128
1134 insert_ob_in_map_at(new_ob, creator->map, creator, 0, creator->x, creator->y); 1129 insert_ob_in_map_at(new_ob, creator->map, creator, 0, creator->x, creator->y);
1135 if (QUERY_FLAG(new_ob, FLAG_FREED)) 1130 if (QUERY_FLAG(new_ob, FLAG_FREED))
1136 return; 1131 return;
1137 1132
1138 if (creator->slaying) { 1133 if (creator->slaying) {
1139 FREE_AND_COPY(new_ob->name, creator->slaying); 1134 new_ob->name = new_ob->title = creator->slaying;
1140 FREE_AND_COPY(new_ob->title, creator->slaying);
1141 } 1135 }
1142} 1136}
1143 1137
1144/* move_marker --peterm@soda.csua.berkeley.edu 1138/* move_marker --peterm@soda.csua.berkeley.edu
1145 when moved, a marker will search for a player sitting above 1139 when moved, a marker will search for a player sitting above
1152 1146
1153void move_marker(object *op) { 1147void move_marker(object *op) {
1154 object *tmp,*tmp2; 1148 object *tmp,*tmp2;
1155 1149
1156 for(tmp=get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) { 1150 for(tmp=get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) {
1157 if(tmp->type == PLAYER) { /* we've got someone to MARK */ 1151 if(tmp->type == PLAYER) { /* we've got someone to MARK */
1158 1152
1159 if ( quest_on_activate(op, tmp->contr) )
1160 return;
1161
1162 /* remove an old force with a slaying field == op->name */ 1153 /* remove an old force with a slaying field == op->name */
1163 for(tmp2=tmp->inv;tmp2 !=NULL; tmp2=tmp2->below) { 1154 for(tmp2=tmp->inv;tmp2 !=NULL; tmp2=tmp2->below) {
1164 if(tmp2->type == FORCE && tmp2->slaying && !strcmp(tmp2->slaying,op->name)) break; 1155 if(tmp2->type == FORCE && tmp2->slaying && !strcmp(tmp2->slaying,op->name)) break;
1165 } 1156 }
1166 1157
1167 if(tmp2) { 1158 if(tmp2) {
1168 remove_ob(tmp2); 1159 remove_ob(tmp2);
1169 free_object(tmp2); 1160 free_object(tmp2);
1170 } 1161 }
1171 1162
1172 /* cycle through his inventory to look for the MARK we want to 1163 /* cycle through his inventory to look for the MARK we want to
1173 * place 1164 * place
1174 */ 1165 */
1175 for(tmp2=tmp->inv;tmp2 !=NULL; tmp2=tmp2->below) { 1166 for(tmp2=tmp->inv;tmp2 !=NULL; tmp2=tmp2->below) {
1176 if(tmp2->type == FORCE && tmp2->slaying && !strcmp(tmp2->slaying,op->slaying)) break; 1167 if(tmp2->type == FORCE && tmp2->slaying && !strcmp(tmp2->slaying,op->slaying)) break;
1177 } 1168 }
1178 1169
1179 /* if we didn't find our own MARK */ 1170 /* if we didn't find our own MARK */
1180 if(tmp2==NULL) { 1171 if(tmp2==NULL) {
1181 object *force = get_archetype(FORCE_NAME); 1172 object *force = get_archetype(FORCE_NAME);
1182 1173
1183 force->speed = 0; 1174 force->speed = 0;
1184 if(op->stats.food) { 1175 if(op->stats.food) {
1185 force->speed = 0.01; 1176 force->speed = 0.01;
1186 force->speed_left = -op->stats.food; 1177 force->speed_left = -op->stats.food;
1187 } 1178 }
1188 update_ob_speed (force); 1179 update_ob_speed (force);
1189 /* put in the lock code */ 1180 /* put in the lock code */
1190 force->slaying = add_string(op->slaying); 1181 force->slaying = op->slaying;
1191 1182
1192 if ( op->lore ) 1183 if (op->lore)
1193 force->lore = add_string( op->lore ); 1184 force->lore = op->lore;
1194 1185
1195 insert_ob_in_ob(force,tmp); 1186 insert_ob_in_ob(force,tmp);
1196 if(op->msg) 1187 if(op->msg)
1197 new_draw_info(NDI_UNIQUE|NDI_NAVY,0,tmp,op->msg); 1188 new_draw_info(NDI_UNIQUE|NDI_NAVY,0,tmp,op->msg);
1198 1189
1199 if(op->stats.hp > 0) { 1190 if(op->stats.hp > 0) {
1200 op->stats.hp--; 1191 op->stats.hp--;
1201 if(op->stats.hp==0) { 1192 if(op->stats.hp==0) {
1202 /* marker expires--granted mark number limit */ 1193 /* marker expires--granted mark number limit */
1203 remove_ob(op); 1194 remove_ob(op);
1204 free_object(op); 1195 free_object(op);
1205 return; 1196 return;
1206 } 1197 }
1207 } 1198 }
1208 } /* if tmp2 == NULL */ 1199 } /* if tmp2 == NULL */
1209 } /* if tmp->type == PLAYER */ 1200 } /* if tmp->type == PLAYER */
1210 } /* For all objects on this space */ 1201 } /* For all objects on this space */
1211} 1202}
1212 1203
1213int process_object(object *op) { 1204int process_object(object *op) {
1214 if (QUERY_FLAG(op, FLAG_IS_A_TEMPLATE)) 1205 if (QUERY_FLAG(op, FLAG_IS_A_TEMPLATE))
1215 return 0; 1206 return 0;
1207
1208 if (INVOKE_OBJECT (TICK, op))
1209 return 0;
1216 1210
1217 if(QUERY_FLAG(op, FLAG_MONSTER)) 1211 if(QUERY_FLAG(op, FLAG_MONSTER))
1218 if(move_monster(op) || QUERY_FLAG(op, FLAG_FREED)) 1212 if(move_monster(op) || QUERY_FLAG(op, FLAG_FREED))
1219 return 1; 1213 return 1;
1220 1214
1221 if(QUERY_FLAG(op, FLAG_ANIMATE) && op->anim_speed==0) { 1215 if(QUERY_FLAG(op, FLAG_ANIMATE) && op->anim_speed==0) {
1222 if (op->type == PLAYER) 1216 if (op->type == PLAYER)
1223 animate_object(op, op->facing); 1217 animate_object(op, op->facing);
1224 else 1218 else
1225 animate_object(op, op->direction); 1219 animate_object(op, op->direction);
1226 1220
1227 if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE)) 1221 if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE))
1228 make_sure_seen(op); 1222 make_sure_seen(op);
1229 } 1223 }
1230 if(QUERY_FLAG(op, FLAG_CHANGING)&&!op->state) { 1224 if(QUERY_FLAG(op, FLAG_CHANGING)&&!op->state) {
1231 change_object(op); 1225 change_object(op);
1232 return 1; 1226 return 1;
1233 } 1227 }
1234 if(QUERY_FLAG(op, FLAG_GENERATOR)&&!QUERY_FLAG(op, FLAG_FRIENDLY)) 1228 if(QUERY_FLAG(op, FLAG_GENERATOR)&&!QUERY_FLAG(op, FLAG_FRIENDLY))
1235 generate_monster(op); 1229 generate_monster(op);
1236 1230
1237 if(QUERY_FLAG(op, FLAG_IS_USED_UP)&&--op->stats.food<=0) { 1231 if(QUERY_FLAG(op, FLAG_IS_USED_UP)&&--op->stats.food<=0) {
1238 if(QUERY_FLAG(op, FLAG_APPLIED)) 1232 if(QUERY_FLAG(op, FLAG_APPLIED))
1239 remove_force(op); 1233 remove_force(op);
1240 else { 1234 else {
1241 /* IF necessary, delete the item from the players inventory */ 1235 /* IF necessary, delete the item from the players inventory */
1242 object *pl=is_player_inv(op); 1236 object *pl=is_player_inv(op);
1243 if (pl) 1237 if (pl)
1244 esrv_del_item(pl->contr, op->count); 1238 esrv_del_item(pl->contr, op->count);
1245 remove_ob(op); 1239 remove_ob(op);
1246 if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE)) 1240 if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE))
1247 make_sure_not_seen(op); 1241 make_sure_not_seen(op);
1248 free_object(op); 1242 free_object(op);
1249 } 1243 }
1250 return 1; 1244 return 1;
1251 } 1245 }
1252 /* Lauwenmark: Handle for plugin time event */
1253 execute_event(op, EVENT_TIME,NULL,NULL,NULL,SCRIPT_FIX_NOTHING);
1254 switch(op->type) { 1246 switch(op->type) {
1255 case TRANSPORT:
1256 /* Transports are directed by players - thus, their
1257 * speed is reduced when the player moves them about.
1258 * So give them back there speed here, since process_objects()
1259 * has decremented it.
1260 */
1261 if (op->speed_left < 0.0) op->speed_left += 1.0;
1262 return 1;
1263 1247
1264 case SPELL_EFFECT: 1248 case SPELL_EFFECT:
1265 move_spell_effect(op); 1249 move_spell_effect(op);
1266 return 1; 1250 return 1;
1267 1251
1268 case ROD: 1252 case ROD:
1269 case HORN: 1253 case HORN:
1270 regenerate_rod(op); 1254 regenerate_rod(op);
1271 return 1; 1255 return 1;
1272 1256
1273 case FORCE: 1257 case FORCE:
1274 case POTION_EFFECT: 1258 case POTION_EFFECT:
1275 remove_force(op); 1259 remove_force(op);
1276 return 1; 1260 return 1;
1277 1261
1278 case BLINDNESS: 1262 case BLINDNESS:
1279 remove_blindness(op); 1263 remove_blindness(op);
1280 return 0; 1264 return 0;
1281 1265
1282 case POISONING: 1266 case POISONING:
1283 poison_more(op); 1267 poison_more(op);
1284 return 0; 1268 return 0;
1285 1269
1286 case DISEASE: 1270 case DISEASE:
1287 move_disease(op); 1271 move_disease(op);
1288 return 0; 1272 return 0;
1289 1273
1290 case SYMPTOM: 1274 case SYMPTOM:
1291 move_symptom(op); 1275 move_symptom(op);
1292 return 0; 1276 return 0;
1293 1277
1294 case THROWN_OBJ: 1278 case THROWN_OBJ:
1295 case ARROW: 1279 case ARROW:
1296 move_arrow(op); 1280 move_arrow(op);
1297 return 0; 1281 return 0;
1298 1282
1299 case LIGHTNING: /* It now moves twice as fast */ 1283 case LIGHTNING: /* It now moves twice as fast */
1300 move_bolt(op); 1284 move_bolt(op);
1301 return 0; 1285 return 0;
1302 1286
1303 case DOOR: 1287 case DOOR:
1304 remove_door(op); 1288 remove_door(op);
1305 return 0; 1289 return 0;
1306 1290
1307 case LOCKED_DOOR: 1291 case LOCKED_DOOR:
1308 remove_door2(op); 1292 remove_door2(op);
1309 return 0; 1293 return 0;
1310 1294
1311 case TELEPORTER: 1295 case TELEPORTER:
1312 move_teleporter(op); 1296 move_teleporter(op);
1313 return 0; 1297 return 0;
1314 1298
1315 case GOLEM: 1299 case GOLEM:
1316 move_golem(op); 1300 move_golem(op);
1317 return 0; 1301 return 0;
1318 1302
1319 case EARTHWALL: 1303 case EARTHWALL:
1320 hit_player(op, 2, op, AT_PHYSICAL, 1); 1304 hit_player(op, 2, op, AT_PHYSICAL, 1);
1321 return 0; 1305 return 0;
1322 1306
1323 case FIREWALL: 1307 case FIREWALL:
1324 move_firewall(op); 1308 move_firewall(op);
1325 if (op->stats.maxsp) 1309 if (op->stats.maxsp)
1326 animate_turning(op); 1310 animate_turning(op);
1327 return 0; 1311 return 0;
1328 1312
1329 case MOOD_FLOOR: 1313 case MOOD_FLOOR:
1330 do_mood_floor(op, op); 1314 do_mood_floor(op);
1331 return 0; 1315 return 0;
1332 1316
1333 case GATE: 1317 case GATE:
1334 move_gate(op); 1318 move_gate(op);
1335 return 0; 1319 return 0;
1336 1320
1337 case TIMED_GATE: 1321 case TIMED_GATE:
1338 move_timed_gate(op); 1322 move_timed_gate(op);
1339 return 0; 1323 return 0;
1340 1324
1341 case TRIGGER: 1325 case TRIGGER:
1342 case TRIGGER_BUTTON: 1326 case TRIGGER_BUTTON:
1343 case TRIGGER_PEDESTAL: 1327 case TRIGGER_PEDESTAL:
1344 case TRIGGER_ALTAR: 1328 case TRIGGER_ALTAR:
1345 animate_trigger(op); 1329 animate_trigger(op);
1346 return 0; 1330 return 0;
1347 1331
1348 case DETECTOR: 1332 case DETECTOR:
1349 move_detector(op); 1333 move_detector(op);
1350 1334
1351 case DIRECTOR: 1335 case DIRECTOR:
1352 if (op->stats.maxsp) 1336 if (op->stats.maxsp)
1353 animate_turning(op); 1337 animate_turning(op);
1354 return 0; 1338 return 0;
1355 1339
1356 case HOLE: 1340 case HOLE:
1357 move_hole(op); 1341 move_hole(op);
1358 return 0; 1342 return 0;
1359 1343
1360 case DEEP_SWAMP: 1344 case DEEP_SWAMP:
1361 move_deep_swamp(op); 1345 move_deep_swamp(op);
1362 return 0; 1346 return 0;
1363 1347
1364 case RUNE: 1348 case RUNE:
1365 case TRAP: 1349 case TRAP:
1366 move_rune(op); 1350 move_rune(op);
1367 return 0; 1351 return 0;
1368 1352
1369 case PLAYERMOVER: 1353 case PLAYERMOVER:
1370 move_player_mover(op); 1354 move_player_mover(op);
1371 return 0; 1355 return 0;
1372 1356
1373 case CREATOR: 1357 case CREATOR:
1374 move_creator(op); 1358 move_creator(op);
1375 return 0; 1359 return 0;
1376 1360
1377 case MARKER: 1361 case MARKER:
1378 move_marker(op); 1362 move_marker(op);
1379 return 0; 1363 return 0;
1380 1364
1381 case PLAYER_CHANGER: 1365 case PLAYER_CHANGER:
1382 move_player_changer(op); 1366 move_player_changer(op);
1383 return 0; 1367 return 0;
1384 1368
1385 case PEACEMAKER: 1369 case PEACEMAKER:
1386 move_peacemaker(op); 1370 move_peacemaker(op);
1387 return 0; 1371 return 0;
1388 } 1372 }
1389 1373
1390 return 0; 1374 return 0;
1391} 1375}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines