예제 #1
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);
}
예제 #2
0
void equip_item( Client *client, PKTIN_13 *msg )
{
	u32 serial = cfBEu32( msg->serial );
	u8 layer = msg->layer;
	u32 equip_on_serial = cfBEu32( msg->equipped_on );

	if ((layer > HIGHEST_LAYER) || (layer == 0) || client->chr->dead())
	{
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP );
		return;
	}
	
	Item *item = client->chr->gotten_item;

	if (item == NULL)
	{
		Log( "Character %08lX tried to equip item %08lx, which did not exist in gotten_items.\n",
			 client->chr->serial, serial );
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP ); // 5
		return;
	}

    if (item->serial != serial)
	{
		Log( "Character %08lX tried to equip item %08lx, but had gotten item %08lX\n",
			 client->chr->serial, 
			 serial,
			 item->serial);
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP ); // 5
		item->gotten_by = NULL;
		return;
	}

	ItemRef itemref(item);

	item->layer = item->tile_layer;
	client->chr->gotten_item->inuse(false);
	item->is_gotten(false);
	item->gotten_by = NULL;
	client->chr->gotten_item = NULL;

    Character* equip_on = NULL;
    if (equip_on_serial == client->chr->serial)
    {
        equip_on = client->chr;
    }
    else
    {
        equip_on = find_character( equip_on_serial );
        if (equip_on == NULL ||
            !client->chr->can_clothe( equip_on ))
        {
		    send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP );

		    undo_get_item( client->chr, item );
            return;		
        }
    }

	if (equip_on->layer_is_equipped( item->tile_layer ))
	{
		// it appears the client already checks for this, so this code hasn't been exercised.
		// we'll assume client mouse holds on to object
        // 3D Client doesn't check for this!
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ALREADY_WORN );

        undo_get_item( client->chr, item ); //added 11/01/03 for 3d client
		return;
	}

    if (!equip_on->strong_enough_to_equip( item ))
    {
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP );
		// the client now puts the item back where it was before.

		// return the item to wherever it was. (?)
		undo_get_item( client->chr, item );
        if (client->chr == equip_on)
        {
            send_sysmessage( client, "You are not strong enough to use that." );
        }
        else
        {
            send_sysmessage( client, "Insufficient strength to equip that." );
        }
        return;		
    }

    if (!equip_on->equippable( item ) ||
        !item->check_equiptest_scripts( equip_on ) ||
        !item->check_equip_script( equip_on, false ))
    {
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP );
		if(item->orphan())
		{
			return;
		}
		undo_get_item( client->chr, item );
		return;		
    }

	if(item->orphan())
	{
		return;
	}
    
	equip_on->equip( item );
	send_wornitem_to_inrange( equip_on, item );
}
예제 #3
0
/** Translate python list of tuples to Config
 *
 *  [(K,V)]   -> Config
 *    float   -> double
 *    str     -> string
 *    [[()]]    -> vector<Config>  (recurse)
 *    ndarray -> vector<double>
 *    TODO: [0.0]   -> vector<double>
 */
void List2Config(Config& ret, PyObject *list, unsigned depth)
{
    if(depth>3)
        throw std::runtime_error("too deep for Dict2Config");

    PyRef<> iter(PyObject_GetIter(list));
    while(true) {
        PyObject *item = PyIter_Next(iter.py());
        if(!item) break;
        PyRef<> itemref(item);
        const char *kname;
        PyObject *value;
        if(!PyArg_ParseTuple(item, "sO", &kname, &value))
            throw std::runtime_error("list item is not a tuple?");

        if(PyArray_Check(value)) { // array as vector<double>
            PyRef<> arr(PyArray_ContiguousFromAny(value, NPY_DOUBLE, 0, 2));
            double *buf = (double*)PyArray_DATA(arr.py());
            std::vector<double> temp(PyArray_SIZE(arr.py()));
            std::copy(buf, buf+temp.size(), temp.begin());

            ret.swap<std::vector<double> >(kname, temp);

        } else if(PyNumber_Check(value)) { // scalar as double
            PyRef<> dval(PyNumber_Float(value));
            double val = PyFloat_AsDouble(dval.py());
            ret.set<double>(kname, val);

        } else if(PyUnicode_Check(value) || (PY_MAJOR_VERSION < 3 && PyBytes_Check(value))) { // string
            PyRef<> valref(value, borrow());
            PyCString sval(valref);
            const char *val = sval.c_str();

            ret.set<std::string>(kname, val);

        } else if(PySequence_Check(value)) { // list of dict
            Py_ssize_t N = PySequence_Size(value);

            Config::vector_t output;
            output.reserve(N);

            for(Py_ssize_t i=0; i<N; i++) {
                PyRef<> elem(PySequence_GetItem(value, i));

                if(PyDict_Check(elem.py())) {
                    elem.reset(PyMapping_Items(elem.py()));
                }
                if(!PyList_Check(elem.py())) {
                    PyTypeObject *valuetype = (PyTypeObject*)PyObject_Type(elem.py());
                    throw std::invalid_argument(SB()<<"lists must contain only dict or list of tuples, not "<<valuetype->tp_name);
                }

                output.push_back(ret.new_scope());

                List2Config(output.back(), elem.py(), depth+1); // inheirt parent scope
            }

            ret.set<Config::vector_t>(kname, output);

        } else {
            PyTypeObject *valuetype = (PyTypeObject*)PyObject_Type(value);
            throw std::invalid_argument(SB()<<"Must be a dict, not "<<valuetype->tp_name);
        }
    }
}