Beispiel #1
0
void CUICarBodyWnd::TakeAll()
{
	u32 cnt				= m_pUIOthersBagList->ItemsCount();
	u16 tmp_id = 0;
	if(m_pInventoryBox){
		tmp_id	= (smart_cast<CGameObject*>(m_pOurObject))->ID();
	}

	for(u32 i=0; i<cnt; ++i)
	{
		CUICellItem*	ci = m_pUIOthersBagList->GetItemIdx(i);
		for(u32 j=0; j<ci->ChildsCount(); ++j)
		{
			PIItem _itm		= (PIItem)(ci->Child(j)->m_pData);
			if(m_pOthersObject)
				TransferItem	(_itm, m_pOthersObject, m_pOurObject, false);
			else{
				move_item		(m_pInventoryBox->ID(), tmp_id, _itm->object().ID());
//.				Actor()->callback(GameObject::eInvBoxItemTake)( m_pInventoryBox->lua_game_object(), _itm->object().lua_game_object() );
			}
		
		}
		PIItem itm		= (PIItem)(ci->m_pData);
		if(m_pOthersObject)
			TransferItem	(itm, m_pOthersObject, m_pOurObject, false);
		else{
			move_item		(m_pInventoryBox->ID(), tmp_id, itm->object().ID());
//.			Actor()->callback(GameObject::eInvBoxItemTake)(m_pInventoryBox->lua_game_object(), itm->object().lua_game_object() );
		}

	}
}
Beispiel #2
0
bool CUICarBodyWnd::OnItemDbClick(CUICellItem* itm)
{
	CUIDragDropListEx*	old_owner		= itm->OwnerList();
	CUIDragDropListEx*	new_owner		= (old_owner==m_pUIOthersBagList)?m_pUIOurBagList:m_pUIOthersBagList;

	if(m_pOthersObject)
	{
		if( TransferItem		(	CurrentIItem(),
								(old_owner==m_pUIOthersBagList)?m_pOthersObject:m_pOurObject, 
								(old_owner==m_pUIOurBagList)?m_pOthersObject:m_pOurObject, 
								(old_owner==m_pUIOurBagList)
								)
			)
		{
			CUICellItem* ci			= old_owner->RemoveItem(CurrentItem(), false);
			new_owner->SetItem		(ci);
		}
	}else
	{
		if(false && old_owner==m_pUIOurBagList) return true;
		bool bMoveDirection		= (old_owner==m_pUIOthersBagList);

		u16 tmp_id				= (smart_cast<CGameObject*>(m_pOurObject))->ID();
		move_item				(
								bMoveDirection?m_pInventoryBox->ID():tmp_id,
								bMoveDirection?tmp_id:m_pInventoryBox->ID(),
								CurrentIItem()->object().ID());
//.		Actor()->callback		(GameObject::eInvBoxItemTake)(m_pInventoryBox->lua_game_object(), CurrentIItem()->object().lua_game_object() );

	}
	SetCurrentItem				(NULL);

	return						true;
}
Beispiel #3
0
bool CUITradeWnd::ToOthersBag()
{
	move_item				(CurrentItem(), &m_uidata->UIOthersTradeList, &m_uidata->UIOthersBagList);
	UpdatePrices			();

	return					true;
}
Beispiel #4
0
bool CUITradeWnd::ToOurTrade()
{
	if (!CanMoveToOther(CurrentIItem()))	return false;

	move_item				(CurrentItem(), &m_uidata->UIOurBagList, &m_uidata->UIOurTradeList);
	UpdatePrices			();
	return					true;
}
Beispiel #5
0
void merge_invlet_test( player &dummy, inventory_location from )
{
    // invlet to assign
    constexpr char invlet_1 = '{';
    constexpr char invlet_2 = '}';

    // should merge from a place other than the inventory
    REQUIRE( from != INVENTORY );
    // cannot assign invlet to items on the ground
    REQUIRE( from != GROUND );

    for( int id = 0; id < INVLET_STATE_NUM * INVLET_STATE_NUM; ++id ) {
        // how to assign invlet to the first item
        invlet_state first_invlet_state = invlet_state( id % INVLET_STATE_NUM );
        // how to assign invlet to the second item
        invlet_state second_invlet_state = invlet_state( id / INVLET_STATE_NUM );
        // what the invlet should be for the merged stack
        invlet_state expected_merged_invlet_state = first_invlet_state != NONE ? first_invlet_state : second_invlet_state;
        char expected_merged_invlet = first_invlet_state != NONE ? invlet_1 : second_invlet_state != NONE ? invlet_2 : 0;

        // remove all items
        dummy.inv.clear();
        dummy.worn.clear();
        dummy.remove_weapon();
        g->m.i_clear( dummy.pos() );

        // some stackable item
        item tshirt( "tshirt" );

        // add the item
        add_item( dummy, tshirt, INVENTORY );
        add_item( dummy, tshirt, from );

        // assign the items with invlets
        assign_invlet( dummy, item_at( dummy, 0, INVENTORY ), invlet_1, first_invlet_state );
        assign_invlet( dummy, item_at( dummy, 0, from ), invlet_2, second_invlet_state );

        // merge the second item into inventory
        move_item( dummy, 0, from, INVENTORY );

        item &merged_item = item_at( dummy, 0, INVENTORY );
        invlet_state merged_invlet_state = check_invlet( dummy, merged_item, expected_merged_invlet );
        char merged_invlet = merged_item.invlet;

        std::stringstream ss;
        ss << "1. add two stackable items to the inventory and " << location_desc( from ) << std::endl;
        ss << "2. assign " << invlet_state_desc( first_invlet_state ) << " invlet " << invlet_1 << " to the item in the inventory " << std::endl;
        ss << "3. assign " << invlet_state_desc( second_invlet_state ) << " invlet " << invlet_2 << " to the " << location_desc( from ) << std::endl;
        ss << "4. " << move_action_desc( 0, from, INVENTORY ) << std::endl;
        ss << "expect the stack in the inventory to have " << invlet_state_desc( expected_merged_invlet_state ) << " invlet " << expected_merged_invlet << std::endl;
        ss << "the stack actually has " << invlet_state_desc( merged_invlet_state ) << " invlet " << merged_invlet << std::endl;
        INFO( ss.str() );
        REQUIRE( merged_item.typeId() == tshirt.typeId() );
        CHECK( merged_invlet_state == expected_merged_invlet_state );
        CHECK( merged_invlet == expected_merged_invlet );
    }
}
Beispiel #6
0
/**
 * @brief sort_items
 * @param start
 * @return
 */
