void mv_mons(void) { object *monster, *next_monster, *test_mons; boolean flew; if (haste_self % 2) { return; } monster = level_monsters.next_monster; while (monster) { next_monster = monster->next_monster; mon_disappeared = 0; if (monster->m_flags & HASTED) { mv_1_monster(monster, rogue.row, rogue.col); if (mon_disappeared) { goto NM; } } else if (monster->m_flags & SLOWED) { monster->slowed_toggle = !monster->slowed_toggle; if (monster->slowed_toggle) { goto NM; } } if ((monster->m_flags & CONFUSED) && move_confused(monster)) { goto NM; } flew = 0; if ( (monster->m_flags & FLIES) && !(monster->m_flags & NAPPING) && !mon_can_go(monster, rogue.row, rogue.col)) { flew = 1; mv_1_monster(monster, rogue.row, rogue.col); if (mon_disappeared) { goto NM; } } if (!(flew && mon_can_go(monster, rogue.row, rogue.col))) { mv_1_monster(monster, rogue.row, rogue.col); } NM: test_mons = level_monsters.next_monster; monster = NULL; while (test_mons) { if (next_monster == test_mons) { monster = next_monster; break; } test_mons = test_mons -> next_monster; } } }
int seek_gold(object *monster) { short i, j, rn, s; if ((rn = get_room_number(monster->row, monster->col)) < 0) { return 0; } for (i = rooms[rn].top_row + 1; i < rooms[rn].bottom_row; i++) { for (j = rooms[rn].left_col + 1; j < rooms[rn].right_col; j++) { if ((gold_at(i, j)) && !(dungeon[i][j] & MONSTER)) { monster->m_flags |= CAN_FLIT; s = mon_can_go(monster, i, j); monster->m_flags &= (~CAN_FLIT); if (s) { move_mon_to(monster, i, j); monster->m_flags |= ASLEEP; monster->m_flags &= (~(WAKENS | SEEKS_GOLD)); return 1; } monster->m_flags &= (~SEEKS_GOLD); monster->m_flags |= CAN_FLIT; mv_monster(monster, i, j); monster->m_flags &= (~CAN_FLIT); monster->m_flags |= SEEKS_GOLD; return 1; } } } return 0; }
static int mtry(object *monster, short row, short col) { if (mon_can_go(monster, row, col)) { move_mon_to(monster, row, col); return(1); } return(0); }
void mv_aquatars(void) { object *monster; monster = level_monsters.next_monster; while (monster) { if ((monster->m_char == 'A') && mon_can_go(monster, rogue.row, rogue.col)) { mv_1_monster(monster, rogue.row, rogue.col); monster->m_flags |= ALREADY_MOVED; } monster = monster->next_monster; } }
void mv_1_monster(object *monster, short row, short col) { short i, n; boolean tried[6]; if (monster->m_flags & ASLEEP) { if (monster->m_flags & NAPPING) { if (--monster->nap_length <= 0) { monster->m_flags &= (~(NAPPING | ASLEEP)); } return; } if ((monster->m_flags & WAKENS) && rogue_is_around(monster->row, monster->col) && rand_percent(((stealthy > 0) ? (WAKE_PERCENT / (STEALTH_FACTOR + stealthy)) : WAKE_PERCENT))) { wake_up(monster); } return; } else if (monster->m_flags & ALREADY_MOVED) { monster->m_flags &= (~ALREADY_MOVED); return; } if ((monster->m_flags & FLITS) && flit(monster)) { return; } if ((monster->m_flags & STATIONARY) && (!mon_can_go(monster, rogue.row, rogue.col))) { return; } if (monster->m_flags & FREEZING_ROGUE) { return; } if ((monster->m_flags & CONFUSES) && m_confuse(monster)) { return; } if (mon_can_go(monster, rogue.row, rogue.col)) { mon_hit(monster); return; } if ((monster->m_flags & FLAMES) && flame_broil(monster)) { return; } if ((monster->m_flags & SEEKS_GOLD) && seek_gold(monster)) { return; } if ((monster->trow == monster->row) && (monster->tcol == monster->col)) { monster->trow = NO_ROOM; } else if (monster->trow != NO_ROOM) { row = monster->trow; col = monster->tcol; } if (monster->row > row) { row = monster->row - 1; } else if (monster->row < row) { row = monster->row + 1; } if ((dungeon[row][monster->col] & DOOR) && mtry(monster, row, monster->col)) { return; } if (monster->col > col) { col = monster->col - 1; } else if (monster->col < col) { col = monster->col + 1; } if ((dungeon[monster->row][col] & DOOR) && mtry(monster, monster->row, col)) { return; } if (mtry(monster, row, col)) { return; } for (i = 0; i <= 5; i++) tried[i] = 0; for (i = 0; i < 6; i++) { NEXT_TRY: n = get_rand(0, 5); switch(n) { case 0: if (!tried[n] && mtry(monster, row, monster->col-1)) { goto O; } break; case 1: if (!tried[n] && mtry(monster, row, monster->col)) { goto O; } break; case 2: if (!tried[n] && mtry(monster, row, monster->col+1)) { goto O; } break; case 3: if (!tried[n] && mtry(monster, monster->row-1, col)) { goto O; } break; case 4: if (!tried[n] && mtry(monster, monster->row, col)) { goto O; } break; case 5: if (!tried[n] && mtry(monster, monster->row+1, col)) { goto O; } break; } if (!tried[n]) { tried[n] = 1; } else { goto NEXT_TRY; } } O: if ((monster->row == monster->o_row) && (monster->col == monster->o_col)) { if (++(monster->o) > 4) { if ((monster->trow == NO_ROOM) && (!mon_sees(monster, rogue.row, rogue.col))) { monster->trow = get_rand(1, (DROWS - 2)); monster->tcol = get_rand(0, (DCOLS - 1)); } else { monster->trow = NO_ROOM; monster->o = 0; } } } else { monster->o_row = monster->row; monster->o_col = monster->col; monster->o = 0; } }