예제 #1
0
long count_player_rooms_entrances(PlayerNumber plyr_idx)
{
    struct Room *room;
    long i;
    unsigned long k;
    long count;
    count = 0;
    i = game.entrance_room_id;
    k = 0;
    while (i != 0)
    {
        room = room_get(i);
        if (room_is_invalid(room))
        {
            ERRORLOG("Jump to invalid room detected");
            break;
        }
        i = room->next_of_kind;
        // Per-room code
        if ((plyr_idx < 0) || (room->owner == plyr_idx))
            count++;
        // Per-room code ends
        k++;
        if (k > ROOMS_COUNT)
        {
            ERRORLOG("Infinite loop detected when sweeping rooms list");
            break;
        }
    }
    return count;
}
예제 #2
0
long computer_check_for_place_door(struct Computer2 *comp, struct ComputerCheck * check)
{
	if (is_newdig_enabled(comp))
		return 4;

    SYNCDBG(8,"Starting");
    ThingModel doorkind;
    struct Dungeon *dungeon;
    dungeon = comp->dungeon;
    //TODO COMPUTER_PLAYER Computer prefers to put wooden doors, and uses other types only if wooden are depleted. That should be changed.
    for (doorkind = 1; doorkind < DOOR_TYPES_COUNT; doorkind++)
    {
        if (dungeon->door_amount_stored[doorkind] <= 0) {
            continue;
        }
        long rkind;
        rkind = check->param1;
        if (rkind == 0)
        {
            rkind = (check->param2 + 1) % ROOM_TYPES_COUNT;
            check->param2 = rkind;
        }
        unsigned long k;
        k = 0;
        long i;
        i = dungeon->room_kind[rkind];
        while (i != 0)
        {
            struct Room *room;
            room = room_get(i);
            if (room_is_invalid(room))
            {
                ERRORLOG("Jump to invalid room detected");
                break;
            }
            i = room->next_of_owner;
            // Per-room code
            struct Coord3d pos;
            pos.x.val = 0;
            pos.y.val = 0;
            pos.z.val = 0;
            if (find_place_to_put_door_around_room(room, &pos))
            {
                if (try_game_action(comp, dungeon->owner, GA_PlaceDoor, 0, pos.x.stl.num, pos.y.stl.num, doorkind, 0) > Lb_OK) {
                    return CTaskRet_Unk1;
                }
            }
            // Per-room code ends
            k++;
            if (k > ROOMS_COUNT)
            {
                ERRORLOG("Infinite loop detected when sweeping rooms list");
                break;
            }
        }
    }
    return CTaskRet_Unk4;
}
예제 #3
0
long creature_add_lair_to_room(struct Thing *creatng, struct Room *room)
{
    struct Thing *lairtng;
    if (!room_has_enough_free_capacity_for_creature(room, creatng))
        return 0;
    //return _DK_creature_add_lair_to_room(thing, room);
    // Make sure we don't already have a lair on that position
    lairtng = find_creature_lair_at_subtile(creatng->mappos.x.stl.num, creatng->mappos.y.stl.num, 0);
    if (!thing_is_invalid(lairtng))
        return 0;
    struct CreatureStats *crstat;
    struct CreatureControl *cctrl;
    crstat = creature_stats_get_from_thing(creatng);
    cctrl = creature_control_get_from_thing(creatng);
    room->content_per_model[creatng->model]++;
    room->used_capacity += crstat->lair_size;
    if ((cctrl->lair_room_id > 0) && (cctrl->lairtng_idx > 0))
    {
        struct Room *room;
        room = room_get(cctrl->lair_room_id);
        creature_remove_lair_from_room(creatng, room);
    }
    cctrl->lair_room_id = room->index;
    // Create the lair thing
    struct CreatureData *crdata;
    struct Coord3d pos;
    pos.x.val = creatng->mappos.x.val;
    pos.y.val = creatng->mappos.y.val;
    pos.z.val = creatng->mappos.z.val;
    crdata = creature_data_get_from_thing(creatng);
    lairtng = create_object(&pos, crdata->field_1, creatng->owner, -1);
    if (thing_is_invalid(lairtng))
    {
        ERRORLOG("Could not create lair totem");
        remove_thing_from_mapwho(creatng);
        place_thing_in_mapwho(creatng);
        return 1; // Return that so we won't try to redo the action over and over
    }
    lairtng->mappos.z.val = get_thing_height_at(lairtng, &lairtng->mappos);
    // Associate creature with the lair
    cctrl->lairtng_idx = lairtng->index;
    lairtng->word_13 = creatng->index;
    lairtng->word_15 = 1;
    // Lair size depends on creature level
    lairtng->word_17 = 300 * cctrl->explevel / 20 + 300;
    lairtng->field_52 = ACTION_RANDOM(0x800);
    struct Objects *objdat;
    unsigned long i;
    objdat = get_objects_data_for_thing(lairtng);
    i = convert_td_iso(objdat->field_5);
    set_thing_draw(lairtng, i, objdat->field_7, lairtng->word_15, 0, -1, objdat->field_11);
    thing_play_sample(creatng, 158, NORMAL_PITCH, 0, 3, 1, 2, FULL_LOUDNESS);
    create_effect(&pos, imp_spangle_effects[creatng->owner], creatng->owner);
    anger_set_creature_anger(creatng, 0, AngR_NoLair);
    remove_thing_from_mapwho(creatng);
    place_thing_in_mapwho(creatng);
    return 1;
}
예제 #4
0
struct Room *player_has_room_of_type(PlayerNumber plyr_idx, RoomKind rkind)
{
    //return _DK_player_has_room_of_type(plyr_idx, rkind);
    struct Dungeon *dungeon;
    if (plyr_idx == game.neutral_player_num)
        return false;
    dungeon = get_players_num_dungeon(plyr_idx);
    return room_get(dungeon->room_kind[rkind]);
}
예제 #5
0
long instf_destroy(struct Thing *creatng, long *param)
{
    struct Dungeon *dungeon;
    struct Room *room;
    struct SlabMap *slb;
    MapSlabCoord slb_x,slb_y;
    long prev_owner;

    TRACE_THING(creatng);
    slb_x = subtile_slab_fast(creatng->mappos.x.stl.num);
    slb_y = subtile_slab_fast(creatng->mappos.y.stl.num);
    dungeon = get_dungeon(creatng->owner);
    slb = get_slabmap_block(slb_x, slb_y);
    room = room_get(slb->room_index);
    prev_owner = slabmap_owner(slb);

    if ( !room_is_invalid(room) && (prev_owner != creatng->owner) )
    {
        if (room->health > 1)
        {
            room->health--;
            return 0;
        }
        clear_dig_on_room_slabs(room, creatng->owner);
        if (room->owner == game.neutral_player_num)
        {
            claim_room(room, creatng);
        } else
        {
            MapCoord ccor_x,ccor_y;
            ccor_x = subtile_coord_center(room->central_stl_x);
            ccor_y = subtile_coord_center(room->central_stl_y);
            event_create_event_or_update_nearby_existing_event(ccor_x, ccor_y, EvKind_RoomLost, room->owner, 0);
            claim_enemy_room(room, creatng);
        }
        thing_play_sample(creatng, 76, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS);
        create_effects_on_room_slabs(room, imp_spangle_effects[creatng->owner], 0, creatng->owner);
        return 0;
    }
    if (slb->health > 1)
    {
        slb->health--;
        return 0;
    }
    if (prev_owner != game.neutral_player_num) {
        struct Dungeon *prev_dungeon;
        prev_dungeon = get_dungeon(prev_owner);
        prev_dungeon->lvstats.territory_lost++;
    }
    decrease_dungeon_area(prev_owner, 1);
    neutralise_enemy_block(creatng->mappos.x.stl.num, creatng->mappos.y.stl.num, creatng->owner);
    remove_traps_around_subtile(slab_subtile_center(slb_x), slab_subtile_center(slb_y), NULL);
    switch_owned_objects_on_destoyed_slab_to_neutral(slb_x, slb_y, prev_owner);
    dungeon->lvstats.territory_destroyed++;
    return 1;
}
예제 #6
0
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;
}
예제 #7
0
void init_dungeon_essential_position(struct Dungeon *dungeon)
{
    struct Room *room;
    room = room_get(dungeon->room_kind[RoK_DUNGHEART]);
    RoomKind rkind;
    for (rkind = 1; rkind < ROOM_TYPES_COUNT; rkind++)
    {
        if (!room_is_invalid(room))
            break;
        room = room_get(dungeon->room_kind[rkind]);
    }
    if (room_is_invalid(room)) {
        dungeon->essential_pos.x.val = subtile_coord_center(map_subtiles_x/2);
        dungeon->essential_pos.y.val = subtile_coord_center(map_subtiles_y/2);
        dungeon->essential_pos.z.val = subtile_coord(0,1);
        return;
    }
    dungeon->essential_pos.x.val = subtile_coord_center(room->central_stl_x);
    dungeon->essential_pos.y.val = subtile_coord_center(room->central_stl_y);
    dungeon->essential_pos.z.val = subtile_coord(0,1);
}
예제 #8
0
long computer_check_move_creatures_to_room(struct Computer2 *comp, struct ComputerCheck * check)
{
    struct Dungeon *dungeon;
    struct Room *room;
    dungeon = comp->dungeon;
    SYNCDBG(8,"Checking player %d for move to %s", (int)dungeon->owner, room_code_name(check->param2));
    int num_to_move;
    num_to_move = check->param1 * dungeon->num_active_creatrs / 100;
    if (num_to_move <= 0) {
        SYNCDBG(8,"No creatures to move, active %d percentage %d", (int)dungeon->num_active_creatrs, (int)check->param1);
        return CTaskRet_Unk4;
    }
    if (computer_able_to_use_magic(comp, PwrK_HAND, 1, num_to_move) != 1) {
        return CTaskRet_Unk4;
    }
    // If there's already task in progress which uses hand, then don't add more
    // content of the hand could be used by wrong task by mistake
    if (is_task_in_progress_using_hand(comp)) {
        return CTaskRet_Unk4;
    }
    unsigned long k;
    long i;
    k = 0;
    i = dungeon->room_kind[check->param2];
    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
        if (room->total_capacity > room->used_capacity)
        {
            int num_to_move_fit;
            num_to_move_fit = min(num_to_move, room->total_capacity - room->used_capacity);
            if (create_task_move_creatures_to_room(comp, room->index, num_to_move_fit)) {
                SYNCDBG(8,"Added task to move %d creatures to %s index %d", (int)num_to_move_fit,room_code_name(room->kind),(int)room->index);
                return CTaskRet_Unk1;
            }
        }
        // Per-room code ends
        k++;
        if (k > ROOMS_COUNT)
        {
            ERRORLOG("Infinite loop detected when sweeping rooms list");
            break;
        }
    }
    return CTaskRet_Unk4;
}
예제 #9
0
long computer_check_move_creatures_to_room(struct Computer2 *comp, struct ComputerCheck * check)
{
    struct Dungeon *dungeon;
    struct Room *room;
    dungeon = comp->dungeon;
    SYNCDBG(8,"Checking player %d for move to %s", (int)dungeon->owner, room_code_name(check->param2));
    //return _DK_computer_check_move_creatures_to_room(comp, check);
    //TODO check if should be changed to computer_able_to_use_magic()
    if (!is_power_available(dungeon->owner, PwrK_HAND)) {
        return 4;
    }
    int num_to_move;
    num_to_move = check->param1 * dungeon->num_active_creatrs / 100;
    if (num_to_move <= 0) {
        SYNCDBG(8,"No creatures to move, active %d percentage %d", (int)dungeon->num_active_creatrs, (int)check->param1);
        return 4;
    }
    if (is_task_in_progress(comp, CTT_MoveCreatureToRoom)) {
        return 4;
    }
    unsigned long k;
    long i;
    k = 0;
    i = dungeon->room_kind[check->param2];
    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
        if (room->total_capacity > room->used_capacity)
        {
            if (create_task_move_creatures_to_room(comp, room->index, num_to_move)) {
                SYNCDBG(8,"Added task to move %d creatures to %s index %d", (int)num_to_move,room_code_name(room->kind),(int)room->index);
                return 1;
            }
        }
        // Per-room code ends
        k++;
        if (k > ROOMS_COUNT)
        {
            ERRORLOG("Infinite loop detected when sweeping rooms list");
            break;
        }
    }
    return 4;
}
예제 #10
0
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;
}
예제 #11
0
long computer_check_for_expand_room_kind(struct Computer2 *comp, struct ComputerCheck * check, RoomKind rkind, long max_slabs, long around_start)
{
    struct Dungeon *dungeon;
    dungeon = comp->dungeon;
    {
        struct RoomStats *rstat;
        rstat = room_stats_get_for_kind(rkind);
        // If we don't have money for the room - don't even try
        // Check price for two slabs - after all, we don't want to end up having nothing
        if (2*rstat->cost >= dungeon->total_money_owned) {
            return 0;
        }
    }
    MapSubtlCoord max_radius;
    // Don't allow the room to be made into long, narrow shape
    max_radius = 3 * slab_subtile(LbSqrL(max_slabs),2) / 4;
    struct Room *room;
    long i;
    unsigned long k;
    i = dungeon->room_kind[rkind];
    k = 0;
    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
        if ((room->slabs_count > 0) && (room->slabs_count < max_slabs)) {
            if (computer_check_for_expand_specific_room(comp, check, room, max_radius, around_start)) {
                SYNCDBG(6,"The %s index %d will be expanded",room_code_name(room->kind),(int)room->index);
                return 1;
            }
        }
        // Per-room code ends
        k++;
        if (k > ROOMS_COUNT)
        {
          ERRORLOG("Infinite loop detected when sweeping rooms list");
          break;
        }
    }
    return 0;
}
예제 #12
0
struct Room *get_player_room_of_kind_nearest_to(PlayerNumber plyr_idx, RoomKind rkind,
    MapSubtlCoord stl_x, MapSubtlCoord stl_y, long *retdist)
{
    struct Dungeon *dungeon;
    struct Room *room;
    long i;
    unsigned long k;
    dungeon = get_dungeon(plyr_idx);
    struct Room *nearest_room;
    long nearest_dist;
    nearest_dist = LONG_MAX;
    nearest_room = INVALID_ROOM;
    i = dungeon->room_kind[rkind];
    k = 0;
    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
      long dist;
      dist = abs(room->central_stl_y - stl_y) + abs(room->central_stl_x - stl_x);
      if (dist < nearest_dist)
      {
          nearest_dist = dist;
          nearest_room = room;
      }
      // Per-room code ends
      k++;
      if (k > ROOMS_COUNT)
      {
          ERRORLOG("Infinite loop detected when sweeping rooms list");
          break;
      }
    }
    if (retdist != NULL)
        *retdist = nearest_dist;
    return nearest_room;
}
예제 #13
0
struct Thing *computer_check_creatures_in_dungeon_rooms_of_kind_for_accelerate(struct Computer2 *comp, RoomKind rkind)
{
    struct Dungeon *dungeon;
    struct Room *room;
    struct Thing *thing;
    long i;
    unsigned long k;
    if ((rkind < 1) || (rkind > ROOM_TYPES_COUNT))
    {
        ERRORLOG("Invalid room kind %d",(int)rkind);
        return INVALID_THING;
    }
    dungeon = comp->dungeon;
    if (dungeon_invalid(dungeon))
    {
        ERRORLOG("Invalid computer players dungeon");
        return INVALID_THING;
    }
    i = dungeon->room_kind[rkind];
    k = 0;
    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
        thing = computer_check_creatures_in_room_for_accelerate(comp, room);
        if (!thing_is_invalid(thing))
            return thing;
        // Per-room code ends
        k++;
        if (k > ROOMS_COUNT)
        {
          ERRORLOG("Infinite loop detected when sweeping rooms list");
          break;
        }
    }
    return INVALID_THING;
}
예제 #14
0
struct Room *get_opponent_room(struct Computer2 *comp, PlayerNumber plyr_idx)
{
    static const RoomKind opponent_room_kinds[] = {RoK_DUNGHEART, RoK_PRISON, RoK_LIBRARY, RoK_TREASURE};
    struct Dungeon *dungeon;
    struct Room *room;
    dungeon = get_players_num_dungeon(plyr_idx);
    if (dungeon_invalid(dungeon) || (slab_conf.room_types_count < 1)) {
        return INVALID_ROOM;
    }
    int i,n;
    n = opponent_room_kinds[ACTION_RANDOM(sizeof(opponent_room_kinds)/sizeof(opponent_room_kinds[0]))];
    for (i=0; i < slab_conf.room_types_count; i++)
    {
        room = room_get(dungeon->room_kind[n]);
        if (room_exists(room)) {
            return room;
        }
        n = (n + 1) % slab_conf.room_types_count;
    }
    return INVALID_ROOM;
}
예제 #15
0
/**
 * Counts amount of rooms of specific type owned by specific player.
 * @param plyr_idx The player number. Only specific player number is accepted.
 * @param rkind Room kind to count. Only specific kind is accepted.
 */
