bool StartSkillScript(Client *client, const Attribute* attrib) { Character* chr = client->chr; ref_ptr<EScriptProgram> prog = find_script2( attrib->script_, true, // complain if not found config.cache_interactive_scripts ); if ( prog.get() != NULL ) { if ( chr->start_skill_script(prog.get()) ) { // Should the script handle the unhiding instead? if ( chr->hidden() && attrib->unhides ) chr->unhide(); if ( attrib->delay_seconds ) { chr->disable_skills_until = poltime() + attrib->delay_seconds; } return true; } } string msg = "Unable to start skill script:";//+attrib->script_.c_str(); msg += attrib->script_.c_str(); send_sysmessage(client, msg.c_str()); return false; }
// EXACTLY the same as start_script, except uses find_script2 UOExecutorModule* start_script( const ScriptDef& script, BObjectImp* param ) throw() { BObject bobj( param?param:UninitObject::create() ); // just to delete if it doesn't go somewhere else ref_ptr<EScriptProgram> program = find_script2( script ); if (program.get() == NULL) { cerr << "Error reading script " << script.name() << endl; // throw runtime_error( "Error starting script" ); return NULL; } auto_ptr<UOExecutor> ex( create_script_executor() ); if (program->haveProgram && (param != NULL)) { ex->pushArg( param ); } //ex->addModule( new FileExecutorModule( *ex ) ); UOExecutorModule* uoemod = new UOExecutorModule( *ex ); ex->addModule( uoemod ); if (!ex->setProgram( program.get() )) { return NULL; //throw runtime_error( "Error starting script." ); } ex->setDebugLevel( Executor::NONE ); runlist.push_back( ex.release() ); return uoemod; }
void USpell::cast( Mobile::Character* chr ) { if ( nocast_here( chr ) ) { if ( chr->client != NULL ) send_sysmessage( chr->client, "Spells cannot be cast here." ); return; } if ( !scriptdef_.empty() ) { ref_ptr<Bscript::EScriptProgram> prog = find_script2( scriptdef_, true, config.cache_interactive_scripts ); if ( prog.get() != NULL ) { if ( chr->start_spell_script( prog.get(), this ) ) return; } } if ( chr->client != NULL ) send_sysmessage( chr->client, "That spell doesn't seem to work." ); }
void Item::walk_on( Mobile::Character* chr ) { const Items::ItemDesc& itemdesc = this->itemdesc(); if ( !itemdesc.walk_on_script.empty() ) { ref_ptr<Bscript::EScriptProgram> prog; prog = find_script2( itemdesc.walk_on_script, true, // complain if not found Plib::systemstate.config.cache_interactive_scripts ); if ( prog.get() != NULL ) { std::unique_ptr<Core::UOExecutor> ex( Core::create_script_executor() ); ex->addModule( new Module::UOExecutorModule( *ex ) ); if ( prog->haveProgram ) { ex->pushArg( new Bscript::BLong( chr->lastz ) ); ex->pushArg( new Bscript::BLong( chr->lasty ) ); ex->pushArg( new Bscript::BLong( chr->lastx ) ); ex->pushArg( new Module::EItemRefObjImp( this ) ); ex->pushArg( new Module::ECharacterRefObjImp( chr ) ); } ex->os_module->priority = 100; if ( ex->setProgram( prog.get() ) ) { schedule_executor( ex.release() ); } } } }
BObjectImp* run_executor_to_completion( UOExecutor& ex, const ScriptDef& script ) { ref_ptr<EScriptProgram> program = find_script2( script ); if (program.get() == NULL) { cerr << "Error reading script " << script.name() << endl; return new BError( "Unable to read script" ); } add_common_exmods( ex ); ex.addModule( new UOExecutorModule( ex ) ); ex.setProgram( program.get() ); ex.setDebugLevel( Executor::NONE ); scripts_thread_script = ex.scriptname(); int i = 0; bool reported = false; while (ex.runnable()) { scripts_thread_scriptPC = ex.PC; ex.execInstr(); if (++i == 1000) { if (reported) { cout << ".." << ex.PC; } else { if(config.report_rtc_scripts) { cout << "Script " << script.name() << " running.." << ex.PC; reported = true; } } i = 0; } } if (reported) cout << endl; if (ex.error_) return new BError( "Script exited with an error condition" ); if (ex.ValueStack.empty()) return new BLong( 1 ); else return ex.ValueStack.top().get()->impptr()->copy(); }
void skillrequest( Network::Client* client, u32 serial ) { if ( serial == client->chr->serial ) { ScriptDef sd; sd.quickconfig( "scripts/misc/skillwin.ecl" ); if ( sd.exists() ) { ref_ptr<Bscript::EScriptProgram> prog; prog = find_script2( sd, false, // complain if not found Plib::systemstate.config.cache_interactive_scripts ); if ( prog.get() != NULL && client->chr->start_script( prog.get(), false ) ) { return; } } send_skillmsg( client, client->chr ); } }
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; } } } }