bool knows_spell( Mobile::Character* chr, u16 spellid ) { //copied code from Character::spellbook to support multiple spellbooks in the pack Items::Item* item = chr->wornitem( LAYER_HAND1 ); if ( item != NULL && item->script_isa( POLCLASS_SPELLBOOK ) ) { Spellbook* book = static_cast<Spellbook*>( item ); if ( book->has_spellid( spellid ) ) return true; } UContainer* cont = chr->backpack(); if ( cont != NULL ) { for ( UContainer::const_iterator itr = cont->begin(), end = cont->end(); itr != end; ++itr ) { const Items::Item* _item = GET_ITEM_PTR( itr ); if ( _item != NULL && _item->script_isa( POLCLASS_SPELLBOOK ) ) { const Spellbook* book = static_cast<const Spellbook*>( _item ); if ( book->has_spellid( spellid ) ) return true; } } } return false; }
Items::Item* find_walkon_item( ItemsVector& ivec, short z ) { for ( ItemsVector::const_iterator itr = ivec.begin( ), end = ivec.end( ); itr != end; ++itr ) { Items::Item* item = ( *itr ); if ( z == item->z || z == item->z + 1 ) { if ( !item->itemdesc().walk_on_script.empty() ) { return item; } } } return NULL; }
void decay_worldzone( unsigned wx, unsigned wy, Realms::Realm* realm ) { Zone& zone = realm->zone[wx][wy]; gameclock_t now = read_gameclock(); bool statistics = Plib::systemstate.config.thread_decay_statistics; for ( ZoneItems::size_type idx = 0; idx < zone.items.size(); ++idx ) { Items::Item* item = zone.items[idx]; if (statistics) { if (item->can_decay()) { const Items::ItemDesc& descriptor = item->itemdesc(); if (!descriptor.decays_on_multis) { Multi::UMulti* multi = realm->find_supporting_multi( item->x, item->y, item->z ); if (multi == NULL) stateManager.decay_statistics.temp_count_active++; } else stateManager.decay_statistics.temp_count_active++; } } if ( item->should_decay( now ) ) { // check the CanDecay syshook first if it returns 1 go over to other checks if ( gamestate.system_hooks.can_decay ) { if ( !gamestate.system_hooks.can_decay->call( new Module::EItemRefObjImp( item ) ) ) continue; } const Items::ItemDesc& descriptor = item->itemdesc(); Multi::UMulti* multi = realm->find_supporting_multi( item->x, item->y, item->z ); // some things don't decay on multis: if ( multi != NULL && !descriptor.decays_on_multis ) continue; if (statistics) stateManager.decay_statistics.temp_count_decayed++; if ( !descriptor.destroy_script.empty() && !item->inuse() ) { bool decayok = call_script( descriptor.destroy_script, item->make_ref() ); if ( !decayok ) continue; } item->spill_contents( multi ); destroy_item( item ); --idx; } } }
bool hands_are_free( Mobile::Character* chr ) { Items::Item* item; item = chr->wornitem( LAYER_HAND1 ); if ( item != NULL ) { const Items::ItemDesc& id = item->itemdesc( ); if ( id.blocks_casting_if_in_hand ) return false; } item = chr->wornitem( LAYER_HAND2 ); if ( item != NULL ) { const Items::ItemDesc& id = item->itemdesc( ); if ( id.blocks_casting_if_in_hand ) return false; } return true; }
void handle_open_spellbook( Network::Client *client, PKTIN_12* /*msg*/ ) { if ( system_hooks.open_spellbook_hook != NULL ) { if ( system_hooks.open_spellbook_hook->call( make_mobileref( client->chr ) ) ) return; } if ( client->chr->dead() ) { send_sysmessage( client, "I am dead and cannot do that." ); return; } Items::Item* spellbook = client->chr->wornitem( LAYER_HAND1 ); if ( spellbook == NULL ) { UContainer* backpack = client->chr->backpack(); if ( backpack != NULL ) { spellbook = backpack->find_toplevel_polclass( POLCLASS_SPELLBOOK ); // // Client crashes if the pack isn't open and you don't tell him // about the spellbook // if ( spellbook != NULL ) send_put_in_container( client, spellbook ); } } if ( spellbook != NULL ) { spellbook->double_click( client ); } }
void doubleclick( Network::Client* client, PKTIN_06* msg ) { u32 serial = cfBEu32( msg->serial ); u32 paperdoll_macro_flag = serial & 0x80000000Lu; serial &= ~0x80000000Lu; // keypress versus doubleclick switch? // the find_character would find this, but most of the time it's your own paperdoll. // this is special-cased for two reasons: // 1) it's commonly done // 2) ghosts can doubleclick ONLY their paperdoll. if ( serial == client->chr->serial ) { if ( !paperdoll_macro_flag ) { ScriptDef sd; sd.quickconfig( "scripts/misc/dblclickself.ecl" ); if ( sd.exists() ) { ref_ptr<Bscript::EScriptProgram> prog; prog = find_script2( sd, false, Plib::systemstate.config.cache_interactive_scripts ); if ( prog.get() != nullptr && client->chr->start_script( prog.get(), false ) ) { return; } } } send_paperdoll( client, client->chr ); return; } if ( client->chr->dblclick_wait() > read_gameclock() ) { private_say_above( client->chr, client->chr, "You must wait to use something again." ); return; } else client->chr->dblclick_wait( read_gameclock() + settingsManager.ssopt.dblclick_wait ); if ( IsCharacter( serial ) ) { if ( client->chr->dead() ) return; Mobile::Character* chr = find_character( serial ); if ( !chr ) return; if ( chr->isa( UOBJ_CLASS::CLASS_NPC ) ) { Mobile::NPC* npc = static_cast<Mobile::NPC*>( chr ); if ( npc->can_accept_event( EVID_DOUBLECLICKED ) ) { npc->send_event( new Module::SourcedEvent( EVID_DOUBLECLICKED, client->chr ) ); return; } } bool script_ran = false; ScriptDef sd; sd.quickconfig( "scripts/misc/dblclickother.ecl" ); if ( sd.exists() ) { ref_ptr<Bscript::EScriptProgram> prog; prog = find_script2( sd, false, Plib::systemstate.config.cache_interactive_scripts ); if ( prog.get() != nullptr ) script_ran = client->chr->start_script( prog.get(), false, new Module::ECharacterRefObjImp( chr ) ); } if ( !script_ran && inrange( client->chr, chr ) ) { // MuadDib Changed from a large if || || || to switch case. 1/4/2007 switch ( chr->graphic ) { case UOBJ_HUMAN_MALE: case UOBJ_HUMAN_FEMALE: case UOBJ_HUMAN_MALE_GHOST: case UOBJ_HUMAN_FEMALE_GHOST: case UOBJ_ELF_MALE: case UOBJ_ELF_FEMALE: case UOBJ_ELF_MALE_GHOST: case UOBJ_ELF_FEMALE_GHOST: case UOBJ_GARGOYLE_MALE: case UOBJ_GARGOYLE_FEMALE: case UOBJ_GARGOYLE_MALE_GHOST: case UOBJ_GARGOYLE_FEMALE_GHOST: case UOBJ_GAMEMASTER: case 0x3de: case 0x3df: case 0x3e2: send_paperdoll( client, chr ); break; } } return; } else // doubleclicked an item { // next, search worn items, items in the backpack, and items in the world. Items::Item* item = find_legal_item( client->chr, serial ); // next, check people's backpacks. (don't recurse down) // (not done yet) if ( item != nullptr ) { const Items::ItemDesc& id = item->itemdesc(); if ( !id.ghosts_can_use && client->chr->dead() ) { private_say_above( client->chr, client->chr, "I am dead and cannot do that." ); return; } if ( !id.can_use_while_frozen && client->chr->frozen() ) { private_say_above( client->chr, client->chr, "I am frozen and cannot do that." ); return; } if ( !id.can_use_while_paralyzed && client->chr->paralyzed() ) { private_say_above( client->chr, client->chr, "I am paralyzed and cannot do that." ); return; } unsigned short dst = pol_distance( client->chr, item ); if ( dst > id.doubleclick_range && !client->chr->can_dblclickany() ) { private_say_above( client->chr, item, "That is too far away." ); return; } UObject* obj = item->toplevel_owner(); obj = obj->self_as_owner(); if ( id.use_requires_los && !client->chr->realm->has_los( *client->chr, *obj ) ) // DAVE // 11/24 { private_say_above( client->chr, item, "I can't see that." ); return; } ScriptDef sd; sd.quickconfig( "scripts/misc/dblclickitem.ecl" ); if ( sd.exists() ) { ref_ptr<Bscript::EScriptProgram> prog; prog = find_script2( sd, false, Plib::systemstate.config.cache_interactive_scripts ); if ( prog.get() != nullptr ) client->chr->start_script( prog.get(), false, new Module::EItemRefObjImp( item ) ); } item->double_click( client ); return; } // allow looking into containers being traded if ( client->chr->is_trading() ) { UContainer* cont = client->chr->trade_container()->find_container( serial ); if ( cont != nullptr ) { cont->builtin_on_use( client ); if ( !cont->locked() ) { if ( client->chr->trading_with->client != nullptr ) cont->builtin_on_use( client->chr->trading_with->client ); } return; } } } }