TbBool attempt_anger_job_join_enemy(struct Thing *creatng) { struct Thing *heartng; int i, n; n = ACTION_RANDOM(PLAYERS_COUNT); for (i=0; i < PLAYERS_COUNT; i++, n=(n+1)%PLAYERS_COUNT) { if ((n == game.neutral_player_num) || (n == creatng->owner)) continue; struct PlayerInfo *player; player = get_player(n); if (!player_exists(player) || (player->field_2C != 1)) continue; heartng = get_player_soul_container(n); if (thing_exists(heartng) && (heartng->active_state != 3)) { TRACE_THING(heartng); if (creature_can_navigate_to(creatng, &heartng->mappos, NavRtF_Default)) { change_creature_owner(creatng, n); anger_set_creature_anger_all_types(creatng, 0); } } } return false; }
struct Room * find_next_navigable_room_for_thing_with_capacity_and_closer_than(struct Thing *thing, int prev_room_idx, unsigned char nav_flags, long used, long *neardistance) { long distance; struct Coord3d pos; struct Room *room; unsigned long k; int i; k = 0; i = prev_room_idx; while (i != 0) { room = room_get(i); if (room_is_invalid(room)) { ERRORLOG("Jump to invalid room detected"); break; } i = room->next_of_owner; // Per-room code // Compute simplified distance - without use of mul or div distance = abs(thing->mappos.x.stl.num - (int)room->central_stl_x) + abs(thing->mappos.y.stl.num - (int)room->central_stl_y); if ((*neardistance > distance) && (room->used_capacity >= used)) { if (find_first_valid_position_for_thing_anywhere_in_room(thing, room, &pos)) { TbBool is_connected; switch (thing->class_id) { case TCls_Creature: is_connected = creature_can_navigate_to(thing, &pos, nav_flags); break; default: is_connected = navigation_points_connected(&thing->mappos, &pos); break; } if (is_connected) { *neardistance = distance; return room; } } } // Per-room code ends k++; if (k > ROOMS_COUNT) { ERRORLOG("Infinite loop detected when sweeping rooms list"); break; } } return INVALID_ROOM; }
struct Room * find_nearest_navigable_room_for_thing_with_capacity_and_closer_than(struct Thing *thing, PlayerNumber owner, RoomKind rkind, unsigned char nav_flags, long used, long *neardistance) { struct Dungeon *dungeon; struct Room *nearoom; long distance; struct Coord3d pos; struct Room *room; unsigned long k; int i; SYNCDBG(18,"Searching for %s navigable by %s index %d",room_code_name(rkind),thing_model_name(thing),(int)thing->index); dungeon = get_dungeon(owner); nearoom = INVALID_ROOM; k = 0; i = dungeon->room_kind[rkind]; while (i != 0) { room = room_get(i); if (room_is_invalid(room)) { ERRORLOG("Jump to invalid room detected"); break; } i = room->next_of_owner; // Per-room code // Compute simplified distance - without use of mul or div distance = abs(thing->mappos.x.stl.num - (int)room->central_stl_x) + abs(thing->mappos.y.stl.num - (int)room->central_stl_y); if ((*neardistance > distance) && (room->used_capacity >= used)) { if (find_first_valid_position_for_thing_anywhere_in_room(thing, room, &pos)) { if ((thing->class_id != TCls_Creature) || creature_can_navigate_to(thing, &pos, nav_flags)) { *neardistance = distance; nearoom = room; } } } // Per-room code ends k++; if (k > ROOMS_COUNT) { ERRORLOG("Infinite loop detected when sweeping rooms list"); break; } } return nearoom; }
short tunnelling(struct Thing *creatng) { struct SlabMap *slb; long speed; SYNCDBG(7,"Move %s from (%d,%d)",thing_model_name(creatng),(int)creatng->mappos.x.stl.num,(int)creatng->mappos.y.stl.num); //return _DK_tunnelling(creatng); speed = get_creature_speed(creatng); slb = get_slabmap_for_subtile(creatng->mappos.x.stl.num,creatng->mappos.y.stl.num); struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); struct Coord3d *pos; pos = &cctrl->moveto_pos; if (slabmap_owner(slb) == cctrl->party.target_plyr_idx) { internal_set_thing_state(creatng, CrSt_GoodDoingNothing); return 1; } long move_result; move_result = creature_tunnel_to(creatng, pos, speed); if (move_result == 1) { internal_set_thing_state(creatng, CrSt_TunnellerDoingNothing); return 1; } if (move_result == -1) { ERRORLOG("Bad place to tunnel to!"); set_start_state(creatng); creatng->continue_state = CrSt_Unused; return 0; } // Once per 128 turns, check if we've done digging and can now walk to the place if (((game.play_gameturn + creatng->index) & 0x7F) == 0) { if (creature_can_navigate_to(creatng, pos, NavRtF_Default)) { SYNCDBG(7,"The %s can now walk to (%d,%d), no need to tunnel",thing_model_name(creatng),(int)pos->x.stl.num,(int)pos->y.stl.num); return 1; } } SYNCDBG(7,"The %s cannot reach (%d,%d) by walk",thing_model_name(creatng),(int)pos->x.stl.num,(int)pos->y.stl.num); return 0; }
TbBool good_can_move_to_dungeon_heart(struct Thing *creatng, PlayerNumber plyr_idx) { struct PlayerInfo *player; SYNCDBG(18,"Starting"); TRACE_THING(creatng); player = get_player(plyr_idx); if (!player_exists(player)) { SYNCDBG(3,"The %s cannot move to inactive player %d heart", thing_model_name(creatng), (int)plyr_idx); return false; } struct Thing *heartng; heartng = get_player_soul_container(plyr_idx); TRACE_THING(heartng); if (thing_is_invalid(heartng)) { SYNCDBG(3,"The %s cannot move to player %d which has no heart", thing_model_name(creatng), (int)plyr_idx); return false; } return creature_can_navigate_to(creatng, &heartng->mappos, NavRtF_Default); }
/** * Returns if a creature can get to given players dungeon. * @param thing * @param plyr_idx * @return * @see creature_can_get_to_any_of_players_rooms() is a function used in similar manner. */ TbBool creature_can_get_to_dungeon(struct Thing *creatng, PlayerNumber plyr_idx) { struct PlayerInfo *player; struct Thing *heartng; SYNCDBG(18,"Starting"); player = get_player(plyr_idx); if (!player_exists(player) || (player->field_2C != 1)) { SYNCDBG(18,"The %s index %d cannot get to inactive player %d",thing_model_name(creatng),(int)creatng->index,(int)plyr_idx); return false; } heartng = get_player_soul_container(player->id_number); if (thing_is_invalid(heartng)) { SYNCDBG(18,"The %s index %d cannot get to player %d without heart",thing_model_name(creatng),(int)creatng->index,(int)plyr_idx); return false; } if (heartng->active_state == ObSt_BeingDestroyed) { SYNCDBG(18,"The %s index %d cannot get to player %d due to heart state",thing_model_name(creatng),(int)creatng->index,(int)plyr_idx); return false; } return creature_can_navigate_to(creatng, &heartng->mappos, NavRtF_Default); }