1 | /* |
1 | /* |
2 | * static char *rcsid_monster_c = |
2 | * static char *rcsid_monster_c = |
3 | * "$Id: monster.c,v 1.3 2006/03/10 14:08:38 root Exp $"; |
3 | * "$Id: monster.c,v 1.6 2006/04/22 15:10:08 elmex 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 | |
… | |
… | |
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. |
… | |
… | |
530 | dir=absdir(dir+4); |
530 | dir=absdir(dir+4); |
531 | |
531 | |
532 | if(QUERY_FLAG(op,FLAG_CONFUSED)) |
532 | if(QUERY_FLAG(op,FLAG_CONFUSED)) |
533 | dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2); |
533 | dir = absdir(dir + RANDOM()%3 + RANDOM()%3 - 2); |
534 | |
534 | |
|
|
535 | pre_att_dir = dir; /* remember the original direction */ |
|
|
536 | |
535 | if ((op->attack_movement & LO4) && !QUERY_FLAG(op, FLAG_SCARED)) |
537 | if ((op->attack_movement & LO4) && !QUERY_FLAG(op, FLAG_SCARED)) |
536 | { |
538 | { |
537 | switch (op->attack_movement & LO4) { |
539 | switch (op->attack_movement & LO4) { |
538 | case DISTATT: |
540 | case DISTATT: |
539 | dir = dist_att (dir,op,enemy,part,&rv); |
541 | dir = dist_att (dir,op,enemy,part,&rv); |
… | |
… | |
571 | if (!dir) |
573 | if (!dir) |
572 | return 0; |
574 | return 0; |
573 | |
575 | |
574 | if (!QUERY_FLAG(op,FLAG_STAND_STILL)) { |
576 | if (!QUERY_FLAG(op,FLAG_STAND_STILL)) { |
575 | if(move_object(op,dir)) /* Can the monster move directly toward player? */ |
577 | if(move_object(op,dir)) /* Can the monster move directly toward player? */ |
|
|
578 | { |
|
|
579 | /* elmex: Turn our monster after it moved if it has DISTATT attack */ |
|
|
580 | if ((op->attack_movement & LO4) == DISTATT) |
|
|
581 | op->direction = pre_att_dir; |
|
|
582 | |
576 | return 0; |
583 | return 0; |
|
|
584 | } |
577 | |
585 | |
578 | if(QUERY_FLAG(op, FLAG_SCARED) || !can_hit(part,enemy,&rv) |
586 | if(QUERY_FLAG(op, FLAG_SCARED) || !can_hit(part,enemy,&rv) |
579 | || QUERY_FLAG(op,FLAG_RUN_AWAY)) { |
587 | || QUERY_FLAG(op,FLAG_RUN_AWAY)) { |
580 | |
588 | |
581 | /* Try move around corners if !close */ |
589 | /* Try move around corners if !close */ |
… | |
… | |
587 | move_object(op,absdir(dir - diff*m))) |
595 | move_object(op,absdir(dir - diff*m))) |
588 | return 0; |
596 | return 0; |
589 | } |
597 | } |
590 | } |
598 | } |
591 | } /* if monster is not standing still */ |
599 | } /* if monster is not standing still */ |
|
|
600 | |
|
|
601 | /* elmex: Turn our monster after it moved if it has DISTATT attack */ |
|
|
602 | if ((op->attack_movement & LO4) == DISTATT) |
|
|
603 | op->direction = pre_att_dir; |
592 | |
604 | |
593 | /* |
605 | /* |
594 | * Eneq(@csd.uu.se): Patch to make RUN_AWAY or SCARED monsters move a random |
606 | * Eneq(@csd.uu.se): Patch to make RUN_AWAY or SCARED monsters move a random |
595 | * direction if they can't move away. |
607 | * direction if they can't move away. |
596 | */ |
608 | */ |
… | |
… | |
1247 | |
1259 | |
1248 | if (item->type == TREASURE && mon->will_apply & WILL_APPLY_TREASURE) flag=1; |
1260 | if (item->type == TREASURE && mon->will_apply & WILL_APPLY_TREASURE) flag=1; |
1249 | /* Eating food gets hp back */ |
1261 | /* Eating food gets hp back */ |
1250 | else if (item->type == FOOD && mon->will_apply & WILL_APPLY_FOOD) flag=1; |
1262 | else if (item->type == FOOD && mon->will_apply & WILL_APPLY_FOOD) flag=1; |
1251 | else if (item->type == SCROLL && QUERY_FLAG(mon, FLAG_USE_SCROLL)) { |
1263 | else if (item->type == SCROLL && QUERY_FLAG(mon, FLAG_USE_SCROLL)) { |
|
|
1264 | if (!item->inv) |
|
|
1265 | LOG(llevDebug,"Monster %d having scroll %d with empty inventory!", mon->count, item->count); |
1252 | if (item->inv && monster_should_cast_spell(mon, item->inv)) |
1266 | else if (monster_should_cast_spell(mon, item->inv)) |
1253 | SET_FLAG(mon, FLAG_READY_SCROLL); |
1267 | SET_FLAG(mon, FLAG_READY_SCROLL); |
1254 | /* Don't use it right now */ |
1268 | /* Don't use it right now */ |
1255 | return; |
1269 | return; |
1256 | } |
1270 | } |
1257 | else if (item->type == WEAPON) flag = check_good_weapon(mon,item); |
1271 | else if (item->type == WEAPON) flag = check_good_weapon(mon,item); |
1258 | else if (IS_ARMOR(item)) flag = check_good_armour(mon,item); |
1272 | else if (IS_ARMOR(item)) flag = check_good_armour(mon,item); |
1259 | /* Should do something more, like make sure this is a better item */ |
1273 | /* Should do something more, like make sure this is a better item */ |
1260 | else if (item->type == RING) |
1274 | else if (item->type == RING) |
… | |
… | |
1652 | return 0; |
1666 | return 0; |
1653 | /* Lauwenmark - Here we let the objects inside inventories hear and answer, too. */ |
1667 | /* Lauwenmark - Here we let the objects inside inventories hear and answer, too. */ |
1654 | /* This allows the existence of "intelligent" weapons you can discuss with */ |
1668 | /* This allows the existence of "intelligent" weapons you can discuss with */ |
1655 | for(cobj=npc->inv;cobj!=NULL; cobj = cobj->below) |
1669 | for(cobj=npc->inv;cobj!=NULL; cobj = cobj->below) |
1656 | { |
1670 | { |
1657 | if (execute_event(cobj, EVENT_SAY,npc,NULL,txt,SCRIPT_FIX_ALL)!=0) |
1671 | if (execute_event(cobj, EVENT_SAY,op,NULL,txt,SCRIPT_FIX_ALL)!=0) |
1658 | return 0; |
1672 | return 0; |
1659 | } |
1673 | } |
1660 | for ( cobj = npc->inv; cobj; cobj = cobj->below ) |
1674 | for ( cobj = npc->inv; cobj; cobj = cobj->below ) |
1661 | if ( quest_is_override_compatible( cobj, op ) ) |
1675 | if ( quest_is_override_compatible( cobj, op ) ) |
1662 | if ( do_talk_npc( op, npc, cobj, txt ) ) |
1676 | if ( do_talk_npc( op, npc, cobj, txt ) ) |