long count_player_rooms_of_type(PlayerNumber plyr_idx, RoomKind rkind)
{
    struct Dungeon *dungeon;
    struct Room *room;
    long i;
    unsigned long k;
    // note that we can't get_players_num_dungeon() because players
    // may be uninitialized yet when this is called.
    dungeon = get_dungeon(plyr_idx);
    if (dungeon_invalid(dungeon))
        return 0;
    i = dungeon->room_kind[rkind];
    k = 0;
    while (i != 0)
    {
        room = room_get(i);
        if (room_is_invalid(room))
        {
            ERRORLOG("Jump to invalid room detected");
            break;
        }
        i = room->next_of_owner;
        // No Per-room code - we only want count
        SYNCDBG(19,"Player %d has %s at (%d,%d)",(int)plyr_idx, room_code_name(room->kind), (int)room->central_stl_x, (int)room->central_stl_y);
        if (room->owner != plyr_idx) {
            ERRORDBG(3,"Player %d has bad room in %s list; it's really %s index %d owned by player %d",(int)plyr_idx, room_code_name(rkind), room_code_name(room->kind), (int)room->index, (int)room->owner);
            break;
        }
        k++;
        if (k > ROOMS_COUNT)
        {
            ERRORLOG("Infinite loop detected when sweeping rooms list");
            break;
        }
    }
    return k;
}
예제 #16
0
/**
 * User thread responsible for handling individual clients
 * @param arg Structure to use to process the thread
 */
