// All this Stuff should be scripted bool QuestionSpeech( cUOSocket *socket, P_PLAYER pPlayer, P_NPC pChar, const QString& comm ) { if( !pChar->isHuman() || pPlayer->dist( pChar ) > 3 ) return false; // Tell the questioner our name if( comm.contains( "NAME" ) ) { pChar->talk( tr( "Hello, my name is %1." ).arg( pChar->name() ) ); return true; } // say time and the npChar gives the time. if( comm.contains( "TIME" ) ) { pChar->talk( tr( "It is now %1" ).arg( uoTime.toString() ) ); return true; } if( comm.contains( "LOCATION" ) ) { cTerritory* Region = pPlayer->region(); if( Region ) pChar->talk( tr( "You are in %1" ).arg( Region->name() ) ); else pChar->talk( tr( "You are in the wilderness" ) ); return true; } // We couldn't handle the speech return false; }
bool PlayerVendorSpeech( cUOSocket *socket, P_PLAYER pPlayer, P_NPC pVendor, const QString &comm ) { /* if( pVendor->npcaitype() != 17 ) return false;*/ if( pPlayer->dist( pVendor ) > 4 ) return false; if( !VendorChkName( pVendor, comm ) ) return false; if( ( comm.contains( " BROWSE" ) ) || ( comm.contains( " VIEW" ) ) || ( comm.contains( " LOOK" ) ) ) { pVendor->talk( tr( "Take a look at my goods." ) ); if( pPlayer->socket() ) pPlayer->socket()->sendContainer( pVendor->getBackpack() ); return true; } if( ( comm.contains( " BUY" ) ) || ( comm.contains( " PURCHASE" ) ) ) { // >> LEGACY /*addx[s]=pVendor->serial(); npctalk(s,pVendor,"What would you like to buy?",0); target(s,0,1,0,224," ");*/ return true; } if( pVendor->owner() != pPlayer ) return false; if( ( comm.contains( " COLLECT" ) ) || ( comm.contains( " GOLD" ) ) || ( comm.contains( " GET" ) ) ) { PlVGetgold( socket, pPlayer, pVendor); return true; } if( comm.contains( "PACKUP" ) ) { P_ITEM pDeed = Items->SpawnItem( pPlayer, 1, "employment deed", 0, 0x14F0, 0, 1 ); if( pDeed ) { pDeed->setType( 217 ); pDeed->setBuyprice( 2000 ); pDeed->setSellprice( 1000 ); pDeed->update(); cCharStuff::DeleteChar( pVendor ); socket->sysMessage( tr( "Packed up vendor %1." ).arg( pVendor->name() ) ); return true; } } return false; }
// All ai controlled creatures can be controlled by a gm // or by their owner if tamed void AbstractAI::onSpeechInput( P_PLAYER pTalker, const QString &comm ) { if (!pTalker->isGM() && (!m_npc->isTamed() || m_npc->owner() != pTalker)) { return; } // too far away to hear us if (pTalker->dist(m_npc) > 7) { return; } if (comm.contains(" FOLLOW")) { if (comm.contains(" ME")) { m_npc->setWanderFollowTarget(pTalker); m_npc->setWanderType(enFollowTarget); m_npc->bark(cBaseChar::Bark_Attacking); } else { pTalker->socket()->attachTarget(new cFollowTarget(m_npc)); } } else if ((comm.contains(" KILL")) || (comm.contains(" ATTACK"))) { if (m_npc->inGuardedArea()) { pTalker->message(tr("You can't have pets attack in town!")); } } else if ((comm.contains(" FETCH")) || (comm.contains(" GET"))) { //pPlayer->setGuarded(false); // >> LEGACY //addx[s]=pPet->serial(); //target(s, 0, 1, 0, 124, "Click on the object to fetch."); } else if (comm.contains(" COME")) { m_npc->setWanderDestination(pTalker->pos()); m_npc->setWanderType(enDestination); m_npc->bark(cBaseChar::Bark_Attacking); } else if (comm.contains(" GUARD")) { } else if ((comm.contains(" STOP")) || (comm.contains(" STAY"))) { m_npc->fight(0); m_npc->setWanderType( enHalt ); m_npc->bark(cBaseChar::Bark_Attacking); } else if (comm.contains(" TRANSFER")) { } else if (comm.contains(" RELEASE")) { // Has it been summoned ? Let's dispel it if (m_npc->summoned()) { m_npc->setSummonTime(uiCurrentTime); } m_npc->setWanderType(enFreely); m_npc->setOwner(0); m_npc->setTamed(false); m_npc->bark(cBaseChar::Bark_Attacking); if (SrvParams->tamedDisappear()) { m_npc->soundEffect(0x01Fe); cCharStuff::DeleteChar(m_npc); } } }
///////////////// // name: response // purpose: tries to get a response from an npc standing around // history: heavily revamped/rewritten by Duke, Oct 2001 // remark: The new logic tries to minimize the # of strstr() calls by *first* checking // what kind of npcs are standing around and then checking only those keywords // that they might be interested in. // This is especially usefull in crowded places. bool Speech::response( cUOSocket* socket, P_PLAYER pPlayer, const QString& comm, QValueVector<Q_UINT16>& keywords ) { if ( !pPlayer->socket() || pPlayer->isDead() ) { return false; } QString speechUpr = comm.upper(); MapCharsIterator ri = MapObjects::instance()->listCharsInCircle( pPlayer->pos(), 18 ); for ( P_CHAR pChar = ri.first(); pChar; pChar = ri.next() ) { P_NPC pNpc = dynamic_cast<P_NPC>( pChar ); // We will only process NPCs here if ( !pNpc ) continue; // at least they should be on the screen if ( pPlayer->dist( pNpc ) > 16 ) continue; if ( pNpc->canHandleEvent( EVENT_SPEECH ) ) { PyObject* pkeywords = PyTuple_New( keywords.size() ); // Set Items for ( unsigned int i = 0; i < keywords.size(); ++i ) PyTuple_SetItem( pkeywords, i, PyInt_FromLong( keywords[i] ) ); PyObject* args = Py_BuildValue( "(NNNO)", pNpc->getPyObject(), pPlayer->getPyObject(), QString2Python( comm ), pkeywords ); bool result = pNpc->callEventHandler( EVENT_SPEECH, args ); Py_DECREF( args ); Py_DECREF( pkeywords ); if ( result ) return true; } if ( pNpc->ai() ) { pNpc->ai()->onSpeechInput( pPlayer, speechUpr ); } if ( QuestionSpeech( socket, pPlayer, pNpc, speechUpr ) ) return true; } return false; }
bool BankerSpeech( cUOSocket *socket, P_PLAYER pPlayer, P_CHAR pBanker, const QString& comm ) { // Needs to be a banker /* if( pBanker->npcaitype() != 8 ) return false;*/ if( pPlayer->dist(pBanker) > 6 ) return false; if( comm.contains( "BANK" ) ) { pBanker->turnTo( pPlayer ); socket->sendContainer( pPlayer->getBankBox() ); return true; } if( ( comm.contains( "BALANCE" ) ) | ( comm.contains( "WITHDRAW" ) ) || ( comm.contains( "CHECK" ) ) ) { //BankerAI->DoAI( s, pBanker, comm ); return true; } return false; }
// All ai controlled creatures can be controlled by a gm // or by their owner if tamed void AbstractAI::onSpeechInput( P_PLAYER pTalker, const QString& comm ) { if ( !pTalker->isGM() && ( !m_npc->isTamed() || m_npc->owner() != pTalker ) ) { return; } // too far away to hear us if ( pTalker->dist( m_npc ) > 7 ) { return; } if ( comm.contains( " FOLLOW" ) ) { if ( comm.contains( " ME" ) ) { m_npc->setWanderFollowTarget( pTalker ); m_npc->setWanderType( enFollowTarget ); m_npc->bark( cBaseChar::Bark_Attacking ); } else { pTalker->socket()->attachTarget( new cFollowTarget( m_npc ) ); } } else if ( ( comm.contains( " KILL" ) ) || ( comm.contains( " ATTACK" ) ) ) { if ( m_npc->inGuardedArea() ) { pTalker->message( tr( "You can't have pets attack in town!" ) ); } } else if ( ( comm.contains( " FETCH" ) ) || ( comm.contains( " GET" ) ) ) { //#pragma note( Implement me ) pTalker->message( tr( "Sorry, not implemented yet :(" ) ); } else if ( comm.contains( " COME" ) ) { m_npc->setWanderDestination( pTalker->pos() ); m_npc->setWanderType( enDestination ); m_npc->bark( cBaseChar::Bark_Attacking ); } else if ( comm.contains( " GUARD" ) ) { } else if ( ( comm.contains( " STOP" ) ) || ( comm.contains( " STAY" ) ) ) { m_npc->fight( 0 ); m_npc->setWanderType( enHalt ); m_npc->bark( cBaseChar::Bark_Attacking ); } else if ( comm.contains( " TRANSFER" ) ) { } else if ( comm.contains( " RELEASE" ) ) { // Has it been summoned ? Let's dispel it if ( m_npc->summoned() ) { m_npc->setSummonTime( Server::instance()->time() ); } m_npc->setWanderType( enFreely ); m_npc->setOwner( 0 ); m_npc->setTamed( false ); m_npc->bark( cBaseChar::Bark_Attacking ); if ( Config::instance()->tamedDisappear() ) { m_npc->soundEffect( 0x01Fe ); m_npc->remove(); } } }
///////////////// // name: response // purpose: tries to get a response from an npc standing around // history: heavily revamped/rewritten by Duke, Oct 2001 // remark: The new logic tries to minimize the # of strstr() calls by *first* checking // what kind of npcs are standing around and then checking only those keywords // that they might be interested in. // This is especially usefull in crowded places. bool cSpeech::response( cUOSocket *socket, P_PLAYER pPlayer, const QString& comm, QValueVector< UINT16 > &keywords ) { if( !pPlayer->socket() || pPlayer->isDead() ) return false; QString speechUpr = comm.upper(); RegionIterator4Chars ri( pPlayer->pos() ); for( ri.Begin(); !ri.atEnd(); ri++ ) { P_NPC pNpc = dynamic_cast<P_NPC>(ri.GetData()); // We will only process NPCs here if( !pNpc ) continue; // at least they should be on the screen if( pPlayer->dist( pNpc ) > 16 ) continue; // Check if the NPC has a script that can handle // speech events and then check if it can handle everything // or just certain things std::vector< WPDefaultScript* > events = pNpc->getEvents(); for( std::vector< WPDefaultScript* >::const_iterator iter = events.begin(); iter != events.end(); ++iter ) { WPDefaultScript *script = *iter; if( !script->handleSpeech() ) continue; if( script->catchAllSpeech() || script->canHandleSpeech( comm, keywords ) ) if( script->onSpeech( pNpc, pPlayer, comm, keywords ) ) return true; } cNPC_AI* pAI = pNpc->ai(); if( pAI && pAI->currState() ) { pAI->currState()->speechInput( pPlayer, speechUpr ); pAI->updateState(); } if( BankerSpeech( socket, pPlayer, pNpc, speechUpr ) ) return true; if( PetCommand( socket, pPlayer, pNpc, speechUpr ) ) return true; if( StableSpeech( socket, pPlayer, pNpc, speechUpr ) ) return true; if( UnStableSpeech( socket, pPlayer, pNpc, speechUpr ) ) return true; if( ShieldSpeech( socket, pPlayer, pNpc, speechUpr ) ) return true; if( QuestionSpeech( socket, pPlayer, pNpc, speechUpr ) ) return true; if( TrainerSpeech( socket, pPlayer, pNpc, speechUpr ) ) return true; if( PlayerVendorSpeech( socket, pPlayer, pNpc, speechUpr ) ) return true; } return false; }
bool PetCommand( cUOSocket *socket, P_PLAYER pPlayer, P_NPC pPet, const QString& comm ) { if( pPet->owner() != pPlayer && !pPlayer->isGM() ) return false; // player vendor /* if( pPet->npcaitype() == 17 ) return false;*/ // too far away to hear us if( pPlayer->dist( pPet ) > 7 ) return false; QString petname = pPet->name(); bool bAllCommand = false; if( !comm.contains( petname, false ) ) if( comm.contains( "ALL", false ) ) bAllCommand = true; else return false; bool bReturn = false; if( comm.contains( " FOLLOW" ) ) { if( comm.contains( " ME" ) ) { #pragma note( "TODO: implement state change here" ) // pPet->setWanderFollowTarget( pPlayer->serial() ); // pPet->setWanderType( enFollowTarget ); playmonstersound( pPet, pPet->bodyID(), SND_STARTATTACK ); } else { // LEGACY: target( s, 0, 1, 0, 117, "Click on the target to follow." ); } bReturn = true; } else if( ( comm.contains( " KILL" ) ) || ( comm.contains( " ATTACK" ) ) ) { if( pPet->inGuardedArea() ) // Ripper..No pet attacking in town. { pPlayer->message( tr( "You can't have pets attack in town!" ) ); return false; } //pPlayer->setGuarded( false ); // >> LEGACY //addx[s]=pPet->serial(); //target(s, 0, 1, 0, 118, "Select the target to attack.");//AntiChrist bReturn = true; } else if( ( comm.contains( " FETCH" ) ) || ( comm.contains( " GET" ) ) ) { //pPlayer->setGuarded(false); // >> LEGACY //addx[s]=pPet->serial(); //target(s, 0, 1, 0, 124, "Click on the object to fetch."); bReturn = true; } else if( comm.contains( " COME" ) ) { //pPlayer->setGuarded( false ); #pragma note( "TODO: implement state change here" ) // pPet->setWanderFollowTarget( pPlayer->serial() ); // pPet->setWanderType( enFollowTarget ); pPet->setNextMoveTime(); pPlayer->message( tr( "Your pet begins following you." ) ); bReturn = true; } else if( comm.contains( " GUARD" ) ) { // LEGACY /*addx[s] = pPet->serial(); // the pet's serial addy[s] = 0; if( comm.find( " ME" ) != string::npos ) addy[s]=1; // indicates we already know whom to guard (for future use) // for now they still must click on themselves (Duke) target(s, 0, 1, 0, 120, "Click on the char to guard.");*/ bReturn = true; } else if( ( comm.contains( " STOP" ) ) || ( comm.contains(" STAY") ) ) { //pPlayer->setGuarded( false ); #pragma note( "TODO: implement state change here" ) // pPet->setWanderFollowTarget( INVALID_SERIAL ); pPet->setCombatTarget( INVALID_SERIAL ); if (pPet->isAtWar()) pPet->toggleCombat(); pPet->setWanderType( enHalt ); bReturn = true; } else if( comm.contains( " TRANSFER" ) ) { //pPlayer->setGuarded( false ); // >> LEGACY /*addx[s]=pPet->serial(); target(s, 0, 1, 0, 119, "Select character to transfer your pet to.");*/ bReturn = true; } else if( comm.contains( " RELEASE" ) ) { //pPlayer->setGuarded( false ); // Has it been summoned ? Let's dispel it if( pPet->summonTime() > uiCurrentTime ) pPet->setSummonTime( uiCurrentTime ); #pragma note( "TODO: implement state change here" ) // pPet->setWanderFollowTarget( INVALID_SERIAL ); pPet->setWanderType( enFreely ); pPet->setOwner( NULL ); pPet->setTamed( false ); pPet->emote( tr( "%1 appears to have decided that it is better off without a master" ).arg( pPet->name() ) ); if( SrvParams->tamedDisappear() ==1 ) { pPet->soundEffect( 0x01FE ); cCharStuff::DeleteChar( pPet ); } bReturn = true; } // give other pets opotunity to process command if ( bReturn && bAllCommand ) return false; else return bReturn; }