struct nodelist_item  *sort_items( struct nodelist_item *start ){
    if( start == NULL ){
        return NULL;
    }
    start->next = sort_items(start->next);
    if( start->next != NULL && start->slot_gain > start->next->slot_gain ) {
        start = move_item( start );
    }
    return start;
}
Beispiel #7
0
void stack_invlet_test( player &dummy, inventory_location from, inventory_location to )
{
    // invlet to assign
    constexpr char invlet = '|';

    // duplication will most likely only happen if the stack is in the inventory
    // and is subsequently wielded or worn
    if( from != INVENTORY || ( to != WORN && to != WIELDED_OR_WORN ) ) {
        FAIL( "unimplemented" );
    }

    // remove all items
    dummy.inv.clear();
    dummy.worn.clear();
    dummy.remove_weapon();
    g->m.i_clear( dummy.pos() );

    // some stackable item that can be wielded and worn
    item tshirt( "tshirt" );

    // add two such items to the starting position
    add_item( dummy, tshirt, from );
    add_item( dummy, tshirt, from );

    // assign the stack with invlet
    assign_invlet( dummy, item_at( dummy, 0, from ), invlet, CACHED );

    // wield or wear one of the items
    move_item( dummy, 0, from, to );

    std::stringstream ss;
    ss << "1. add a stack of two same items to " << location_desc( from ) << std::endl;
    ss << "2. assign the stack with an invlet" << std::endl;
    ss << "3. " << move_action_desc( 0, from, to ) << std::endl;
    ss << "expect the two items to have different invlets" << std::endl;
    ss << "actually the two items have " <<
       ( item_at( dummy, 0, to ).invlet != item_at( dummy, 0, from ).invlet ? "different" : "the same" ) <<
       " invlets" << std::endl;
    INFO( ss.str() );
    REQUIRE( item_at( dummy, 0, from ).typeId() == tshirt.typeId() );
    REQUIRE( item_at( dummy, 0, to ).typeId() == tshirt.typeId() );
    // the wielded/worn item should have different invlet from the remaining item
    CHECK( item_at( dummy, 0, to ).invlet != item_at( dummy, 0, from ).invlet );

    // clear invlets
    assign_invlet( dummy, item_at( dummy, 0, from ), invlet, NONE );
    assign_invlet( dummy, item_at( dummy, 0, to ), invlet, NONE );
}
Beispiel #8
0
bool CUICarBodyWnd::TransferItem(PIItem itm, CInventoryOwner* owner_from, CInventoryOwner* owner_to, bool b_check)
{
	VERIFY									(NULL==m_pInventoryBox);
	CGameObject* go_from					= smart_cast<CGameObject*>(owner_from);
	CGameObject* go_to						= smart_cast<CGameObject*>(owner_to);

	if(smart_cast<CBaseMonster*>(go_to))	return false;
	if(b_check)
	{
		float invWeight						= owner_to->inventory().CalcTotalWeight();
		float maxWeight						= owner_to->inventory().GetMaxWeight();
		float itmWeight						= itm->Weight();
		if(invWeight+itmWeight >=maxWeight)	return false;
	}

	move_item(go_from->ID(), go_to->ID(), itm->object().ID());

	return true;
}
Beispiel #9
0
void invlet_test( player &dummy, inventory_location from, inventory_location to )
{
    // invlet to assign
    constexpr char invlet = '|';

    // iterate through all permutations of test actions
    for( int id = 0; id < INVLET_STATE_NUM * INVLET_STATE_NUM * TEST_ACTION_NUM; ++id ) {
        // how to assign invlet to the first item
        invlet_state first_invlet_state = invlet_state( id % INVLET_STATE_NUM );
        // how to assign invlet to the second item
        invlet_state second_invlet_state = invlet_state( id / INVLET_STATE_NUM % INVLET_STATE_NUM );
        // the test steps
        test_action action = test_action( id / INVLET_STATE_NUM / INVLET_STATE_NUM % TEST_ACTION_NUM );

        // the final expected invlet state of the two items
        invlet_state expected_first_invlet_state = second_invlet_state == NONE ? first_invlet_state : NONE;
        invlet_state expected_second_invlet_state = second_invlet_state;

        // remove all items
        dummy.inv.clear();
        dummy.worn.clear();
        dummy.remove_weapon();
        g->m.i_clear( dummy.pos() );

        // some two items that can be wielded, worn, and picked up
        item tshirt( "tshirt" );
        item jeans( "jeans" );

        // add the items to the starting position
        add_item( dummy, tshirt, to );
        add_item( dummy, jeans, to );

        // assign invlet to the first item
        assign_invlet( dummy, item_at( dummy, 0, to ), invlet, first_invlet_state );

        // remove the first item
        move_item( dummy, 0, to, from );

        // assign invlet to the second item
        assign_invlet( dummy, item_at( dummy, 0, to ), invlet, second_invlet_state );

        item *final_first = nullptr, *final_second = nullptr;
        switch( action ) {
            case REMOVE_1ST_REMOVE_2ND_ADD_1ST_ADD_2ND:
                move_item( dummy, 0, to, from );
                move_item( dummy, 0, from, to );
                move_item( dummy, 0, from, to );
                final_first = &item_at( dummy, 0, to );
                final_second = &item_at( dummy, 1, to );
                break;
            case REMOVE_1ST_REMOVE_2ND_ADD_2ND_ADD_1ST:
                move_item( dummy, 0, to, from );
                move_item( dummy, 1, from, to );
                move_item( dummy, 0, from, to );
                final_first = &item_at( dummy, 1, to );
                final_second = &item_at( dummy, 0, to );
                break;
            case REMOVE_1ST_ADD_1ST:
                move_item( dummy, 0, from, to );
                final_first = &item_at( dummy, 1, to );
                final_second = &item_at( dummy, 0, to );
                break;
            default:
                FAIL( "unimplemented" );
                break;
        }

        invlet_state final_first_invlet_state = check_invlet( dummy, *final_first, invlet ),
                     final_second_invlet_state = check_invlet( dummy, *final_second, invlet );

        INFO( test_action_desc( action, from, to, first_invlet_state, second_invlet_state,
                                expected_first_invlet_state, expected_second_invlet_state, final_first_invlet_state,
                                final_second_invlet_state ) );
        REQUIRE( final_first->typeId() == tshirt.typeId() );
        REQUIRE( final_second->typeId() == jeans.typeId() );
        CHECK( final_first_invlet_state == expected_first_invlet_state );
        CHECK( final_second_invlet_state == expected_second_invlet_state );

        // clear invlets
        assign_invlet( dummy, *final_first, invlet, NONE );
        assign_invlet( dummy, *final_second, invlet, NONE );
    }
}
int
d_capture_beasts(struct command *c)
{
  int type, piety, from = 0;
  int target = c->a;

  if (!has_holy_symbol(c->who)) {
    wout(c->who, "You must have a holy symbol to capture wild beasts.");
    return FALSE;
  };

  if (!has_holy_plant(c->who)) {
    wout(c->who, "Capturing wild beasts requires a holy plant.");
    return FALSE;
  };

  /*
   *  Target should be a character (oddly enough)
   *
   */
  if (kind(target) != T_char) {
    wout(c->who, "You cannot capture beasts from %s.",box_name(target));
    return FALSE;
  };

  /*
   *  In same location.
   *
   */
    
  if (!check_char_here(c->who, target)) {
    wout(c->who, "%s is not here.",box_name(c->a));
    return FALSE;
  };

  if (is_prisoner(target)) {
    wout(c->who, "Cannot capture beasts from prisoners.");
    return FALSE;
  };

  if (c->who == target) {
    wout(c->who, "Can't capture beasts from oneself.");
    return FALSE;
  };

  if (stack_leader(c->who) == stack_leader(target)) {
    wout(c->who, "Can't capture beasts from a member of the same stack.");
    return FALSE;
  };

  /*
   *  Now select a random beast from the target.  That can be either the
   *  target itself, or one of the beasts in the target's inventory.  In
   *  any case, the beast's statistics determine the piety cost of the
   *  spell.
   *
   *  Note that who the beast is "from" is also returned.
   *
   */
  type = get_random_beast(target, &from);

  if (!type || !item_animal(type)) {
    wout(c->who, "%s has no beasts that you can capture.", box_name(target));
    return FALSE;
  };

  piety = ((item_attack(type) + item_defense(type)) / 50.0) + 1.5;

  /*
   *  Perhaps he hasn't the piety.
   *
   */
  if (!has_piety(c->who, piety)) {
    wout(c->who, "You lack the piety to lure a beast from %s.",
	 box_name(target));
    return FALSE;
  };
  
  /*
   *  Lure the beast away.
   *
   */
  if (!move_item(from, c->who, type, 1)) {
    /*
     *  Possibly it is "from" himself who we are capturing.
     *
     */
    if (subkind(from) == sub_ni && item_animal(noble_item(from))) {
      wout(c->who, "You capture %s!",box_name(target));
      use_piety(c->who, piety);
      take_prisoner(c->who, from);
      /*
       *  Fri Mar 24 06:56:46 2000 -- Scott Turner
       *
       *  Take prisoner doesn't actually transfer the animal into your
       *  inventory, so we'll have to "create" one.
       *
       */
      gen_item(c->who, type, 1);
      return TRUE;
    };
    wout(c->who,"For some reason, you capture no beast.");
    return FALSE;
  };
  wout(c->who, "You capture a %s from %s!",box_name(type), box_name(target));
  use_piety(c->who, piety);
  return TRUE;
  
};
Beispiel #11
0
int btree_delete(btree_t bt, const void *key)
{
	const struct btree_def *def = bt->def;
	const int halfsize = def->branches / 2;
	struct btree_page *path[MAX_HEIGHT] = {0};
	int slot[MAX_HEIGHT] = {0};
	int h;

	check_btree(bt);

	/* Trace a path to the item to be deleted */
	if (!key) {
		if (bt->slot[0] < 0)
			return 1;

		memcpy(path, bt->path, sizeof(path));
		memcpy(slot, bt->slot, sizeof(slot));
	} else if (!trace_path(bt, key, path, slot)) {
		return 1;
	}

	/* Select the next item if we're deleting at the cursor */
	if (bt->slot[0] == slot[0] && bt->path[0] == path[0])
		cursor_next(bt);

	/* Delete from the leaf node. If it's still full enough, then we don't
	 * need to do anything else.
	 */
	delete_item(path[0], slot[0]);
	if (path[0]->num_children >= halfsize)
		return 0;

	/* Trace back up the tree, fixing underfull nodes. If we can fix by
	 * borrowing, do it and we're done. Otherwise, we need to fix by
	 * merging, which may result in another underfull node, and we need
	 * to continue.
	 */
	for (h = 1; h <= bt->root->height; h++) {
		struct btree_page *p = path[h];
		struct btree_page *c = path[h - 1];
		int s = slot[h];

		if (s > 0) {
			/* Borrow/merge from lower page */
			struct btree_page *d = *PAGE_PTR(p, s - 1);

			if (d->num_children > halfsize) {
				move_item(d, d->num_children - 1, c, 0);
				memcpy(PAGE_KEY(p, s), PAGE_KEY(c, 0),
				       def->key_size);
				return 0;
			}

			merge_pages(d, c);
			delete_item(p, s);
			free(c);
		} else {
			/* Borrow/merge from higher page */
			struct btree_page *d = *PAGE_PTR(p, s + 1);

			if (d->num_children > halfsize) {
				move_item(d, 0, c, c->num_children);
				memcpy(PAGE_KEY(p, s + 1),
				       PAGE_KEY(d, 0),
				       def->key_size);
				return 0;
			}

			merge_pages(c, d);
			delete_item(p, s + 1);
			free(d);
		}

		if (p->num_children >= halfsize)
			return 0;
	}

	/* If the root contains only a single pointer to another page,
	 * shrink the tree. This does not affect the cursor.
	 */
	if (bt->root->height && bt->root->num_children == 1) {
		struct btree_page *old = bt->root;

		bt->root = *PAGE_PTR(old, 0);
		free(old);
	}

	return 0;
}
void activity_on_turn_move_loot( player_activity &, player &p )
{
    const activity_id act_move_loot = activity_id( "ACT_MOVE_LOOT" );
    auto &mgr = zone_manager::get_manager();
    if( g->m.check_vehicle_zones( g->get_levz() ) ) {
        mgr.cache_vzones();
    }
    const auto abspos = g->m.getabs( p.pos() );
    const auto &src_set = mgr.get_near( zone_type_id( "LOOT_UNSORTED" ), abspos );
    vehicle *src_veh, *dest_veh;
    int src_part, dest_part;

    // Nuke the current activity, leaving the backlog alone.
    p.activity = player_activity();

    // sort source tiles by distance
    const auto &src_sorted = get_sorted_tiles_by_distance( abspos, src_set );

    if( !mgr.is_sorting() ) {
        mgr.start_sort( src_sorted );
    }

    for( auto &src : src_sorted ) {
        const auto &src_loc = g->m.getlocal( src );
        if( !g->m.inbounds( src_loc ) ) {
            if( !g->m.inbounds( p.pos() ) ) {
                // p is implicitly an NPC that has been moved off the map, so reset the activity
                // and unload them
                p.assign_activity( act_move_loot );
                p.set_moves( 0 );
                g->reload_npcs();
                mgr.end_sort();
                return;
            }
            std::vector<tripoint> route;
            route = g->m.route( p.pos(), src_loc, p.get_pathfinding_settings(),
                                p.get_path_avoid() );
            if( route.empty() ) {
                // can't get there, can't do anything, skip it
                continue;
            }
            p.set_destination( route, player_activity( act_move_loot ) );
            mgr.end_sort();
            return;
        }

        bool is_adjacent_or_closer = square_dist( p.pos(), src_loc ) <= 1;

        // skip tiles in IGNORE zone and tiles on fire
        // (to prevent taking out wood off the lit brazier)
        // and inaccessible furniture, like filled charcoal kiln
        if( mgr.has( zone_type_id( "LOOT_IGNORE" ), src ) ||
            g->m.get_field( src_loc, fd_fire ) != nullptr ||
            !g->m.can_put_items_ter_furn( src_loc ) ) {
            continue;
        }

        // the boolean in this pair being true indicates the item is from a vehicle storage space
        auto items = std::vector<std::pair<item *, bool>>();

        //Check source for cargo part
        //map_stack and vehicle_stack are different types but inherit from item_stack
        // TODO: use one for loop
        if( const cata::optional<vpart_reference> vp = g->m.veh_at( src_loc ).part_with_feature( "CARGO",
                false ) ) {
            src_veh = &vp->vehicle();
            src_part = vp->part_index();
            for( auto &it : src_veh->get_items( src_part ) ) {
                items.push_back( std::make_pair( &it, true ) );
            }
        } else {
            src_veh = nullptr;
            src_part = -1;
        }
        for( auto &it : g->m.i_at( src_loc ) ) {
            items.push_back( std::make_pair( &it, false ) );
        }
        //Skip items that have already been processed
        for( auto it = items.begin() + mgr.get_num_processed( src ); it < items.end(); it++ ) {

            mgr.increment_num_processed( src );

            const auto thisitem = it->first;

            if( thisitem->made_of_from_type( LIQUID ) ) { // skip unpickable liquid
                continue;
            }

            // Only if it's from a vehicle do we use the vehicle source location information.
            vehicle *this_veh = it->second ? src_veh : nullptr;
            const int this_part = it->second ? src_part : -1;

            const auto id = mgr.get_near_zone_type_for_item( *thisitem, abspos );

            // checks whether the item is already on correct loot zone or not
            // if it is, we can skip such item, if not we move the item to correct pile
            // think empty bag on food pile, after you ate the content
            if( !mgr.has( id, src ) ) {
                const auto &dest_set = mgr.get_near( id, abspos );

                for( auto &dest : dest_set ) {
                    const auto &dest_loc = g->m.getlocal( dest );

                    //Check destination for cargo part
                    if( const cata::optional<vpart_reference> vp = g->m.veh_at( dest_loc ).part_with_feature( "CARGO",
                            false ) ) {
                        dest_veh = &vp->vehicle();
                        dest_part = vp->part_index();
                    } else {
                        dest_veh = nullptr;
                        dest_part = -1;
                    }

                    // skip tiles with inaccessible furniture, like filled charcoal kiln
                    if( !g->m.can_put_items_ter_furn( dest_loc ) ) {
                        continue;
                    }

                    units::volume free_space;
                    // if there's a vehicle with space do not check the tile beneath
                    if( dest_veh ) {
                        free_space = dest_veh->free_volume( dest_part );
                    } else {
                        free_space = g->m.free_volume( dest_loc );
                    }
                    // check free space at destination
                    if( free_space >= thisitem->volume() ) {
                        // before we move any item, check if player is at or
                        // adjacent to the loot source tile
                        if( !is_adjacent_or_closer ) {
                            std::vector<tripoint> route;
                            bool adjacent = false;

                            // get either direct route or route to nearest adjacent tile if
                            // source tile is impassable
                            if( g->m.passable( src_loc ) ) {
                                route = g->m.route( p.pos(), src_loc, p.get_pathfinding_settings(),
                                                    p.get_path_avoid() );
                            } else {
                                // immpassable source tile (locker etc.),
                                // get route to nerest adjacent tile instead
                                route = route_adjacent( p, src_loc );
                                adjacent = true;
                            }

                            // check if we found path to source / adjacent tile
                            if( route.empty() ) {
                                add_msg( m_info, _( "%s can't reach the source tile. Try to sort out loot without a cart." ),
                                         p.disp_name() );
                                mgr.end_sort();
                                return;
                            }

                            // shorten the route to adjacent tile, if necessary
                            if( !adjacent ) {
                                route.pop_back();
                            }

                            // set the destination and restart activity after player arrives there
                            // we don't need to check for safe mode,
                            // activity will be restarted only if
                            // player arrives on destination tile
                            p.set_destination( route, player_activity( act_move_loot ) );
                            mgr.end_sort();
                            return;
                        }
                        move_item( p, *thisitem, thisitem->count(), src_loc, dest_loc, this_veh, this_part );

                        // moved item away from source so decrement
                        mgr.decrement_num_processed( src );

                        break;
                    }
                }
                if( p.moves <= 0 ) {
                    // Restart activity and break from cycle.
                    p.assign_activity( act_move_loot );
                    mgr.end_sort();
                    return;
                }
            }
        }
    }

    // If we got here without restarting the activity, it means we're done
    add_msg( m_info, string_format( _( "%s sorted out every item possible." ), p.disp_name() ) );
    mgr.end_sort();
}
Beispiel #13
0
// Function to read from player; will be called when GTK is idle
gboolean
player_read_func(gpointer* arg)
{
  int i;
  static int count=0;
  pose_t robot_pose;
  gui_data_t* gui_data = (gui_data_t*)arg;
  static struct timeval lastdump = {0, 0};
  static struct timeval lastmapupdate = {0, 0};
  static player_pose2d_t lastwaypt[MAX_NUM_ROBOTS];
  static player_pose2d_t lastgoal[MAX_NUM_ROBOTS];
  struct timeval curr;
  double diff;
  gboolean onmap;
  int peek;

  if(!count)
  {
    memset(lastwaypt,0,sizeof(lastwaypt));
    memset(lastgoal,0,sizeof(lastgoal));
  }

  // update map

  if(mapupdatefreq)
  {
    gettimeofday(&curr,NULL);
    diff = (curr.tv_sec + curr.tv_usec/1e6) - 
            (lastmapupdate.tv_sec + lastmapupdate.tv_usec/1e6);
    if(diff >= 1.0/mapupdatefreq)
    {
      update_map(gui_data);
      lastmapupdate = curr;
    }
  }


  peek = playerc_mclient_peek(gui_data->mclient,10);
  if(peek < 0)
  {
    //fprintf(stderr, "Error on peek\n");
    //gtk_main_quit();
    return(TRUE);
  }
  else if(peek == 0)
    return(TRUE);

  // read new data
  if(playerc_mclient_read(gui_data->mclient,-1) <= 0)
  {
    //fprintf(stderr, "Error on read\n");
    //gtk_main_quit();
    return(TRUE);
  }
  for(i=0;i<gui_data->num_robots;i++)
  {

    int have_robot = 0;

    // Try to get the pose from the planner
    if(gui_data->planners[i] && gui_data->planners[i]->info.fresh)
    {
      robot_pose.px = gui_data->planners[i]->px;
      robot_pose.py = gui_data->planners[i]->py;
      robot_pose.pa = gui_data->planners[i]->pa;
      have_robot = 1;
    }
    // Fall back on getting the pose from the localizer
    else if(gui_data->localizes[i] && 
            gui_data->localizes[i]->info.fresh &&
            gui_data->localizes[i]->hypoth_count)
    {
      robot_pose.px = gui_data->localizes[i]->hypoths[0].mean.px;
      robot_pose.py = gui_data->localizes[i]->hypoths[0].mean.py;
      robot_pose.pa = gui_data->localizes[i]->hypoths[0].mean.pa;
      have_robot = 1;
    }

    // If we got the robot's pose from somewhere
    if(have_robot)
    {
      // is the robot localized within the map?
      onmap = (robot_pose.px >=
               gui_data->mapdev->origin[0]) &&
              (robot_pose.px <
               (gui_data->mapdev->origin[0] + 
                (gui_data->mapdev->width * gui_data->mapdev->resolution))) &&
              (robot_pose.py >=
               gui_data->mapdev->origin[1]) &&
              (robot_pose.py <
               (gui_data->mapdev->origin[1] + 
                (gui_data->mapdev->height * gui_data->mapdev->resolution)));

      // if it's off the map, put it in the middle
      if(!onmap)
        robot_pose.px = robot_pose.py = 0.0;

      // don't draw the new pose if the user is in the middle of moving the
      // robot
      if(!robot_moving_p || (robot_moving_idx != i))
      {
        // also don't draw it if the pose hasn't changed since last time
        if((gui_data->robot_poses[i].px != robot_pose.px) ||
           (gui_data->robot_poses[i].py != robot_pose.py) ||
           (gui_data->robot_poses[i].pa != robot_pose.pa))
        {
          move_item(gui_data->robot_items[i],robot_pose,1);

          // If we have a localizer, retrieve and draw particle cloud
          if(showparticlesp && gui_data->localizes[i])
          {
            playerc_localize_get_particles(gui_data->localizes[i]);
            draw_particles(gui_data,i);
          }
	  
	  // If we have a localizer retrive and draw uncertainty ellipsis
	  if(showuncertaintyp && gui_data->localizes[i])
	  {
	    draw_uncertainty(gui_data,i);
	  }
        }
      }

      // regardless, store this pose for comparison on next iteration
      gui_data->robot_poses[i] = robot_pose;

      // If we have a planner
      if(gui_data->planners[i])
      {
        // If the current goal or waypoint changed, get the whole list 
        // of waypoints again
        if((lastwaypt[i].px != gui_data->planners[i]->wx) ||
           (lastwaypt[i].py != gui_data->planners[i]->wy) ||
           (lastwaypt[i].pa != gui_data->planners[i]->wa) ||
           (lastgoal[i].px != gui_data->planners[i]->gx) ||
           (lastgoal[i].py != gui_data->planners[i]->gy) ||
           (lastgoal[i].pa != gui_data->planners[i]->ga))
        {
          if(get_waypoints)
          {
            if(playerc_planner_get_waypoints(gui_data->planners[i]) < 0)
            {
              fprintf(stderr, 
                      "error while getting waypoints for robot %d\n", i);
            }
            else
            {
              draw_waypoints(gui_data,i);
            }
          }
          else
            draw_goal(gui_data,i);

          // Cache goal and waypoint info
          lastwaypt[i].px = gui_data->planners[i]->wx;
          lastwaypt[i].py = gui_data->planners[i]->wy;
          lastwaypt[i].pa = gui_data->planners[i]->wa;
          lastgoal[i].px = gui_data->planners[i]->gx;
          lastgoal[i].py = gui_data->planners[i]->gy;
          lastgoal[i].pa = gui_data->planners[i]->ga;
        }
      }

      // Reset freshness flag(s)
      if(gui_data->planners[i])
        gui_data->planners[i]->info.fresh = 0;
      if(gui_data->localizes[i])
        gui_data->localizes[i]->info.fresh = 0;
    }

    // raise the robot's canvas item, so that the user can select it
    if(gui_data->localizes[i] || gui_data->planners[i])
    {
      gnome_canvas_item_raise_to_top(gui_data->robot_items[i]);
    }
  }

  // dump screenshot
  if(dumpp)
  {
    gettimeofday(&curr,NULL);
    diff = (curr.tv_sec + curr.tv_usec/1e6) - 
            (lastdump.tv_sec + lastdump.tv_usec/1e6);
    if(diff >= 1.0/dumpfreq)
    {
      dump_screenshot(gui_data);
      lastdump = curr;
    }
  }


  count++;
  return(TRUE);
}
Beispiel #14
0
static void
down_item (GtkWidget *widget, gpointer data)
{
  move_item(widget, data, FALSE);
}
Beispiel #15
0
static void
up_item (GtkWidget *widget, gpointer data)
{
  move_item(widget, data, TRUE);
}
Beispiel #16
0
void swap_invlet_test( player &dummy, inventory_location loc )
{
    // invlet to assign
    constexpr char invlet_1 = '{';
    constexpr char invlet_2 = '}';

    // cannot swap invlets of items on the ground
    REQUIRE( loc != GROUND );

    // remove all items
    dummy.inv.clear();
    dummy.worn.clear();
    dummy.remove_weapon();
    g->m.i_clear( dummy.pos() );

    // two items of the same type that do not stack
    item tshirt1( "tshirt" );
    item tshirt2( "tshirt" );
    tshirt2.mod_damage( -1 );

    // add the items
    add_item( dummy, tshirt1, loc );
    add_item( dummy, tshirt2, loc );

    // assign the items with invlets
    assign_invlet( dummy, item_at( dummy, 0, loc ), invlet_1, CACHED );
    assign_invlet( dummy, item_at( dummy, 1, loc ), invlet_2, CACHED );

    // swap the invlets (invoking twice to make the invlet non-player-assigned)
    dummy.reassign_item( item_at( dummy, 0, loc ), invlet_2 );
    dummy.reassign_item( item_at( dummy, 0, loc ), invlet_2 );

    // drop the items
    move_item( dummy, 0, loc, GROUND );
    move_item( dummy, 0, loc, GROUND );

    // get them again
    move_item( dummy, 0, GROUND, loc );
    move_item( dummy, 0, GROUND, loc );

    std::stringstream ss;
    ss << "1. add two items of the same type to " << location_desc( loc ) <<
       ", and ensure them do not stack" << std::endl;
    ss << "2. assign different invlets to the two items" << std::endl;
    ss << "3. swap the invlets by assign one of the items with the invlet of the other item" <<
       std::endl;
    ss << "4. move the items to " << location_desc( GROUND ) << std::endl;
    ss << "5. move the items to " << location_desc( loc ) << " again" << std::endl;
    ss << "expect the items to keep their swapped invlets" << std::endl;
    if( item_at( dummy, 0, loc ).invlet == invlet_2 && item_at( dummy, 1, loc ).invlet == invlet_1 ) {
        ss << "the items actually keep their swapped invlets" << std::endl;
    } else {
        ss << "the items actually does not keep their swapped invlets" << std::endl;
    }
    INFO( ss.str() );
    REQUIRE( item_at( dummy, 0, loc ).typeId() == tshirt1.typeId() );
    REQUIRE( item_at( dummy, 1, loc ).typeId() == tshirt2.typeId() );
    // invlets should not disappear and should still be swapped
    CHECK( item_at( dummy, 0, loc ).invlet == invlet_2 );
    CHECK( item_at( dummy, 1, loc ).invlet == invlet_1 );
    CHECK( check_invlet( dummy, item_at( dummy, 0, loc ), invlet_2 ) == CACHED );
    CHECK( check_invlet( dummy, item_at( dummy, 1, loc ), invlet_1 ) == CACHED );

    // clear invlets
    assign_invlet( dummy, item_at( dummy, 0, loc ), invlet_2, NONE );
    assign_invlet( dummy, item_at( dummy, 1, loc ), invlet_1, NONE );
}
Beispiel #17
0
BObjectImp* UOExecutorModule::internal_MoveItem(Item* item, xcoord x, ycoord y, zcoord z, long flags, Realm* newrealm)
{
	ItemRef itemref(item); //dave 1/28/3 prevent item from being destroyed before function ends
	if (!(flags & MOVEITEM_IGNOREMOVABLE) && !item->movable())
	{
	    Character* chr = controller_.get();
	    if ( chr == NULL || !chr->can_move( item ) )
			 return new BError( "That is immobile" );
	}
	if ( item->inuse() && !is_reserved_to_me(item) )
	{
		    return new BError("That item is being used.");
	}

	Realm* oldrealm = item->realm;
	item->realm = newrealm;
	if ( !item->realm->valid( x,y,z ) )
	{	// Should probably have checked this already.
		item->realm = oldrealm;
		string message = "Location (" + tostring(x) + "," + tostring(y) + "," + tostring(z) + ") is out of bounds";
		return new BError( message );
	}

	UMulti* multi = NULL;
	if ( flags & MOVEITEM_FORCELOCATION )
	{
	    short newz;
	    Item* walkon;
	    item->realm->walkheight( x,y,z, &newz, &multi, &walkon, true, MOVEMODE_LAND );
	    // note that newz is ignored...
	}
	else
	{
	    short newz;
	    Item* walkon;
	    if (!item->realm->walkheight( x,y,z, &newz, &multi, &walkon, true, MOVEMODE_LAND ))
	    {
			item->realm = oldrealm;
			return new BError( "Invalid location selected" );
	    }
	    z = newz;
	}

	if (item->container != NULL)
	{
		//DAVE added this 12/04, call can/onRemove scripts for the old container
		UObject* oldroot = item->toplevel_owner();
		UContainer* oldcont = item->container;
		Character* chr_owner = oldcont->GetCharacterOwner();
		if(chr_owner == NULL)
			if(controller_.get() != NULL)
				chr_owner = controller_.get();

		//dave changed 1/26/3 order of scripts to call. added unequip/test script call
		if( !oldcont->check_can_remove_script(chr_owner, item, UContainer::MT_CORE_MOVED) )
		{
			item->realm = oldrealm;
			return new BError("Could not remove item from its container.");
		}
		else if( item->orphan() ) //dave added 1/28/3, item might be destroyed in RTC script
		{
			return new BError("Item was destroyed in CanRemove script");
		}

		if ( !item->check_unequiptest_scripts() || !item->check_unequip_script() )
		{
			item->realm = oldrealm;
			return new BError("Item cannot be unequipped");
		}
		if( item->orphan() ) //dave added 1/28/3, item might be destroyed in RTC script
			return new BError( "Item was destroyed in Equip script" );

		oldcont->on_remove( chr_owner, item, UContainer::MT_CORE_MOVED );
		if( item->orphan() ) //dave added 1/28/3, item might be destroyed in RTC script
		{
			return new BError( "Item was destroyed in OnRemove script" );
		}

		item->set_dirty();

		item->extricate();

		// wherever it was, it wasn't in the world/on the ground
	    item->x = oldroot->x;
	    item->y = oldroot->y;
	    // move_item calls MoveItemWorldLocation, so this gets it
	    // in the right place to start with.
		item->realm = oldrealm;
		add_item_to_world( item );
		item->realm = newrealm;
	}

	move_item( item,
		    x,
			y,
		    static_cast<signed char>(z), oldrealm );

	if ( multi != NULL )
	{
		multi->register_object(item);
	}
	if( item->realm != oldrealm )
	{
		++item->realm->toplevel_item_count;
		--oldrealm->toplevel_item_count;
	}
	return new BLong(1);
}