void *user_thread( void *arg ) {

	User user = new_user( ((Environment)arg)->client );
	Management manager = ((Environment)arg)->manager;

    // increase thread count
    manager_up_thread( manager, pthread_self() );

    // lock user for now
    user_lock( user );

	    // add the user to the list of users
	    manager_add_user( manager, user );

	    // turn client on
	    client_ok( user->client );

    // ready user for commo
    user_unlock( user );



	/* ---------------------------------------------
	 * Login screen
	 */

    Room login_room = room_get( manager->rooms, 0 );    

    if( login_room == NULL ){
        printf("Error getting login room\n");
        //return 0;
    }

    char_set_room( user->parent->character, login_room );

    // have a look
    action_look( NULL, user, manager );

    // client_prompt(  )


	// accept input
	
	// initialize
    int buff_len = 256;
	char *buff = (char *) malloc( buff_len );
	memset( buff, 0, 256 );
	if( buff == NULL ){
	    perror("client thread recv buffer malloc");
	    return NULL;
	}

	// user response loop
	while( manager->cease != 1 && (user->flags & USER_FLAG_EXIT) == 0 ){

		// receive response from client
		int length = client_recv( 
		    user->client, 
		    &buff, 
		    &buff_len );

		// handle response
		if( buff != NULL && length > 0 ){

			// parse the response for actionable text
			action_parse_response( 
			    buff,       // buffer with response
			    length,     // length of response
			    user,       // user making response
			    manager );  // manager

            // reset response
            memset(buff,0,length);

		} else {
		    // nothing going on, yield
		    sched_yield();
		}

	}
	
	free( buff );



	// remove from manager list
	manager_remove_user( manager, user );

    // lock user for this    
	user_lock( user );
	
	// close and destory all structs
	// manually manage this part
	close_client( user->client );
	destroy_client( user->client );
	
	// user gone from manager so safe to unlock a head
	user_unlock( user );
	
	// now destroy
	destroy_user( user );
	
	free( ((Environment)arg) );

    // decrease thread count
    manager_down_thread( manager, pthread_self() );
    pthread_exit( 0 );

	return NULL;
}
예제 #17
0
long computer_check_enemy_entrances(struct Computer2 *comp, struct ComputerCheck * check)
{
    SYNCDBG(8,"Starting");
    //return _DK_computer_check_enemy_entrances(comp, check);
    long result;
    result = 4;
    PlayerNumber plyr_idx;
    for (plyr_idx=0; plyr_idx < PLAYERS_COUNT; plyr_idx++)
    {
        if (comp->dungeon->owner == plyr_idx) {
            continue;
        }
        if (players_are_mutual_allies(comp->dungeon->owner, plyr_idx)) {
            continue;
        }
        struct PlayerInfo *player;
        struct Dungeon *dungeon;
        player = get_player(plyr_idx);
        dungeon = get_players_dungeon(player);
        long i;
        unsigned long k;
        i = dungeon->room_kind[RoK_ENTRANCE];
        k = 0;
        while (i != 0)
        {
            struct Room *room;
            room = room_get(i);
            if (room_is_invalid(room))
            {
                ERRORLOG("Jump to invalid room detected");
                break;
            }
            i = room->next_of_owner;
            // Per-room code
            struct Comp2_UnkStr1 *unkptr;
            unkptr = &comp->unkarr_A10[(int)plyr_idx];
            long n;
            for (n = 0; n < 64; n++)
            {
                struct Coord3d *pos;
                pos = &unkptr->pos_A[n];
                if ((pos->x.val == subtile_coord(room->central_stl_x,0)) && (pos->y.val == subtile_coord(room->central_stl_y,0))) {
                    break;
                }
            }
            if (n == 64)
            {
                struct Coord3d *pos;
                n = unkptr->field_4;
                unkptr->field_4 = (n + 1) % 64;
                unkptr->field_0 = game.play_gameturn;
                pos = &unkptr->pos_A[n];
                pos->x.val = subtile_coord(room->central_stl_x,0);
                pos->y.val = subtile_coord(room->central_stl_y,0);
                pos->z.val = subtile_coord(1,0);
                result = 2;
            }
            // Per-room code ends
            k++;
            if (k > ROOMS_COUNT)
            {
                ERRORLOG("Infinite loop detected when sweeping rooms list");
                break;
            }
        }
    }
    return result;
}