// scripted_create duplicates some of this work //Dave changed 3/8/3 to use objecthash UMulti* UMulti::create( const Items::ItemDesc& descriptor, u32 serial ) { UMulti* multi = NULL; if ( descriptor.type == Items::ItemDesc::BOATDESC ) { multi = new UBoat( descriptor ); } else if ( descriptor.type == Items::ItemDesc::HOUSEDESC ) { multi = new UHouse( descriptor ); } else { ERROR_PRINT << "Tried to create multi 0x" << fmt::hexu( descriptor.objtype ) << " but no definition exists in itemdesc.cfg\n"; return NULL; } if ( serial ) multi->serial = Core::UseItemSerialNumber( serial ); else multi->serial = Core::GetNewItemSerialNumber( ); multi->serial_ext = ctBEu32( multi->serial ); ////HASH Core::objStorageManager.objecthash.Insert( multi ); //// return multi; }
// scripted_create duplicates some of this work //Dave changed 3/8/3 to use objecthash UMulti* UMulti::create( const ItemDesc& descriptor, u32 serial ) { UMulti* multi = NULL; if ( descriptor.type == ItemDesc::BOATDESC ) { multi = new UBoat( descriptor ); } else if ( descriptor.type == ItemDesc::HOUSEDESC ) { multi = new UHouse( descriptor ); } else { cerr << "Tried to create multi " << hexint(descriptor.objtype) << " but no definition exists in itemdesc.cfg" << endl; return NULL; } if (serial) multi->serial = UseItemSerialNumber( serial ); else multi->serial = GetNewItemSerialNumber(); multi->serial_ext = ctBEu32( multi->serial ); ////HASH objecthash.Insert(multi); //// return multi; }
Bscript::BObjectImp* UOExecutorModule::mf_PromptInput() { Mobile::Character* chr; Items::Item* item; const Bscript::String* prompt; if ( !getCharacterParam( exec, 0, chr ) || !getItemParam( exec, 1, item ) || !exec.getStringParam( 2, prompt ) ) { return new Bscript::BError( "Invalid parameter" ); } if ( chr->client == nullptr ) { return new Bscript::BError( "No client attached" ); } if ( chr->has_active_prompt() != false ) { return new Bscript::BError( "Another script has an active prompt" ); } if ( !uoexec.suspend() ) { DEBUGLOG << "Script Error in '" << scriptname() << "' PC=" << exec.PC << ": \n" << "\tCall to function UO::RequestInput():\n" << "\tThe execution of this script can't be blocked!\n"; return new Bscript::BError( "Script can't be blocked" ); } Core::send_sysmessage( chr->client, prompt->data() ); chr->client->gd->prompt_uoemod = this; prompt_chr = chr; Core::send_prompt( chr->client, ctBEu32( item->serial ) ); return new Bscript::BLong( 0 ); }
Item* Item::create( const ItemDesc& id, u32 serial ) { u32 objtype = id.objtype; unsigned short graphic = id.graphic; Item* item; // FIXME looks like a place for a bunch of function pointers if I ever saw one. if ( id.type == ItemDesc::DOORDESC ) { item = new Core::UDoor( static_cast<const DoorDesc&>( id ) ); } else if ( id.type == ItemDesc::BOATDESC ) { // still created with create_multi return NULL; } else if ( id.type == ItemDesc::HOUSEDESC ) { // still created with create_multi return NULL; } else if ( ( objtype >= Core::gamestate.spell_scroll_objtype_limits[0][0] && objtype <= Core::gamestate.spell_scroll_objtype_limits[0][1] ) || ( objtype >= Core::gamestate.spell_scroll_objtype_limits[1][0] && objtype <= Core::gamestate.spell_scroll_objtype_limits[1][1] ) || ( objtype >= Core::gamestate.spell_scroll_objtype_limits[2][0] && objtype <= Core::gamestate.spell_scroll_objtype_limits[2][1] ) ) { item = new Core::USpellScroll( id ); } else if ( objtype == UOBJ_CORPSE ) // ITEMDESCTODO make new ItemDesc type { item = new Core::UCorpse( static_cast<const ContainerDesc&>( id ) ); } else if ( id.type == ItemDesc::SPELLBOOKDESC ) // ITEMDESCTODO make new ItemDesc type { item = new Core::Spellbook( static_cast<const SpellbookDesc&>( id ) ); } else if ( id.type == ItemDesc::CONTAINERDESC ) { item = new Core::UContainer( static_cast<const ContainerDesc&>( id ) ); } else if ( id.type == ItemDesc::WEAPONDESC ) { // we call find_itemdesc here because the item descriptor passed in may not // be the "real" one - it may be a temporary descriptor. const WeaponDesc* permanent_descriptor = static_cast<const WeaponDesc*>( &find_itemdesc( objtype ) ); item = new UWeapon( static_cast<const WeaponDesc&>( id ), permanent_descriptor ); } else if ( id.type == ItemDesc::ARMORDESC ) { const ArmorDesc* permanent_descriptor = static_cast<const ArmorDesc*>( &find_itemdesc( objtype ) ); item = new UArmor( static_cast<const ArmorDesc&>( id ), permanent_descriptor ); } else if ( id.type == ItemDesc::MAPDESC ) // (graphic >= UOBJ_MAP1 && graphic <= UOBJ_ROLLED_MAP2) { item = new Core::Map( static_cast<const MapDesc&>( id ) ); } else if ( objtype == Core::settingsManager.extobj.port_plank || objtype == Core::settingsManager.extobj.starboard_plank )// ITEMDESCTODO make new ItemDesc type { item = new Multi::UPlank( id ); } else if ( objtype_is_lockable( objtype ) ) { item = new Core::ULockable( id, CLASS_ITEM ); } else { item = new Item( id, CLASS_ITEM ); } // 12-17-2008 MuadDib added for reading the tilelayer at all times while retaining item.layer useage. item->tile_layer = Core::tilelayer( graphic ); // Have to be set after the item is created, because item graphic changes // Because items can have facing 0 as the lightsource we use as default 127 to check if ( item->facing == 127 ) item->facing = item->tile_layer; if ( serial ) { item->serial = Core::UseItemSerialNumber( serial ); item->clear_dirty(); } else if ( !find_itemdesc( objtype ).save_on_exit ) // get the real itemdesc { item->set_dirty(); item->serial = Core::GetNewItemSerialNumber( ); } else // creating something new { item->set_dirty(); remove_resources( objtype, 1 ); item->serial = Core::GetNewItemSerialNumber( ); } ////HASH Core::objStorageManager.objecthash.Insert( item ); //// item->serial_ext = ctBEu32( item->serial ); item->restart_decay_timer(); item->graphic = graphic; // If item already has a serial (eg. an existing item loaded from a save), // then do not assign CProps from descriptor if( ! serial ) item->copyprops( id.props ); #ifdef PERGON std::string value_self; if (!item->getprop( "ct", value_self )) // Pergon: Check if Prop still exist - prevents Overwrite on Server-Restart item->setprop("ct", "i" + Clib::decint( Core::read_gameclock() )); // Pergon: Init Property CreateTime for a new Item #endif if ( !id.control_script.empty() ) { passert( item->process() == nullptr ); Module::UOExecutorModule* uoemod = start_script( id.control_script, item->make_ref() ); if ( uoemod ) { uoemod->attached_item_ = item; item->process(uoemod); } else { POLLOG << "Unable to start control script " << id.control_script.name() << " for " << id.objtype_description() << "\n"; } } for ( unsigned element = 0; element <= Core::ELEMENTAL_TYPE_MAX; ++element ) { switch ( element ) { case Core::ELEMENTAL_FIRE: item->fire_resist(item->fire_resist().addToValue(id.element_resist.fire)); item->fire_damage(item->fire_damage().addToValue(id.element_damage.fire)); break; case Core::ELEMENTAL_COLD: item->cold_resist(item->cold_resist().addToValue(id.element_resist.cold)); item->cold_damage(item->cold_damage().addToValue(id.element_damage.cold)); break; case Core::ELEMENTAL_ENERGY: item->energy_resist(item->energy_resist().addToValue(id.element_resist.energy)); item->energy_damage(item->energy_damage().addToValue(id.element_damage.energy)); break; case Core::ELEMENTAL_POISON: item->poison_resist(item->poison_resist().addToValue(id.element_resist.poison)); item->poison_damage(item->poison_damage().addToValue(id.element_damage.poison)); break; case Core::ELEMENTAL_PHYSICAL: item->physical_resist(item->physical_resist().addToValue(id.element_resist.physical)); item->physical_damage(item->physical_damage().addToValue(id.element_damage.physical)); break; } } // if ItemDesc is a dynamic one desc could differ and would be lost const ItemDesc& origid = find_itemdesc( item->objtype_ ); if ( id.desc != origid.desc ) item->setname( id.desc ); return item; }
// This is for legacy up to 5.0(?). Cuz ML added new bytes in the middle of the packet. void send_full_statmsg_std( Client *client, Character *chr ) { PKTOUT_11_V1 msg; msg.msgtype = PKTOUT_11_V1_ID; if( (client->UOExpansionFlag & AOS) ) { msg.msglen = ctBEu16(sizeof msg); msg.moreinfo = 04; // Set to AOS level statbar for full info } else { unsigned short msglen = offsetof( PKTOUT_11_V1, statcap ); msg.msglen = ctBEu16(msglen); msg.moreinfo = 01; // Set to oldschool statbar info. } msg.serial = chr->serial_ext; strzcpy( msg.name, chr->name().c_str(), sizeof msg.name ); if (uoclient_general.hits.any) { long v = chr->vital(uoclient_general.hits.id).current_ones(); if (v > 0xFFFF) v = 0xFFFF; msg.hits = ctBEu16( static_cast<u16>(v) ); v = chr->vital(uoclient_general.hits.id).maximum_ones(); if (v > 0xFFFF) v = 0xFFFF; msg.max_hits = ctBEu16( static_cast<u16>(v) ); } else { msg.hits = 0; msg.max_hits = 0; } msg.renameable = 0; // (client->chr->can_rename( chr ) ? 0xFF : 0); //if (chr->race == RACE_ELF) // msg.gender = static_cast<u8>(chr->gender | FLAG_RACE); //else msg.gender = static_cast<u8>(chr->gender); if (uoclient_general.strength.any) { long v = chr->attribute(uoclient_general.strength.id).effective(); if (v > 0xFFFF) v = 0xFFFF; msg.str = ctBEu16( static_cast<u16>(v) ); } else { msg.str = 0; } if (uoclient_general.dexterity.any) { long v = chr->attribute(uoclient_general.dexterity.id).effective(); if (v > 0xFFFF) v = 0xFFFF; msg.dex = ctBEu16( static_cast<u16>(v) ); } else { msg.dex = 0; } if (uoclient_general.intelligence.any) { long v = chr->attribute(uoclient_general.intelligence.id).effective(); if (v > 0xFFFF) v = 0xFFFF; msg.intel = ctBEu16( static_cast<u16>(v) ); } else { msg.intel = 0; } if (uoclient_general.stamina.any) { long v = chr->vital(uoclient_general.stamina.id).current_ones(); if (v > 0xFFFF) v = 0xFFFF; msg.stamina = ctBEu16( static_cast<u16>(v) ); v = chr->vital( uoclient_general.stamina.id ).maximum_ones(); if (v > 0xFFFF) v = 0xFFFF; msg.max_stamina = ctBEu16( static_cast<u16>(v) ); } else { msg.stamina = 0; msg.max_stamina = 0; } if (uoclient_general.mana.any) { long v = chr->vital(uoclient_general.mana.id).current_ones(); if (v > 0xFFFF) v = 0xFFFF; msg.mana = ctBEu16( static_cast<u16>(v) ); v = chr->vital(uoclient_general.mana.id).maximum_ones(); if (v > 0xFFFF) v = 0xFFFF; msg.max_mana = ctBEu16( static_cast<u16>(v) ); } else { msg.mana = 0; msg.max_mana = 0; } msg.gold = ctBEu32( chr->gold_carried() ); // Adjusted to work with Physical Resist if AOS client, and AOS Resistances enabled. if( (client->UOExpansionFlag & AOS) && client->aosresist ) msg.AR = (chr->element_resist.physical < 0)?ctBEu16(0x10000+chr->element_resist.physical):ctBEu16(chr->element_resist.physical); else msg.AR = ctBEu16( chr->ar() ); msg.weight = ctBEu16( static_cast<u16>(chr->weight()) ); if ( msg.moreinfo >= 4 ) { msg.statcap = ctBEu16( chr->expanded_statbar.statcap ); msg.followers = chr->expanded_statbar.followers; msg.followers_max = chr->expanded_statbar.followers_max; msg.fireresist = (chr->element_resist.fire < 0)?ctBEu16(0x10000+chr->element_resist.fire):ctBEu16(chr->element_resist.fire); msg.coldresist = (chr->element_resist.cold < 0)?ctBEu16(0x10000+chr->element_resist.cold):ctBEu16(chr->element_resist.cold); msg.poisonresist = (chr->element_resist.poison < 0)?ctBEu16(0x10000+chr->element_resist.poison):ctBEu16(chr->element_resist.poison); msg.energyresist = (chr->element_resist.energy < 0)?ctBEu16(0x10000+chr->element_resist.energy):ctBEu16(chr->element_resist.energy); msg.luck = ctBEu16( chr->expanded_statbar.luck ); msg.damage_min = ctBEu16( chr->min_weapon_damage() ); msg.damage_max = ctBEu16( chr->max_weapon_damage() ); msg.titching = ctBEu32( chr->expanded_statbar.tithing ); } transmit(client, &msg, cfBEu16(msg.msglen) ); }
void handle_msg_BF( Client* client, PKTBI_BF* msg ) { UObject* obj = NULL; UMulti* multi = NULL; UHouse* house = NULL; switch(cfBEu16(msg->subcmd)) { case PKTBI_BF::TYPE_CLIENT_LANGUAGE: client->chr->uclang = strlower(msg->client_lang); break; case PKTBI_BF::TYPE_REQ_FULL_CUSTOM_HOUSE: if( (client->UOExpansionFlag & AOS) == 0 ) return; multi = system_find_multi(cfBEu32(msg->reqfullcustomhouse.house_serial)); if(multi != NULL) { house = multi->as_house(); if(house != NULL) { if(client->UOExpansionFlag & AOS) { send_object_cache(client, (UObject*)(house)); } //consider sending working design to certain players, to assist building, or GM help CustomHousesSendFull( house, client, HOUSE_DESIGN_CURRENT ); } } break; case PKTBI_BF::TYPE_OBJECT_CACHE: if( (client->UOExpansionFlag & AOS) == 0) return; obj = system_find_object(cfBEu32(msg->objectcache.serial)); if(obj != NULL) { SendAOSTooltip(client,obj); } break; case PKTBI_BF::TYPE_SESPAM: return; break; case PKTBI_BF::TYPE_SPELL_SELECT: do_cast(client, cfBEu16(msg->spellselect.selected_spell) ); break; case PKTBI_BF::TYPE_CHARACTER_RACE_CHANGER: character_race_changer_handler( client, msg ); break; case PKTBI_BF::TYPE_PARTY_SYSTEM: party_cmd_handler( client, msg ); break; case PKTBI_BF::TYPE_EXTENDED_STATS_IN: ext_stats_in(client, msg); break; case PKTBI_BF::TYPE_CLOSED_STATUS_GUMP: return; break; case PKTBI_BF::TYPE_SCREEN_SIZE: return; break; case PKTBI_BF::TYPE_TOGGLE_FLYING: if (client->chr->race==RACE_GARGOYLE) { // FIXME: add checks if its possible to stand with new movemode client->chr->movemode = (MOVEMODE)(client->chr->movemode ^ MOVEMODE_FLY); send_move_mobile_to_nearby_cansee( client->chr ); send_goxyz( client, client->chr ); } break; case PKTBI_BF::TYPE_CLIENTTYPE: client->UOExpansionFlagClient = ctBEu32( msg->clienttype.clientflag ); break; default: handle_unknown_packet( client ); } }
Item* Item::create( const ItemDesc& id, u32 serial) { unsigned short objtype = id.objtype; unsigned short graphic = id.graphic; Item* item; // FIXME looks like a place for a bunch of function pointers if I ever saw one. if (id.type == ItemDesc::DOORDESC) { item = new UDoor( static_cast<const DoorDesc&>(id) ); } else if (id.type == ItemDesc::BOATDESC) { // still created with create_multi return NULL; } else if (id.type == ItemDesc::HOUSEDESC) { // still created with create_multi return NULL; } else if ( (objtype >= spell_scroll_objtype_limits[0][0] && objtype <= spell_scroll_objtype_limits[0][1]) || (objtype >= spell_scroll_objtype_limits[1][0] && objtype <= spell_scroll_objtype_limits[1][1]) || (objtype >= spell_scroll_objtype_limits[2][0] && objtype <= spell_scroll_objtype_limits[2][1]) ) { item = new USpellScroll( id ); } else if (objtype == UOBJ_CORPSE) // ITEMDESCTODO make new ItemDesc type { item = new UCorpse( static_cast<const ContainerDesc&>(id) ); } else if (id.type == ItemDesc::SPELLBOOKDESC) // ITEMDESCTODO make new ItemDesc type { item = new Spellbook( static_cast<const SpellbookDesc&>(id) ); } else if (id.type == ItemDesc::CONTAINERDESC) { item = new UContainer( static_cast<const ContainerDesc&>(id) ); } else if (id.type == ItemDesc::WEAPONDESC) { // we call find_itemdesc here because the item descriptor passed in may not // be the "real" one - it may be a temporary descriptor. const WeaponDesc* permanent_descriptor = static_cast<const WeaponDesc*>(&find_itemdesc(objtype)); item = new UWeapon( static_cast<const WeaponDesc&>(id), permanent_descriptor ); } else if (id.type == ItemDesc::ARMORDESC) { const ArmorDesc* permanent_descriptor = static_cast<const ArmorDesc*>(&find_itemdesc(objtype)); item = new UArmor( static_cast<const ArmorDesc&>(id), permanent_descriptor ); } else if (id.type == ItemDesc::MAPDESC) // (graphic >= UOBJ_MAP1 && graphic <= UOBJ_ROLLED_MAP2) { item = new Map( static_cast<const MapDesc&>(id) ); } else if (objtype == EXTOBJ_PORT_PLANK || objtype == EXTOBJ_STARBOARD_PLANK)// ITEMDESCTODO make new ItemDesc type { item = new UPlank( id ); } else if (objtype_is_lockable(objtype)) { item = new ULockable( id, CLASS_ITEM ); } else { item = new Item( id, CLASS_ITEM ); } // 12-17-2008 MuadDib added for reading the tilelayer at all times while retaining item.layer useage. item->tile_layer = tilelayer( graphic ); // Have to be set after the item is created, because item graphic changes // Because items can have facing 0 as the lightsource we use as default 127 to check if ( item->facing == 127 ) item->facing = item->tile_layer; if (serial) { item->serial = UseItemSerialNumber(serial); item->clear_dirty(); } else if (dont_save_itemtype[objtype]) { item->set_dirty(); item->serial = GetNewItemSerialNumber(); } else // creating something new { item->set_dirty(); remove_resources( objtype, 1 ); item->serial = GetNewItemSerialNumber(); } ////HASH objecthash.Insert(item); //// item->serial_ext = ctBEu32( item->serial ); item->restart_decay_timer(); item->graphic = graphic; item->graphic_ext = ctBEu16( item->graphic ); item->copyprops( id.props ); #ifdef PERGON string value_self; if (!item->getprop( "ct", value_self )) // Pergon: Check if Prop still exist - prevents Overwrite on Server-Restart item->setprop("ct", "i" + decint( read_gameclock() )); // Pergon: Init Property CreateTime for a new Item #endif if (!id.control_script.empty()) { UOExecutorModule* uoemod = start_script( id.control_script, item->make_ref() ); if (!uoemod) { Log( "Unable to start control script %s for %s\n", id.control_script.name().c_str(), id.objtype_description().c_str() ); } } for( unsigned element = 0; element <= ELEMENTAL_TYPE_MAX; ++element ) { switch(element) { case ELEMENTAL_FIRE: item->element_resist.fire = id.element_resist.fire; item->element_damage.fire = id.element_damage.fire;break; case ELEMENTAL_COLD: item->element_resist.cold = id.element_resist.cold; item->element_damage.cold = id.element_damage.cold;break; case ELEMENTAL_ENERGY: item->element_resist.energy = id.element_resist.energy; item->element_damage.energy = id.element_damage.energy; break; case ELEMENTAL_POISON: item->element_resist.poison = id.element_resist.poison; item->element_damage.poison = id.element_damage.poison; break; case ELEMENTAL_PHYSICAL: item->element_resist.physical = id.element_resist.physical; item->element_damage.physical = id.element_damage.physical; break; } } // if ItemDesc is a dynamic one desc could differ and would be lost const ItemDesc& origid = find_itemdesc( item->objtype_ ); if (id.desc != origid.desc) item->setname( id.desc); return item; }