1 | /* |
1 | /* |
2 | * static char *rcsid_monster_c = |
2 | * static char *rcsid_monster_c = |
3 | * "$Id: monster.c,v 1.1.1.2 2006/03/15 14:05:37 elmex Exp $"; |
3 | * "$Id: monster.c,v 1.8 2006/08/13 17:16:04 elmex dead $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
291 | /* |
291 | /* |
292 | * Move-monster returns 1 if the object has been freed, otherwise 0. |
292 | * Move-monster returns 1 if the object has been freed, otherwise 0. |
293 | */ |
293 | */ |
294 | |
294 | |
295 | int move_monster(object *op) { |
295 | int move_monster(object *op) { |
296 | int dir, diff; |
296 | int dir, diff, pre_att_dir; /* elmex: pre_att_dir remembers the direction before attack movement */ |
297 | object *owner, *enemy, *part, *oph=op; |
297 | object *owner, *enemy, *part, *oph=op; |
298 | rv_vector rv; |
298 | rv_vector rv; |
299 | |
299 | |
300 | /* Monsters not on maps don't do anything. These monsters are things |
300 | /* Monsters not on maps don't do anything. These monsters are things |
301 | * Like royal guards in city dwellers inventories. |
301 | * Like royal guards in city dwellers inventories. |
… | |
… | |
379 | */ |
379 | */ |
380 | if(QUERY_FLAG(op, FLAG_SCARED) &&!(RANDOM()%20)) { |
380 | if(QUERY_FLAG(op, FLAG_SCARED) &&!(RANDOM()%20)) { |
381 | CLEAR_FLAG(op,FLAG_SCARED); /* Time to regain some "guts"... */ |
381 | CLEAR_FLAG(op,FLAG_SCARED); /* Time to regain some "guts"... */ |
382 | } |
382 | } |
383 | |
383 | |
|
|
384 | if (execute_event (op, EVENT_MOVE, op->enemy, 0, 0, SCRIPT_FIX_ALL)) |
|
|
385 | return 0; |
|
|
386 | |
384 | /* If we don't have an enemy, do special movement or the like */ |
387 | /* If we don't have an enemy, do special movement or the like */ |
385 | if(!enemy) { |
388 | if(!enemy) { |
386 | if(QUERY_FLAG(op, FLAG_ONLY_ATTACK)) { |
389 | if(QUERY_FLAG(op, FLAG_ONLY_ATTACK)) { |
387 | remove_ob(op); |
390 | remove_ob(op); |
388 | free_object(op); |
391 | free_object(op); |
… | |
… | |
441 | return 0; |
444 | return 0; |
442 | } /* no enemy */ |
445 | } /* no enemy */ |
443 | |
446 | |
444 | /* We have an enemy. Block immediately below is for pets */ |
447 | /* We have an enemy. Block immediately below is for pets */ |
445 | if((op->attack_movement&HI4) == PETMOVE && (owner = get_owner(op)) != NULL && !on_same_map(op,owner)) |
448 | if((op->attack_movement&HI4) == PETMOVE && (owner = get_owner(op)) != NULL && !on_same_map(op,owner)) |
446 | { |
|
|
447 | follow_owner(op, owner); |
449 | return follow_owner(op, owner); |
448 | /* If the pet was unable to follow the owner, free it */ |
|
|
449 | if(QUERY_FLAG(op, FLAG_REMOVED) && FABS(op->speed) > MIN_ACTIVE_SPEED) { |
|
|
450 | remove_friendly_object(op); |
|
|
451 | free_object(op); |
|
|
452 | return 1; |
|
|
453 | } |
|
|
454 | return 0; |
|
|
455 | } |
|
|
456 | |
450 | |
457 | /* doppleganger code to change monster facing to that of the nearest |
451 | /* doppleganger code to change monster facing to that of the nearest |
458 | * player. Hmm. The code is here, but no monster in the current |
452 | * player. Hmm. The code is here, but no monster in the current |
459 | * arch set uses it. |
453 | * arch set uses it. |
460 | */ |
454 | */ |
… | |
… | |
527 | dir=absdir(dir+4); |
521 | dir=absdir(dir+4); |
528 | |
522 | |
529 | if(QUERY_FLAG(op,FLAG_CONFUSED)) |
523 | if(QUERY_FLAG(op,FLAG_CONFUSED)) |
530 | dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2); |
524 | dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2); |
531 | |
525 | |
|
|
526 | pre_att_dir = dir; /* remember the original direction */ |
|
|
527 | |
532 | if ((op->attack_movement & LO4) && !QUERY_FLAG(op, FLAG_SCARED)) |
528 | if ((op->attack_movement & LO4) && !QUERY_FLAG(op, FLAG_SCARED)) |
533 | { |
529 | { |
534 | switch (op->attack_movement & LO4) { |
530 | switch (op->attack_movement & LO4) { |
535 | case DISTATT: |
531 | case DISTATT: |
536 | dir = dist_att (dir,op,enemy,part,&rv); |
532 | dir = dist_att (dir,op,enemy,part,&rv); |
… | |
… | |
568 | if (!dir) |
564 | if (!dir) |
569 | return 0; |
565 | return 0; |
570 | |
566 | |
571 | if (!QUERY_FLAG(op,FLAG_STAND_STILL)) { |
567 | if (!QUERY_FLAG(op,FLAG_STAND_STILL)) { |
572 | if(move_object(op,dir)) /* Can the monster move directly toward player? */ |
568 | if(move_object(op,dir)) /* Can the monster move directly toward player? */ |
|
|
569 | { |
|
|
570 | /* elmex: Turn our monster after it moved if it has DISTATT attack */ |
|
|
571 | if ((op->attack_movement & LO4) == DISTATT) |
|
|
572 | op->direction = pre_att_dir; |
|
|
573 | |
573 | return 0; |
574 | return 0; |
|
|
575 | } |
574 | |
576 | |
575 | if(QUERY_FLAG(op, FLAG_SCARED) || !can_hit(part,enemy,&rv) |
577 | if(QUERY_FLAG(op, FLAG_SCARED) || !can_hit(part,enemy,&rv) |
576 | || QUERY_FLAG(op,FLAG_RUN_AWAY)) { |
578 | || QUERY_FLAG(op,FLAG_RUN_AWAY)) { |
577 | |
579 | |
578 | /* Try move around corners if !close */ |
580 | /* Try move around corners if !close */ |
… | |
… | |
584 | move_object(op,absdir(dir - diff*m))) |
586 | move_object(op,absdir(dir - diff*m))) |
585 | return 0; |
587 | return 0; |
586 | } |
588 | } |
587 | } |
589 | } |
588 | } /* if monster is not standing still */ |
590 | } /* if monster is not standing still */ |
|
|
591 | |
|
|
592 | /* elmex: Turn our monster after it moved if it has DISTATT attack */ |
|
|
593 | if ((op->attack_movement & LO4) == DISTATT) |
|
|
594 | op->direction = pre_att_dir; |
589 | |
595 | |
590 | /* |
596 | /* |
591 | * Eneq(@csd.uu.se): Patch to make RUN_AWAY or SCARED monsters move a random |
597 | * Eneq(@csd.uu.se): Patch to make RUN_AWAY or SCARED monsters move a random |
592 | * direction if they can't move away. |
598 | * direction if they can't move away. |
593 | */ |
599 | */ |
… | |
… | |
1651 | return 0; |
1657 | return 0; |
1652 | /* Lauwenmark - Here we let the objects inside inventories hear and answer, too. */ |
1658 | /* Lauwenmark - Here we let the objects inside inventories hear and answer, too. */ |
1653 | /* This allows the existence of "intelligent" weapons you can discuss with */ |
1659 | /* This allows the existence of "intelligent" weapons you can discuss with */ |
1654 | for(cobj=npc->inv;cobj!=NULL; cobj = cobj->below) |
1660 | for(cobj=npc->inv;cobj!=NULL; cobj = cobj->below) |
1655 | { |
1661 | { |
1656 | if (execute_event(cobj, EVENT_SAY,npc,NULL,txt,SCRIPT_FIX_ALL)!=0) |
1662 | if (execute_event(cobj, EVENT_SAY,op,NULL,txt,SCRIPT_FIX_ALL)!=0) |
1657 | return 0; |
1663 | return 0; |
1658 | } |
1664 | } |
1659 | for ( cobj = npc->inv; cobj; cobj = cobj->below ) |
1665 | for ( cobj = npc->inv; cobj; cobj = cobj->below ) |
1660 | if ( quest_is_override_compatible( cobj, op ) ) |
1666 | if ( quest_is_override_compatible( cobj, op ) ) |
1661 | if ( do_talk_npc( op, npc, cobj, txt ) ) |
1667 | if ( do_talk_npc( op, npc, cobj, txt ) ) |