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); }
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 ); }
/** 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); } } }