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.6 by root, Tue Aug 29 08:01:38 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.6 2006/08/29 08:01:38 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){
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;
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 if (op->slaying != NULL)
565 FREE_AND_CLEAR_STR(op->slaying); 565 FREE_AND_CLEAR_STR(op->slaying);
566 566
567 if (op->skill != NULL) 567 if (op->skill != NULL)
568 FREE_AND_CLEAR_STR(op->skill); 568 FREE_AND_CLEAR_STR(op->skill);
569 569
570 if (op->spellarg != NULL) { 570 if (op->spellarg != NULL) {
571 op->slaying = add_string(op->spellarg); 571 op->slaying = add_string(op->spellarg);
572 free(op->spellarg); 572 free(op->spellarg);
573 op->spellarg = NULL; 573 op->spellarg = NULL;
574 } else 574 } else
575 op->slaying = NULL; 575 op->slaying = NULL;
576 576
577 /* Reset these to zero, so that CAN_MERGE will work properly */ 577 /* Reset these to zero, so that CAN_MERGE will work properly */
578 op->spellarg = NULL; 578 op->spellarg = NULL;
579 op->stats.sp = 0; 579 op->stats.sp = 0;
580 op->stats.hp = 0; 580 op->stats.hp = 0;
594 * from maps or inventories), or NULL if was destroyed. 594 * from maps or inventories), or NULL if was destroyed.
595 */ 595 */
596 596
597static void stop_arrow (object *op) 597static void stop_arrow (object *op)
598{ 598{
599 /* Lauwenmark: Handle for plugin stop event */ 599 if (INVOKE_OBJECT (STOP, op))
600 execute_event(op, EVENT_STOP,NULL,NULL,NULL,SCRIPT_FIX_NOTHING); 600 return;
601
601 if (op->inv) { 602 if (op->inv) {
602 object *payload = op->inv; 603 object *payload = op->inv;
603 remove_ob (payload); 604 remove_ob (payload);
604 clear_owner(payload); 605 clear_owner(payload);
605 insert_ob_in_map (payload, op->map, payload,0); 606 insert_ob_in_map (payload, op->map, payload,0);
606 remove_ob (op); 607 remove_ob (op);
607 free_object (op); 608 free_object (op);
608 } else { 609 } else {
609 op = fix_stopped_arrow (op); 610 op = fix_stopped_arrow (op);
610 if (op) 611 if (op)
611 merge_ob (op, NULL); 612 merge_ob (op, NULL);
612 } 613 }
620 sint16 new_x, new_y; 621 sint16 new_x, new_y;
621 int was_reflected, mflags; 622 int was_reflected, mflags;
622 mapstruct *m; 623 mapstruct *m;
623 624
624 if(op->map==NULL) { 625 if(op->map==NULL) {
625 LOG (llevError, "BUG: Arrow had no map.\n"); 626 LOG (llevError, "BUG: Arrow had no map.\n");
626 remove_ob(op); 627 remove_ob(op);
627 free_object(op); 628 free_object(op);
628 return; 629 return;
629 } 630 }
630 631
631 /* we need to stop thrown objects at some point. Like here. */ 632 /* we need to stop thrown objects at some point. Like here. */
632 if(op->type==THROWN_OBJ) { 633 if(op->type==THROWN_OBJ) {
633 /* If the object that the THROWN_OBJ encapsulates disappears, 634 /* If the object that the THROWN_OBJ encapsulates disappears,
634 * we need to have this object go away also - otherwise, you get 635 * we need to have this object go away also - otherwise, you get
635 * left over remnants on the map. Where this currently happens 636 * left over remnants on the map. Where this currently happens
636 * is if the player throws a bomb - the bomb explodes on its own, 637 * 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 638 * 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, 639 * bomb code, but there are potential other cases where that could happen,
639 * and it is easy enough to clean it up here. 640 * and it is easy enough to clean it up here.
640 */ 641 */
641 if (op->inv == NULL) { 642 if (op->inv == NULL) {
642 remove_ob(op); 643 remove_ob(op);
643 free_object(op); 644 free_object(op);
644 return; 645 return;
645 } 646 }
646 if(op->last_sp-- < 0) { 647 if(op->last_sp-- < 0) {
647 stop_arrow (op); 648 stop_arrow (op);
648 return; 649 return;
649 } 650 }
650 } 651 }
651 652
652 /* if the arrow is moving too slow.. stop it. 0.5 was chosen as lower 653 /* if the arrow is moving too slow.. stop it. 0.5 was chosen as lower
653 values look rediculous. */ 654 values look rediculous. */
654 if (op->speed < 0.5 && op->type==ARROW) { 655 if (op->speed < 0.5 && op->type==ARROW) {
655 stop_arrow(op); 656 stop_arrow(op);
656 return; 657 return;
657 } 658 }
658 659
659 /* Calculate target map square */ 660 /* Calculate target map square */
660 new_x = op->x + DIRX(op); 661 new_x = op->x + DIRX(op);
661 new_y = op->y + DIRY(op); 662 new_y = op->y + DIRY(op);
663 664
664 m = op->map; 665 m = op->map;
665 mflags = get_map_flags(m, &m, new_x, new_y, &new_x, &new_y); 666 mflags = get_map_flags(m, &m, new_x, new_y, &new_x, &new_y);
666 667
667 if (mflags & P_OUT_OF_MAP) { 668 if (mflags & P_OUT_OF_MAP) {
668 stop_arrow(op); 669 stop_arrow(op);
669 return; 670 return;
670 } 671 }
671 672
672 /* only need to look for living creatures if this flag is set */ 673 /* only need to look for living creatures if this flag is set */
673 if (mflags & P_IS_ALIVE) { 674 if (mflags & P_IS_ALIVE) {
674 for (tmp = get_map_ob(m, new_x, new_y); tmp != NULL; tmp=tmp->above) 675 for (tmp = get_map_ob(m, new_x, new_y); tmp != NULL; tmp=tmp->above)
675 if (QUERY_FLAG(tmp, FLAG_ALIVE)) break; 676 if (QUERY_FLAG(tmp, FLAG_ALIVE)) break;
676 677
677 678
678 /* Not really fair, but don't let monsters hit themselves with 679 /* Not really fair, but don't let monsters hit themselves with
679 * their own arrow - this can be because they fire it then 680 * their own arrow - this can be because they fire it then
680 * move into it. 681 * move into it.
681 */ 682 */
682 683
683 if (tmp != NULL && tmp != op->owner) { 684 if (tmp != NULL && tmp != op->owner) {
684 /* Found living object, but it is reflecting the missile. Update 685 /* Found living object, but it is reflecting the missile. Update
685 * as below. (Note that for living creatures there is a small 686 * as below. (Note that for living creatures there is a small
686 * chance that reflect_missile fails.) 687 * chance that reflect_missile fails.)
687 */ 688 */
688 689
689 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) && 690 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE) &&
690 (rndm(0, 99)) < (90-op->level/10)) { 691 (rndm(0, 99)) < (90-op->level/10)) {
691 692
692 int number = op->face->number; 693 int number = op->face->number;
693 694
694 op->direction = absdir (op->direction + 4); 695 op->direction = absdir (op->direction + 4);
695 op->state = 0; 696 op->state = 0;
696 if (GET_ANIM_ID (op)) { 697 if (GET_ANIM_ID (op)) {
697 number += 4; 698 number += 4;
698 if (number > GET_ANIMATION (op, 8)) 699 if (number > GET_ANIMATION (op, 8))
699 number -= 8; 700 number -= 8;
700 op->face = &new_faces[number]; 701 op->face = &new_faces[number];
701 } 702 }
702 was_reflected = 1; /* skip normal movement calculations */ 703 was_reflected = 1; /* skip normal movement calculations */
703 } 704 }
704 else { 705 else {
705 /* Attack the object. */ 706 /* Attack the object. */
706 op = hit_with_arrow (op, tmp); 707 op = hit_with_arrow (op, tmp);
707 if (op == NULL) 708 if (op == NULL)
708 return; 709 return;
709 } 710 }
710 } /* if this is not hitting its owner */ 711 } /* if this is not hitting its owner */
711 } /* if there is something alive on this space */ 712 } /* if there is something alive on this space */
712 713
713 714
714 if (OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, new_x, new_y))) { 715 if (OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, new_x, new_y))) {
715 int retry=0; 716 int retry=0;
716 717
717 /* if the object doesn't reflect, stop the arrow from moving 718 /* if the object doesn't reflect, stop the arrow from moving
718 * note that this code will now catch cases where a monster is 719 * note that this code will now catch cases where a monster is
719 * on a wall but has reflecting - the arrow won't reflect. 720 * on a wall but has reflecting - the arrow won't reflect.
720 * Mapmakers shouldn't put monsters on top of wall in the first 721 * Mapmakers shouldn't put monsters on top of wall in the first
721 * place, so I don't consider that a problem. 722 * place, so I don't consider that a problem.
722 */ 723 */
723 if(!QUERY_FLAG(op, FLAG_REFLECTING) || !(rndm(0, 19))) { 724 if(!QUERY_FLAG(op, FLAG_REFLECTING) || !(rndm(0, 19))) {
724 stop_arrow (op); 725 stop_arrow (op);
725 return; 726 return;
726 } else { 727 } else {
727 /* If one of the major directions (n,s,e,w), just reverse it */ 728 /* If one of the major directions (n,s,e,w), just reverse it */
728 if(op->direction&1) { 729 if(op->direction&1) {
729 op->direction=absdir(op->direction+4); 730 op->direction=absdir(op->direction+4);
730 retry=1; 731 retry=1;
731 } 732 }
732 /* There were two blocks with identical code - 733 /* There were two blocks with identical code -
733 * use this retry here to make this one block 734 * use this retry here to make this one block
734 * that did the same thing. 735 * that did the same thing.
735 */ 736 */
736 while (retry<2) { 737 while (retry<2) {
737 int left, right, mflags; 738 int left, right, mflags;
738 mapstruct *m1; 739 mapstruct *m1;
739 sint16 x1, y1; 740 sint16 x1, y1;
740 741
741 retry++; 742 retry++;
742 743
743 /* Need to check for P_OUT_OF_MAP: if the arrow is tavelling 744 /* 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 745 * over a corner in a tiled map, it is possible that
745 * op->direction is within an adjacent map but either 746 * op->direction is within an adjacent map but either
746 * op->direction-1 or op->direction+1 does not exist. 747 * op->direction-1 or op->direction+1 does not exist.
747 */ 748 */
748 mflags = get_map_flags(op->map,&m1, op->x+freearr_x[absdir(op->direction-1)], 749 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); 750 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))); 751 left = (mflags & P_OUT_OF_MAP) ? 0 : OB_TYPE_MOVE_BLOCK(op, (GET_MAP_MOVE_BLOCK(m1, x1, y1)));
751 752
752 mflags = get_map_flags(op->map,&m1, op->x+freearr_x[absdir(op->direction+1)], 753 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); 754 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))); 755 right = (mflags & P_OUT_OF_MAP) ? 0 : OB_TYPE_MOVE_BLOCK(op, (GET_MAP_MOVE_BLOCK(m1, x1, y1)));
755 756
756 if(left==right) 757 if(left==right)
757 op->direction=absdir(op->direction+4); 758 op->direction=absdir(op->direction+4);
758 else if(left) 759 else if(left)
759 op->direction=absdir(op->direction+2); 760 op->direction=absdir(op->direction+2);
760 else if(right) 761 else if(right)
761 op->direction=absdir(op->direction-2); 762 op->direction=absdir(op->direction-2);
762 763
763 mflags = get_map_flags(op->map,&m1, op->x+DIRX(op),op->y+DIRY(op), &x1, &y1); 764 mflags = get_map_flags(op->map,&m1, op->x+DIRX(op),op->y+DIRY(op), &x1, &y1);
764 765
765 /* If this space is not out of the map and not blocked, valid space - 766 /* If this space is not out of the map and not blocked, valid space -
766 * don't need to retry again. 767 * don't need to retry again.
767 */ 768 */
768 if (!(mflags & P_OUT_OF_MAP) && 769 if (!(mflags & P_OUT_OF_MAP) &&
769 !OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m1, x1, y1))) break; 770 !OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m1, x1, y1))) break;
770 771
771 } 772 }
772 /* Couldn't find a direction to move the arrow to - just 773 /* Couldn't find a direction to move the arrow to - just
773 * top it from moving. 774 * top it from moving.
774 */ 775 */
775 if (retry==2) { 776 if (retry==2) {
776 stop_arrow (op); 777 stop_arrow (op);
777 return; 778 return;
778 } 779 }
779 /* update object image for new facing */ 780 /* update object image for new facing */
780 /* many thrown objects *don't* have more than one face */ 781 /* many thrown objects *don't* have more than one face */
781 if(GET_ANIM_ID(op)) 782 if(GET_ANIM_ID(op))
782 SET_ANIMATION(op, op->direction); 783 SET_ANIMATION(op, op->direction);
783 } /* object is reflected */ 784 } /* object is reflected */
784 } /* object ran into a wall */ 785 } /* object ran into a wall */
785 786
786 /* Move the arrow. */ 787 /* Move the arrow. */
787 remove_ob (op); 788 remove_ob (op);
788 op->x = new_x; 789 op->x = new_x;
808 return; 809 return;
809 } 810 }
810 811
811 /* In non-living items only change when food value is 0 */ 812 /* In non-living items only change when food value is 0 */
812 if(!QUERY_FLAG(op,FLAG_ALIVE)) { 813 if(!QUERY_FLAG(op,FLAG_ALIVE)) {
813 if(op->stats.food-- > 0) return; 814 if(op->stats.food-- > 0) return;
814 else op->stats.food=1; /* so 1 other_arch is made */ 815 else op->stats.food=1; /* so 1 other_arch is made */
815 } 816 }
816 env=op->env; 817 env=op->env;
817 remove_ob(op); 818 remove_ob(op);
818 for(i=0;i<NROFNEWOBJS(op);i++) { 819 for(i=0;i<NROFNEWOBJS(op);i++) {
819 tmp=arch_to_object(op->other_arch); 820 tmp=arch_to_object(op->other_arch);
820 if (op->type == LAMP) 821 if (op->type == LAMP)
821 tmp->stats.food = op->stats.food-1; 822 tmp->stats.food = op->stats.food-1;
822 tmp->stats.hp=op->stats.hp; /* The only variable it keeps. */ 823 tmp->stats.hp=op->stats.hp; /* The only variable it keeps. */
823 if(env) { 824 if(env) {
824 tmp->x=env->x,tmp->y=env->y; 825 tmp->x=env->x,tmp->y=env->y;
825 tmp=insert_ob_in_ob(tmp,env); 826 tmp=insert_ob_in_ob(tmp,env);
826 /* If this object is the players inventory, we need to tell the 827 /* 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 828 * 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. 829 * updating the client, so we don't need to do that below.
829 */ 830 */
830 if ((pl=is_player_inv(env))!=NULL) { 831 if ((pl=is_player_inv(env))!=NULL) {
831 esrv_del_item(pl->contr, op->count); 832 esrv_del_item(pl->contr, op->count);
832 esrv_send_item(pl, tmp); 833 esrv_send_item(pl, tmp);
833 } 834 }
834 } else { 835 } else {
835 j=find_first_free_spot(tmp,op->map,op->x,op->y); 836 j=find_first_free_spot(tmp,op->map,op->x,op->y);
836 if (j==-1) /* No free spot */ 837 if (j==-1) /* No free spot */
837 free_object(tmp); 838 free_object(tmp);
838 else { 839 else {
839 tmp->x=op->x+freearr_x[j],tmp->y=op->y+freearr_y[j]; 840 tmp->x=op->x+freearr_x[j],tmp->y=op->y+freearr_y[j];
840 insert_ob_in_map(tmp,op->map,op,0); 841 insert_ob_in_map(tmp,op->map,op,0);
841 } 842 }
842 } 843 }
843 } 844 }
844 free_object(op); 845 free_object(op);
845} 846}
846 847
857 if (op->more && FABS(op->more->speed)<MIN_ACTIVE_SPEED) move_teleporter(op->more); 858 if (op->more && FABS(op->more->speed)<MIN_ACTIVE_SPEED) move_teleporter(op->more);
858 859
859 if (op->head) head=op->head; 860 if (op->head) head=op->head;
860 861
861 for (tmp=op->above; tmp!=NULL; tmp=tmp->above) 862 for (tmp=op->above; tmp!=NULL; tmp=tmp->above)
862 if (!QUERY_FLAG(tmp, FLAG_IS_FLOOR)) break; 863 if (!QUERY_FLAG(tmp, FLAG_IS_FLOOR)) break;
863 864
864 /* If nothing above us to move, nothing to do */ 865 /* If nothing above us to move, nothing to do */
865 if (!tmp || QUERY_FLAG(tmp, FLAG_WIZPASS)) return; 866 if (!tmp || QUERY_FLAG(tmp, FLAG_WIZPASS)) return;
866 867
867 if(EXIT_PATH(head)) { 868 if(EXIT_PATH(head)) {
868 if(tmp->type==PLAYER) { 869 if(tmp->type==PLAYER) {
869 /* Lauwenmark: Handle for plugin TRIGGER event */ 870 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp)))
870 if (execute_event(op, EVENT_TRIGGER, tmp, NULL, NULL, SCRIPT_FIX_ALL) != 0)
871 return; 871 return;
872
872 enter_exit(tmp, head); 873 enter_exit(tmp, head);
873 } 874 }
874 else 875 else
875 /* Currently only players can transfer maps */ 876 /* Currently only players can transfer maps */
876 return; 877 return;
877 } 878 }
878 else if(EXIT_X(head)||EXIT_Y(head)) { 879 else if(EXIT_X(head)||EXIT_Y(head)) {
879 if (out_of_map(head->map, EXIT_X(head), EXIT_Y(head))) { 880 if (out_of_map(head->map, EXIT_X(head), EXIT_Y(head))) {
880 LOG(llevError, "Removed illegal teleporter.\n"); 881 LOG(llevError, "Removed illegal teleporter.\n");
881 remove_ob(head); 882 remove_ob(head);
882 free_object(head); 883 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; 884 return;
885 }
886 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp)))
887 return;
888 transfer_ob(tmp,EXIT_X(head),EXIT_Y(head),0,head); 888 transfer_ob(tmp,EXIT_X(head),EXIT_Y(head),0,head);
889 } 889 }
890 else { 890 else {
891 /* Random teleporter */ 891 /* Random teleporter */
892 /* Lauwenmark: Handle for plugin TRIGGER event */ 892 if (INVOKE_OBJECT (TRIGGER, op, ARG_OBJECT (tmp)))
893 if (execute_event(op, EVENT_TRIGGER, tmp, NULL, NULL, SCRIPT_FIX_ALL) != 0)
894 return; 893 return;
895 teleport(head, TELEPORTER, tmp); 894 teleport(head, TELEPORTER, tmp);
896 } 895 }
897} 896}
898 897
899 898
900/* This object will teleport someone to a different map 899/* This object will teleport someone to a different map
912 911
913 /* This isn't all that great - means that the player_mover 912 /* This isn't all that great - means that the player_mover
914 * needs to be on top. 913 * needs to be on top.
915 */ 914 */
916 if(op->above->type==PLAYER) { 915 if(op->above->type==PLAYER) {
917 /* Lauwenmark: Handle for plugin TRIGGER event */ 916 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; 917 return;
920 player=op->above; 918 player=op->above;
921 for(walk=op->inv;walk!=NULL;walk=walk->below) 919 for(walk=op->inv;walk!=NULL;walk=walk->below)
922 apply_changes_to_player(player,walk); 920 apply_changes_to_player(player,walk);
923 921
924 fix_player(player); 922 fix_player(player);
925 esrv_send_inventory(op->above,op->above); 923 esrv_send_inventory(op->above,op->above);
926 esrv_update_item(UPD_FACE, op->above, op->above); 924 esrv_update_item(UPD_FACE, op->above, op->above);
927 925
928 /* update players death & WoR home-position */ 926 /* update players death & WoR home-position */
929 sscanf(EXIT_PATH(op), "%c", &c); 927 sscanf(EXIT_PATH(op), "%c", &c);
930 if (c == '/') { 928 if (c == '/') {
931 strcpy(player->contr->savebed_map, EXIT_PATH(op)); 929 strcpy(player->contr->savebed_map, EXIT_PATH(op));
932 player->contr->bed_x = EXIT_X(op); 930 player->contr->bed_x = EXIT_X(op);
933 player->contr->bed_y = EXIT_Y(op); 931 player->contr->bed_y = EXIT_Y(op);
934 } 932 }
935 else 933 else
936 LOG(llevDebug, 934 LOG(llevDebug,
937 "WARNING: destination '%s' in player_changer must be an absolute path!\n", 935 "WARNING: destination '%s' in player_changer must be an absolute path!\n",
938 EXIT_PATH(op)); 936 EXIT_PATH(op));
939 937
940 enter_exit(op->above,op); 938 enter_exit(op->above,op);
941 save_player(player, 1); 939 save_player(player, 1);
942 } 940 }
943} 941}
944 942
945/* firewalls fire other spells. 943/* firewalls fire other spells.
946 * The direction of the wall is stored in op->stats.sp. 944 * The direction of the wall is stored in op->stats.sp.
948 */ 946 */
949void move_firewall(object *op) { 947void move_firewall(object *op) {
950 object *spell; 948 object *spell;
951 949
952 if ( ! op->map) 950 if ( ! op->map)
953 return; /* dm has created a firewall in his inventory */ 951 return; /* dm has created a firewall in his inventory */
954 952
955 spell = op->inv; 953 spell = op->inv;
956 if (!spell || spell->type != SPELL) spell=&op->other_arch->clone; 954 if (!spell || spell->type != SPELL) spell=&op->other_arch->clone;
957 if (!spell) { 955 if (!spell) {
958 LOG(llevError,"move_firewall: no spell specified (%s, %s, %d, %d)\n", 956 LOG(llevError,"move_firewall: no spell specified (%s, %s, %d, %d)\n",
959 op->name, op->map->name, op->x, op->y); 957 op->name, op->map->name, op->x, op->y);
960 return; 958 return;
961 } 959 }
962 960
963 cast_spell(op,op,op->stats.sp?op->stats.sp:rndm(1, 8),spell, NULL); 961 cast_spell(op,op,op->stats.sp?op->stats.sp:rndm(1, 8),spell, NULL);
964} 962}
965 963
981 979
982 /* Determine direction now for random movers so we do the right thing */ 980 /* Determine direction now for random movers so we do the right thing */
983 if (!dir) dir=rndm(1, 8); 981 if (!dir) dir=rndm(1, 8);
984 982
985 for(victim=get_map_ob(op->map,op->x,op->y); victim !=NULL; victim=victim->above) { 983 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) && 984 if(QUERY_FLAG(victim, FLAG_ALIVE) && !QUERY_FLAG(victim, FLAG_WIZPASS) &&
987 (victim->move_type & op->move_type || !victim->move_type)) { 985 (victim->move_type & op->move_type || !victim->move_type)) {
988 986
989 if (victim->head) victim = victim->head; 987 if (victim->head) victim = victim->head;
990 988
991 if(QUERY_FLAG(op,FLAG_LIFESAVE)&&op->stats.hp--<0) { 989 if(QUERY_FLAG(op,FLAG_LIFESAVE)&&op->stats.hp--<0) {
992 remove_ob(op); 990 remove_ob(op);
993 free_object(op); 991 free_object(op);
994 return; 992 return;
995 } 993 }
996 nx = op->x+freearr_x[dir]; 994 nx = op->x+freearr_x[dir];
997 ny = op->y+freearr_y[dir]; 995 ny = op->y+freearr_y[dir];
998 m = op->map; 996 m = op->map;
999 if (get_map_flags(m, &m, nx, ny, &nx, &ny) & P_OUT_OF_MAP) { 997 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", 998 LOG(llevError,"move_player_mover: Trying to push player off the map! map=%s (%d, %d)\n",
1001 m->path, op->x, op->y); 999 m->path, op->x, op->y);
1002 return ; 1000 return ;
1003 } 1001 }
1004 1002
1005 if (should_director_abort(op, victim)) return ; 1003 if (should_director_abort(op, victim)) return ;
1006 1004
1007 for(nextmover=get_map_ob(m,nx, ny); nextmover !=NULL; nextmover=nextmover->above) { 1005 for(nextmover=get_map_ob(m,nx, ny); nextmover !=NULL; nextmover=nextmover->above) {
1008 if(nextmover->type == PLAYERMOVER) 1006 if(nextmover->type == PLAYERMOVER)
1009 nextmover->speed_left=-.99; 1007 nextmover->speed_left=-.99;
1010 if(QUERY_FLAG(nextmover,FLAG_ALIVE)) { 1008 if(QUERY_FLAG(nextmover,FLAG_ALIVE)) {
1011 op->speed_left=-1.1; /* wait until the next thing gets out of the way */ 1009 op->speed_left=-1.1; /* wait until the next thing gets out of the way */
1012 } 1010 }
1013 } 1011 }
1014 1012
1015 if(victim->type==PLAYER) { 1013 if(victim->type==PLAYER) {
1016 /* only level >=1 movers move people */ 1014 /* only level >=1 movers move people */
1017 if(op->level) { 1015 if(op->level) {
1018 /* Following is a bit of hack. We need to make sure it 1016 /* Following is a bit of hack. We need to make sure it
1019 * is cleared, otherwise the player will get stuck in 1017 * is cleared, otherwise the player will get stuck in
1020 * place. This can happen if the player used a spell to 1018 * place. This can happen if the player used a spell to
1021 * get to this space. 1019 * get to this space.
1022 */ 1020 */
1023 victim->contr->fire_on=0; 1021 victim->contr->fire_on=0;
1024 victim->speed_left=-FABS(victim->speed); 1022 victim->speed_left=-FABS(victim->speed);
1025 move_player(victim, dir); 1023 move_player(victim, dir);
1026 } 1024 }
1027 else return; 1025 else return;
1028 } 1026 }
1029 else move_object(victim,dir); 1027 else move_object(victim,dir);
1030 1028
1031 if(!op->stats.maxsp&&op->attacktype) op->stats.maxsp=2; 1029 if(!op->stats.maxsp&&op->attacktype) op->stats.maxsp=2;
1032 1030
1033 if(op->attacktype) { /* flag to paralyze the player */ 1031 if(op->attacktype) { /* flag to paralyze the player */
1034 1032
1035 victim->speed_left= -FABS(op->stats.maxsp*victim->speed/op->speed); 1033 victim->speed_left= -FABS(op->stats.maxsp*victim->speed/op->speed);
1036 /* Not sure why, but for some chars on metalforge, they 1034 /* Not sure why, but for some chars on metalforge, they
1037 * would sometimes get -inf speed_left, and from the 1035 * would sometimes get -inf speed_left, and from the
1038 * description, it could only happen here, so just put 1036 * description, it could only happen here, so just put
1039 * a lower sanity limit. My only guess is that the 1037 * a lower sanity limit. My only guess is that the
1040 * mover has 0 speed. 1038 * mover has 0 speed.
1041 */ 1039 */
1042 if (victim->speed_left < -5.0) victim->speed_left=-5.0; 1040 if (victim->speed_left < -5.0) victim->speed_left=-5.0;
1043 } 1041 }
1044 } 1042 }
1045 } 1043 }
1046} 1044}
1047 1045
1048/* 1046/*
1049 * Will duplicate a specified object placed on top of it. 1047 * 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"); 1057 LOG(llevInfo, "Duplicator with no other_arch! %d %d %s\n", op->x, op->y, op->map ? op->map->path : "nullmap");
1060 return; 1058 return;
1061 } 1059 }
1062 1060
1063 if (op->above == NULL) 1061 if (op->above == NULL)
1064 return; 1062 return;
1065 for (tmp=op->above; tmp != NULL; tmp=tmp->above) { 1063 for (tmp=op->above; tmp != NULL; tmp=tmp->above) {
1066 if (strcmp(op->other_arch->name, tmp->arch->name) == 0) { 1064 if (strcmp(op->other_arch->name, tmp->arch->name) == 0) {
1067 if (op->level <= 0) { 1065 if (op->level <= 0) {
1068 remove_ob(tmp); 1066 remove_ob(tmp);
1069 free_object(tmp); 1067 free_object(tmp);
1070 } else { 1068 } else {
1071 uint64 new_nrof = (uint64)tmp->nrof*op->level; 1069 uint64 new_nrof = (uint64)tmp->nrof*op->level;
1072 if (new_nrof >= 1UL<<31) 1070 if (new_nrof >= 1UL<<31)
1073 new_nrof = 1UL<<31; 1071 new_nrof = 1UL<<31;
1074 tmp->nrof = new_nrof; 1072 tmp->nrof = new_nrof;
1075 } 1073 }
1076 break; 1074 break;
1077 } 1075 }
1078 } 1076 }
1079} 1077}
1080 1078
1081/* move_creator (by peterm) 1079/* move_creator (by peterm)
1082 * it has the creator object create it's other_arch right on top of it. 1080 * it has the creator object create it's other_arch right on top of it.
1094 1092
1095void move_creator(object *creator) { 1093void move_creator(object *creator) {
1096 object *new_ob; 1094 object *new_ob;
1097 1095
1098 if(!QUERY_FLAG(creator, FLAG_LIFESAVE) && --creator->stats.hp < 0) { 1096 if(!QUERY_FLAG(creator, FLAG_LIFESAVE) && --creator->stats.hp < 0) {
1099 creator->stats.hp=-1; 1097 creator->stats.hp=-1;
1100 return; 1098 return;
1101 } 1099 }
1102 1100
1103 if (creator->inv != NULL) { 1101 if (creator->inv != NULL) {
1104 object *ob; 1102 object *ob;
1105 int i; 1103 int i;
1106 object *ob_to_copy; 1104 object *ob_to_copy;
1107 1105
1108 /* select random object from inventory to copy */ 1106 /* select random object from inventory to copy */
1109 ob_to_copy = creator->inv; 1107 ob_to_copy = creator->inv;
1110 for (ob = creator->inv->below, i = 1; ob != NULL; ob = ob->below, i++) { 1108 for (ob = creator->inv->below, i = 1; ob != NULL; ob = ob->below, i++) {
1111 if (rndm(0, i) == 0) { 1109 if (rndm(0, i) == 0) {
1112 ob_to_copy = ob; 1110 ob_to_copy = ob;
1113 } 1111 }
1114 } 1112 }
1115 new_ob = object_create_clone(ob_to_copy); 1113 new_ob = object_create_clone(ob_to_copy);
1116 CLEAR_FLAG(new_ob, FLAG_IS_A_TEMPLATE); 1114 CLEAR_FLAG(new_ob, FLAG_IS_A_TEMPLATE);
1117 unflag_inv(new_ob, FLAG_IS_A_TEMPLATE); 1115 unflag_inv(new_ob, FLAG_IS_A_TEMPLATE);
1118 } else { 1116 } else {
1119 if (creator->other_arch == NULL) { 1117 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); 1118 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);
1121 return; 1119 return;
1122 } 1120 }
1123 1121
1124 new_ob = object_create_arch(creator->other_arch); 1122 new_ob = object_create_arch(creator->other_arch);
1125 fix_generated_item(new_ob, creator, 0, 0, GT_MINIMAL); 1123 fix_generated_item(new_ob, creator, 0, 0, GT_MINIMAL);
1126 } 1124 }
1127 1125
1128 /* Make sure this multipart object fits */ 1126 /* Make sure this multipart object fits */
1129 if (new_ob->arch->more && ob_blocked(new_ob, creator->map, creator->x, creator->y)) { 1127 if (new_ob->arch->more && ob_blocked(new_ob, creator->map, creator->x, creator->y)) {
1130 free_object(new_ob); 1128 free_object(new_ob);
1131 return; 1129 return;
1132 } 1130 }
1133 1131
1134 insert_ob_in_map_at(new_ob, creator->map, creator, 0, creator->x, creator->y); 1132 insert_ob_in_map_at(new_ob, creator->map, creator, 0, creator->x, creator->y);
1135 if (QUERY_FLAG(new_ob, FLAG_FREED)) 1133 if (QUERY_FLAG(new_ob, FLAG_FREED))
1136 return; 1134 return;
1137 1135
1138 if (creator->slaying) { 1136 if (creator->slaying) {
1139 FREE_AND_COPY(new_ob->name, creator->slaying); 1137 FREE_AND_COPY(new_ob->name, creator->slaying);
1140 FREE_AND_COPY(new_ob->title, creator->slaying); 1138 FREE_AND_COPY(new_ob->title, creator->slaying);
1141 } 1139 }
1142} 1140}
1143 1141
1144/* move_marker --peterm@soda.csua.berkeley.edu 1142/* move_marker --peterm@soda.csua.berkeley.edu
1145 when moved, a marker will search for a player sitting above 1143 when moved, a marker will search for a player sitting above
1152 1150
1153void move_marker(object *op) { 1151void move_marker(object *op) {
1154 object *tmp,*tmp2; 1152 object *tmp,*tmp2;
1155 1153
1156 for(tmp=get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) { 1154 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 */ 1155 if(tmp->type == PLAYER) { /* we've got someone to MARK */
1158 1156
1159 if ( quest_on_activate(op, tmp->contr) ) 1157 if ( quest_on_activate(op, tmp->contr) )
1160 return; 1158 return;
1161 1159
1162 /* remove an old force with a slaying field == op->name */ 1160 /* remove an old force with a slaying field == op->name */
1163 for(tmp2=tmp->inv;tmp2 !=NULL; tmp2=tmp2->below) { 1161 for(tmp2=tmp->inv;tmp2 !=NULL; tmp2=tmp2->below) {
1164 if(tmp2->type == FORCE && tmp2->slaying && !strcmp(tmp2->slaying,op->name)) break; 1162 if(tmp2->type == FORCE && tmp2->slaying && !strcmp(tmp2->slaying,op->name)) break;
1165 } 1163 }
1166 1164
1167 if(tmp2) { 1165 if(tmp2) {
1168 remove_ob(tmp2); 1166 remove_ob(tmp2);
1169 free_object(tmp2); 1167 free_object(tmp2);
1170 } 1168 }
1171 1169
1172 /* cycle through his inventory to look for the MARK we want to 1170 /* cycle through his inventory to look for the MARK we want to
1173 * place 1171 * place
1174 */ 1172 */
1175 for(tmp2=tmp->inv;tmp2 !=NULL; tmp2=tmp2->below) { 1173 for(tmp2=tmp->inv;tmp2 !=NULL; tmp2=tmp2->below) {
1176 if(tmp2->type == FORCE && tmp2->slaying && !strcmp(tmp2->slaying,op->slaying)) break; 1174 if(tmp2->type == FORCE && tmp2->slaying && !strcmp(tmp2->slaying,op->slaying)) break;
1177 } 1175 }
1178 1176
1179 /* if we didn't find our own MARK */ 1177 /* if we didn't find our own MARK */
1180 if(tmp2==NULL) { 1178 if(tmp2==NULL) {
1181 object *force = get_archetype(FORCE_NAME); 1179 object *force = get_archetype(FORCE_NAME);
1182 1180
1183 force->speed = 0; 1181 force->speed = 0;
1184 if(op->stats.food) { 1182 if(op->stats.food) {
1185 force->speed = 0.01; 1183 force->speed = 0.01;
1186 force->speed_left = -op->stats.food; 1184 force->speed_left = -op->stats.food;
1187 } 1185 }
1188 update_ob_speed (force); 1186 update_ob_speed (force);
1189 /* put in the lock code */ 1187 /* put in the lock code */
1190 force->slaying = add_string(op->slaying); 1188 force->slaying = add_string(op->slaying);
1191 1189
1192 if ( op->lore ) 1190 if ( op->lore )
1193 force->lore = add_string( op->lore ); 1191 force->lore = add_string( op->lore );
1194 1192
1195 insert_ob_in_ob(force,tmp); 1193 insert_ob_in_ob(force,tmp);
1196 if(op->msg) 1194 if(op->msg)
1197 new_draw_info(NDI_UNIQUE|NDI_NAVY,0,tmp,op->msg); 1195 new_draw_info(NDI_UNIQUE|NDI_NAVY,0,tmp,op->msg);
1198 1196
1199 if(op->stats.hp > 0) { 1197 if(op->stats.hp > 0) {
1200 op->stats.hp--; 1198 op->stats.hp--;
1201 if(op->stats.hp==0) { 1199 if(op->stats.hp==0) {
1202 /* marker expires--granted mark number limit */ 1200 /* marker expires--granted mark number limit */
1203 remove_ob(op); 1201 remove_ob(op);
1204 free_object(op); 1202 free_object(op);
1205 return; 1203 return;
1206 } 1204 }
1207 } 1205 }
1208 } /* if tmp2 == NULL */ 1206 } /* if tmp2 == NULL */
1209 } /* if tmp->type == PLAYER */ 1207 } /* if tmp->type == PLAYER */
1210 } /* For all objects on this space */ 1208 } /* For all objects on this space */
1211} 1209}
1212 1210
1213int process_object(object *op) { 1211int process_object(object *op) {
1214 if (QUERY_FLAG(op, FLAG_IS_A_TEMPLATE)) 1212 if (QUERY_FLAG(op, FLAG_IS_A_TEMPLATE))
1215 return 0; 1213 return 0;
1214
1215 if (INVOKE_OBJECT (TICK, op))
1216 return 0;
1216 1217
1217 if(QUERY_FLAG(op, FLAG_MONSTER)) 1218 if(QUERY_FLAG(op, FLAG_MONSTER))
1218 if(move_monster(op) || QUERY_FLAG(op, FLAG_FREED)) 1219 if(move_monster(op) || QUERY_FLAG(op, FLAG_FREED))
1219 return 1; 1220 return 1;
1220 1221
1221 if(QUERY_FLAG(op, FLAG_ANIMATE) && op->anim_speed==0) { 1222 if(QUERY_FLAG(op, FLAG_ANIMATE) && op->anim_speed==0) {
1222 if (op->type == PLAYER) 1223 if (op->type == PLAYER)
1223 animate_object(op, op->facing); 1224 animate_object(op, op->facing);
1224 else 1225 else
1225 animate_object(op, op->direction); 1226 animate_object(op, op->direction);
1226 1227
1227 if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE)) 1228 if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE))
1228 make_sure_seen(op); 1229 make_sure_seen(op);
1229 } 1230 }
1230 if(QUERY_FLAG(op, FLAG_CHANGING)&&!op->state) { 1231 if(QUERY_FLAG(op, FLAG_CHANGING)&&!op->state) {
1231 change_object(op); 1232 change_object(op);
1232 return 1; 1233 return 1;
1233 } 1234 }
1234 if(QUERY_FLAG(op, FLAG_GENERATOR)&&!QUERY_FLAG(op, FLAG_FRIENDLY)) 1235 if(QUERY_FLAG(op, FLAG_GENERATOR)&&!QUERY_FLAG(op, FLAG_FRIENDLY))
1235 generate_monster(op); 1236 generate_monster(op);
1236 1237
1237 if(QUERY_FLAG(op, FLAG_IS_USED_UP)&&--op->stats.food<=0) { 1238 if(QUERY_FLAG(op, FLAG_IS_USED_UP)&&--op->stats.food<=0) {
1238 if(QUERY_FLAG(op, FLAG_APPLIED)) 1239 if(QUERY_FLAG(op, FLAG_APPLIED))
1239 remove_force(op); 1240 remove_force(op);
1240 else { 1241 else {
1241 /* IF necessary, delete the item from the players inventory */ 1242 /* IF necessary, delete the item from the players inventory */
1242 object *pl=is_player_inv(op); 1243 object *pl=is_player_inv(op);
1243 if (pl) 1244 if (pl)
1244 esrv_del_item(pl->contr, op->count); 1245 esrv_del_item(pl->contr, op->count);
1245 remove_ob(op); 1246 remove_ob(op);
1246 if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE)) 1247 if (QUERY_FLAG(op, FLAG_SEE_ANYWHERE))
1247 make_sure_not_seen(op); 1248 make_sure_not_seen(op);
1248 free_object(op); 1249 free_object(op);
1249 } 1250 }
1250 return 1; 1251 return 1;
1251 } 1252 }
1252 /* Lauwenmark: Handle for plugin time event */
1253 execute_event(op, EVENT_TIME,NULL,NULL,NULL,SCRIPT_FIX_NOTHING);
1254 switch(op->type) { 1253 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 1254
1264 case SPELL_EFFECT: 1255 case SPELL_EFFECT:
1265 move_spell_effect(op); 1256 move_spell_effect(op);
1266 return 1; 1257 return 1;
1267 1258
1268 case ROD: 1259 case ROD:
1269 case HORN: 1260 case HORN:
1270 regenerate_rod(op); 1261 regenerate_rod(op);
1271 return 1; 1262 return 1;
1272 1263
1273 case FORCE: 1264 case FORCE:
1274 case POTION_EFFECT: 1265 case POTION_EFFECT:
1275 remove_force(op); 1266 remove_force(op);
1276 return 1; 1267 return 1;
1277 1268
1278 case BLINDNESS: 1269 case BLINDNESS:
1279 remove_blindness(op); 1270 remove_blindness(op);
1280 return 0; 1271 return 0;
1281 1272
1282 case POISONING: 1273 case POISONING:
1283 poison_more(op); 1274 poison_more(op);
1284 return 0; 1275 return 0;
1285 1276
1286 case DISEASE: 1277 case DISEASE:
1287 move_disease(op); 1278 move_disease(op);
1288 return 0; 1279 return 0;
1289 1280
1290 case SYMPTOM: 1281 case SYMPTOM:
1291 move_symptom(op); 1282 move_symptom(op);
1292 return 0; 1283 return 0;
1293 1284
1294 case THROWN_OBJ: 1285 case THROWN_OBJ:
1295 case ARROW: 1286 case ARROW:
1296 move_arrow(op); 1287 move_arrow(op);
1297 return 0; 1288 return 0;
1298 1289
1299 case LIGHTNING: /* It now moves twice as fast */ 1290 case LIGHTNING: /* It now moves twice as fast */
1300 move_bolt(op); 1291 move_bolt(op);
1301 return 0; 1292 return 0;
1302 1293
1303 case DOOR: 1294 case DOOR:
1304 remove_door(op); 1295 remove_door(op);
1305 return 0; 1296 return 0;
1306 1297
1307 case LOCKED_DOOR: 1298 case LOCKED_DOOR:
1308 remove_door2(op); 1299 remove_door2(op);
1309 return 0; 1300 return 0;
1310 1301
1311 case TELEPORTER: 1302 case TELEPORTER:
1312 move_teleporter(op); 1303 move_teleporter(op);
1313 return 0; 1304 return 0;
1314 1305
1315 case GOLEM: 1306 case GOLEM:
1316 move_golem(op); 1307 move_golem(op);
1317 return 0; 1308 return 0;
1318 1309
1319 case EARTHWALL: 1310 case EARTHWALL:
1320 hit_player(op, 2, op, AT_PHYSICAL, 1); 1311 hit_player(op, 2, op, AT_PHYSICAL, 1);
1321 return 0; 1312 return 0;
1322 1313
1323 case FIREWALL: 1314 case FIREWALL:
1324 move_firewall(op); 1315 move_firewall(op);
1325 if (op->stats.maxsp) 1316 if (op->stats.maxsp)
1326 animate_turning(op); 1317 animate_turning(op);
1327 return 0; 1318 return 0;
1328 1319
1329 case MOOD_FLOOR: 1320 case MOOD_FLOOR:
1330 do_mood_floor(op, op); 1321 do_mood_floor(op, op);
1331 return 0; 1322 return 0;
1332 1323
1333 case GATE: 1324 case GATE:
1334 move_gate(op); 1325 move_gate(op);
1335 return 0; 1326 return 0;
1336 1327
1337 case TIMED_GATE: 1328 case TIMED_GATE:
1338 move_timed_gate(op); 1329 move_timed_gate(op);
1339 return 0; 1330 return 0;
1340 1331
1341 case TRIGGER: 1332 case TRIGGER:
1342 case TRIGGER_BUTTON: 1333 case TRIGGER_BUTTON:
1343 case TRIGGER_PEDESTAL: 1334 case TRIGGER_PEDESTAL:
1344 case TRIGGER_ALTAR: 1335 case TRIGGER_ALTAR:
1345 animate_trigger(op); 1336 animate_trigger(op);
1346 return 0; 1337 return 0;
1347 1338
1348 case DETECTOR: 1339 case DETECTOR:
1349 move_detector(op); 1340 move_detector(op);
1350 1341
1351 case DIRECTOR: 1342 case DIRECTOR:
1352 if (op->stats.maxsp) 1343 if (op->stats.maxsp)
1353 animate_turning(op); 1344 animate_turning(op);
1354 return 0; 1345 return 0;
1355 1346
1356 case HOLE: 1347 case HOLE:
1357 move_hole(op); 1348 move_hole(op);
1358 return 0; 1349 return 0;
1359 1350
1360 case DEEP_SWAMP: 1351 case DEEP_SWAMP:
1361 move_deep_swamp(op); 1352 move_deep_swamp(op);
1362 return 0; 1353 return 0;
1363 1354
1364 case RUNE: 1355 case RUNE:
1365 case TRAP: 1356 case TRAP:
1366 move_rune(op); 1357 move_rune(op);
1367 return 0; 1358 return 0;
1368 1359
1369 case PLAYERMOVER: 1360 case PLAYERMOVER:
1370 move_player_mover(op); 1361 move_player_mover(op);
1371 return 0; 1362 return 0;
1372 1363
1373 case CREATOR: 1364 case CREATOR:
1374 move_creator(op); 1365 move_creator(op);
1375 return 0; 1366 return 0;
1376 1367
1377 case MARKER: 1368 case MARKER:
1378 move_marker(op); 1369 move_marker(op);
1379 return 0; 1370 return 0;
1380 1371
1381 case PLAYER_CHANGER: 1372 case PLAYER_CHANGER:
1382 move_player_changer(op); 1373 move_player_changer(op);
1383 return 0; 1374 return 0;
1384 1375
1385 case PEACEMAKER: 1376 case PEACEMAKER:
1386 move_peacemaker(op); 1377 move_peacemaker(op);
1387 return 0; 1378 return 0;
1388 } 1379 }
1389 1380
1390 return 0; 1381 return 0;
1391} 1382}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines