Exemplo n.º 1
0
void Human_Stablemaster::onSpeechInput( P_PLAYER pTalker, const QString& message )
{
	if ( !pTalker->socket() )
		return;

	if ( m_npc->inRange( pTalker, 4 ) && ( VendorChkName( m_npc, message ) || message.contains( tr( "STABLEMASTER" ) ) ) )
	{
		if ( message.contains( tr( " STABLE" ) ) )
		{
			m_npc->talk( tr( "Which pet do you want me to stable?" ) );
			pTalker->socket()->attachTarget( new cStableTarget( m_npc ) );
		}
		else if ( message.contains( tr( " RELEASE" ) ) )
		{
			int gold = pTalker->countBankGold() + pTalker->countGold();
			P_ITEM pPack = m_npc->getBankbox();
			
			cItem::ContainerContent stableitems;
			if ( pPack )
			{
				cItem::ContainerContent content = pPack->content();
				cItem::ContainerContent::const_iterator it( content.begin() );
				while ( it != content.end() )
				{
					if ( !( *it )->hasTag( "player" ) || !( *it )->hasTag( "pet" ) )
						continue;

					if ( ( *it ) && ( uint )( *it )->getTag( "player" ).toInt() == pTalker->serial() )
						stableitems.push_back( ( *it ) );
					++it;
				}
			}

			if ( !stableitems.empty() )
			{
				cItem::ContainerContent::const_iterator it( stableitems.begin() );
				while ( it != stableitems.end() )
				{
					if ( ( *it ) )
					{
						P_NPC pPet = dynamic_cast<P_NPC>( World::instance()->findChar( ( *it )->getTag( "pet" ).toInt() ) );
						if ( pPet )
						{
							pPet->free = false;
							// we need this for db saves
							pPet->setStablemasterSerial( INVALID_SERIAL );
							pPet->moveTo( m_npc->pos() );
							pPet->resend();
						}
						( *it )->remove();
					}
					++it;
				}

				pPack->update();
				m_npc->talk( tr( "Here's your pet back!" ) );
			}
		}
	}
}
Exemplo n.º 2
0
void cPlayer::addPet( P_NPC pPet, bool noOwnerChange )
{
	if ( !pPet )
		return;

	// It may be the follower of someone else already, so
	// check that...
	if ( pPet->owner() && pPet->owner() != this )
		pPet->owner()->removePet( pPet, true );

	// Only reset the owner if we have slots left
	if ( pets_.size() + pPet->controlSlots() <= maxControlSlots() )
	{
		pPet->setOwner( this, true );

		// Check if it already is our follower
		CharContainer::iterator it = std::find( pets_.begin(), pets_.end(), pPet );
		if ( it != pets_.end() )
			return;

		pets_.push_back( pPet );

		if ( socket_ )
		{
			socket_->sendStatWindow();
		}
	}
}
Exemplo n.º 3
0
void cCombat::spawnGuard( P_CHAR pOffender, P_CHAR pCaller, const Coord& pos )
{
	if ( !pOffender || !pCaller )
		return;

	if ( pOffender->isDead() || pCaller->isDead() )
		return;

	cTerritory* pRegion = pCaller->region();

	if ( pRegion == NULL )
		return;

	if ( pRegion->isGuarded() && Config::instance()->guardsActive() )
	{
		QString guardsect = pRegion->getGuardSect();

		P_NPC pGuard = ( guardsect.isNull() ? NULL : cNPC::createFromScript( guardsect, pos ) );

		if ( !pGuard )
			return;

		// Send guard to surrounding Players
		pGuard->resend( false );
		pGuard->soundEffect( 0x1FE );
		pGuard->effect( 0x372A, 0x09, 0x06 );
		pGuard->fight( pOffender );
	}
}
Exemplo n.º 4
0
void cSectorMaps::add( cUObject* object )
{
	// Very powerful statement. It completely
	// annihilates the need to check for
	// nullpointers in our object-map
	if ( !object )
		return;

	if ( isItemSerial( object->serial() ) )
	{
		P_ITEM pItem = dynamic_cast<P_ITEM>( object );
		if ( pItem )
		{
			Coord_cl pos = pItem->pos();

			std::map<unsigned char, cSectorMap*>::const_iterator it = itemmaps.find( pos.map );

			if ( it == itemmaps.end() )
				throw QString( "Couldn't find a map with the id %1." ).arg( pos.map );

			it->second->addItem( ( cUObject * ) pItem );

			Timing::instance()->addDecayItem( pItem );
		}
	}
	else if ( isCharSerial( object->serial() ) )
	{
		// This is a safety check to make sure that
		// stabled pets don't appear on our sectormap
		P_NPC npc = dynamic_cast<P_NPC>( object );

		if ( npc && npc->stablemasterSerial() != INVALID_SERIAL )
		{
			return;
		}

		// The same check for players
		/*P_PLAYER player = dynamic_cast<P_PLAYER>( object );

		if ( player && !player->socket() && !player->logoutTime() )
		{
			return;
		}*/

		P_CHAR pChar = dynamic_cast<P_CHAR>( object );
		if ( pChar )
		{
			Coord_cl pos = pChar->pos();

			std::map<unsigned char, cSectorMap*>::const_iterator it = charmaps.find( pos.map );

			if ( it == charmaps.end() )
				throw QString( "Couldn't find a map with the id %1." ).arg( pos.map );

			it->second->addItem( ( cUObject * ) pChar );
		}
	}
}
Exemplo n.º 5
0
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;
}
// do one spawn and reset the timer
void cSpawnRegion::reSpawn( void )
{
	this->checkForDeleted();

	UI16 i = 0;
	for( i = 0; i < this->npcsPerCycle_; i++ )
	{
		if( this->npcSerials_.size() < this->maxNpcAmt_ )
		{
			// spawn a random npc
			// first find a valid position for the npc
			Coord_cl pos;
			if( this->findValidSpot( pos ) )
			{
				QString NpcSect = this->npcSections_[ RandomNum( 1, this->npcSections_.size() ) - 1 ];
				P_NPC pc = cCharStuff::createScriptNpc( NpcSect, pos );
				if( pc != NULL )
				{
					this->npcSerials_.push_back( pc->serial() );
					pc->setSpawnregion( this->name_ );
				}
			}
		}
	}

	for( i = 0; i < this->itemsPerCycle_; i++ )
	{
		if( this->itemSerials_.size() < this->maxItemAmt_ )
		{
			// spawn a random item
			// first find a valid position for the item
			Coord_cl pos;
			if( this->findValidSpot( pos ) )
			{
				QString ItemSect = this->itemSections_[ RandomNum( 1, this->itemSections_.size() ) - 1 ];
				P_ITEM pi = cItem::createFromScript( ItemSect );
				if( pi != NULL )
				{
					pi->moveTo( pos );
					this->itemSerials_.push_back( pi->serial() );
//					pi->setSpawnRegion( this->name_ );
				}
			}
		}
	}

	this->nextTime_ = uiCurrentTime + RandomNum( this->minTime_, this->maxTime_ ) * MY_CLOCKS_PER_SEC;
}
void cSpawnRegion::spawnSingleNPC()
{
	Coord_cl pos;
	if ( findValidSpot( pos ) )
	{
		QString NpcSect = this->npcSections_[RandomNum( 1, this->npcSections_.size() ) - 1];
		P_NPC pc = cNPC::createFromScript( NpcSect, pos );
		if ( pc )
		{
			pc->setSpawnregion( this );
			if ( pc->wanderType() == enFreely )
			{
				pc->setWanderType( enWanderSpawnregion );
			}
			pc->update();
			onSpawn( pc );
		}
	}
}
void cSpawnRegion::reSpawnToMax( void )
{
	this->checkForDeleted();

	while( this->npcSerials_.size() < this->maxNpcAmt_ )
	{
		// spawn a random npc
		// first find a valid position for the npc
		Coord_cl pos;
		if( this->findValidSpot( pos ) )
		{
			QString NpcSect = this->npcSections_[ RandomNum( 1, static_cast<uint>(this->npcSections_.size()) ) - 1 ];
			P_NPC pc = cCharStuff::createScriptNpc( NpcSect, pos );
			if( pc != NULL )
			{
				this->npcSerials_.push_back( pc->serial() );
				pc->setSpawnregion( this->name_ );
				pc->update();
			}
		}
	}

	while( this->npcSerials_.size() < this->maxNpcAmt_ )
	{
		// spawn a random item
		// first find a valid position for the item
		Coord_cl pos;
		if( this->findValidSpot( pos ) )
		{
			QString ItemSect = this->itemSections_[ RandomNum( 1, this->itemSections_.size() ) - 1 ];
			P_ITEM pi = cItem::createFromScript( ItemSect );
			if( pi != NULL )
			{
				pi->setPos( pos );
				this->itemSerials_.push_back( pi->serial() );
//				pi->setSpawnRegion( this->name_ );
			}
		}
	}

	this->nextTime_ = uiCurrentTime + RandomNum( this->minTime_, this->maxTime_ ) * MY_CLOCKS_PER_SEC;
}
Exemplo n.º 9
0
// 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;
}
Exemplo n.º 10
0
void cSpawnRegion::checkForDeleted( void )
{
	std::vector< SERIAL > foundSerials;
	std::vector< SERIAL >::iterator it = this->npcSerials_.begin();
	while( it != this->npcSerials_.end() )
	{
		P_NPC pChar = dynamic_cast<P_NPC>( FindCharBySerial( *it ) );
		if( pChar && !pChar->free && pChar->spawnregion() == name_ )
			foundSerials.push_back( (*it) );
		it++;
	}
	npcSerials_ = foundSerials;

	foundSerials.clear();
	it = this->itemSerials_.begin();
	while( it != this->itemSerials_.end() )
	{
		if( FindItemBySerial( *it ) )
			foundSerials.push_back( (*it) );
		it++;
	}
	itemSerials_ = foundSerials;
}
Exemplo n.º 11
0
/////////////////
// 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;
}
Exemplo n.º 12
0
void cAIFactory::checkScriptAI( const QStringList& oldSections, const QStringList& newSections )
{
	QStringList::const_iterator aiit = oldSections.begin();
	for ( ; aiit != oldSections.end(); ++aiit )
	{
		// We must reset all existing and scripted AI objects, so changes can take effect.
		if ( !newSections.contains( *aiit ) )
		{
			cCharIterator iter;
			for ( P_CHAR pChar = iter.first(); pChar; pChar = iter.next() )
			{
				P_NPC pNPC = dynamic_cast<P_NPC>( pChar );
				if ( pNPC )
				{
					ScriptAI* ai = dynamic_cast<ScriptAI*>( pNPC->ai() );
					if ( ai && ai->name() == ( *aiit ) )
					{
						pNPC->setAI( *aiit );
					}
				}
			}
		}
		else
		{
			cCharIterator iter;
			for ( P_CHAR pChar = iter.first(); pChar; pChar = iter.next() )
			{
				P_NPC pNPC = dynamic_cast<P_NPC>( pChar );
				if ( pNPC )
				{
					ScriptAI* ai = dynamic_cast<ScriptAI*>( pNPC->ai() );
					if ( ai && ai->name() == ( *aiit ) )
					{
						delete ai;
						pNPC->setAI( NULL );
					}
				}
			}
			unregisterType( *aiit );
		}
	}
	aiit = newSections.begin();
	while ( aiit != newSections.end() )
	{
		if ( !oldSections.contains( *aiit ) )
		{
			ScriptAI::registerInFactory( *aiit );
		}
		++aiit;
	}
}
Exemplo n.º 13
0
void cPlayer::removePet( P_NPC pPet, bool noOwnerChange )
{
	if ( !pPet )
		return;

	CharContainer::iterator it = std::find( pets_.begin(), pets_.end(), pPet );
	if ( it != pets_.end() )
		pets_.erase( it );

	if ( !noOwnerChange )
	{
		pPet->setOwner( NULL, true );
	}

	if ( socket_ )
	{
		socket_->sendStatWindow();
	}
}
Exemplo n.º 14
0
void Human_Stablemaster::handleTargetInput( P_PLAYER player, cUORxTarget* target )
{
	if ( !player )
		return;

	P_ITEM pPack = m_npc->getBankbox();
	if ( !pPack )
		return;

	P_NPC pPet = dynamic_cast<P_NPC>( World::instance()->findChar( target->serial() ) );
	if ( !pPet )
	{
		m_npc->talk( tr( "I cannot stable that!" ) );
		return;
	}

	if ( pPet->owner() != player )
	{
		m_npc->talk( tr( "This does not belong to you!" ) );
		return;
	}

	// we spawn a worldgem in the stablemasters bankbox for the pet
	// it does only hold the serial of it, the serial of the owner and the
	// number of refresh signals since begin of stabling
	// the pet becomes "free", which means, that it isnt in the world
	// but will still be saved.
	P_ITEM pGem = new cItem();
	pGem->Init( true );
	pGem->setTag( "player", cVariant( player->serial() ) );
	pGem->setTag( "pet", cVariant( pPet->serial() ) );
	pGem->setId( 0x1ea7 );
	pGem->setName( tr( "petitem: %1" ).arg( pPet->name() ) );
	pGem->setVisible( 2 ); // gm visible
	pPack->addItem( pGem );
	pGem->update();


	//pPet->free = true;
	MapObjects::instance()->remove( pPet );
	pPet->setStablemasterSerial( this->m_npc->serial() );
	pPet->removeFromView();

	// we need this for db saves
    m_npc->talk( tr( "Say release to get your pet back!" ) );
}
Exemplo n.º 15
0
P_NPC cPlayer::unmount()
{
	P_ITEM pi = atLayer( Mount );
	if ( pi && !pi->free )
	{
		P_NPC pMount = dynamic_cast<P_NPC>( FindCharBySerial( pi->getTag( "pet" ).toInt() ) );
		if ( pMount && !pMount->free )
		{
			pMount->setWanderType( enHalt );
			pMount->setStablemasterSerial( INVALID_SERIAL );
			pMount->moveTo( pos() );
			pMount->setDirection( direction_ );
			pMount->resend( false );
			pMount->bark( Bark_Idle );
		}
		pi->remove();
		resend( false );
		return pMount;
	}
	return NULL;
}
Exemplo n.º 16
0
static void npcRegisterAfterLoading( P_NPC pc )
{
	if (pc->stablemasterSerial() == INVALID_SERIAL) {
		MapObjects::instance()->add(pc);
	}
}
Exemplo n.º 17
0
/*!
	This handles if a character actually tries to walk (NPC & Player)
*/
bool cMovement::Walking( P_CHAR pChar, Q_UINT8 dir, Q_UINT8 sequence )
{
	if ( !pChar )
		return false;

	// Scripting
	if ( pChar->onWalk( dir, sequence ) )
		return false;

	P_PLAYER player = dynamic_cast<P_PLAYER>( pChar );

	// Is the sequence in order ?
	if ( player && player->socket() && !verifySequence( player->socket(), sequence ) )
		return false;

	// If checking for weight is more expensive, shouldn't we check for frozen first?
	if ( pChar->isFrozen() )
	{
		if ( player && player->socket() )
			player->socket()->denyMove( sequence );
		return false;
	}

	// save our original location before we even think about moving
	const Coord oldpos( pChar->pos() );

	// If the Direction we're moving to is different from our current direction
	// We're turning and NOT moving into a specific direction
	// Clear the running flag here (!)
	// If the direction we're moving is already equal to our current direction
	bool running = dir & 0x80;
	dir = dir & 0x7; // Remove all unneeded stuff

	pChar->setRunning( running );

	bool turning = dir != pChar->direction();

	// This happens if we're moving
	if ( !turning )
	{
		// Note: Do NOT use the copy constructor as it'll create a reference
		Coord newCoord = calcCoordFromDir( dir, pChar->pos() );

		// Check if the stamina parameters
		if ( player && !consumeStamina( player, running ) )
		{
			if ( player->socket() )
				player->socket()->denyMove( sequence );
			return false;
		}

		// Check if we're going to collide with characters
		if ( player )
		{
			// Player vs characters
			if ( player->socket() && player->pos().map == 0 && !player->account()->isStaff() )
			{
				// Currently hard-limiting collisions to Felucca; this should be a server option!
				MapCharsIterator charCollisions = MapObjects::instance()->listCharsAtCoord( newCoord );
				for ( P_CHAR them = charCollisions.first(); them; them = charCollisions.next() )
				{
					if ( them == player )
						continue;

					P_PLAYER otherplayer = dynamic_cast<P_PLAYER>( them );
					if ( otherplayer && otherplayer->account()->isStaff() )
						continue; // no collisions against the staff

					if ( wpAbs<SI08>( newCoord.z - them->pos().z ) < P_M_MAX_Z_CLIMB )
					{
						// to push another char we must have maximum stamina
						if ( player->stamina() >= player->maxStamina() )
						{
							player->socket()->clilocMessage( them->isHidden() ? 1019043 : 1019042 );
							player->setStamina( player->stamina() - 10 );
							break;
						}
						else
						{
							player->socket()->denyMove( sequence );
							return false;
						}
					}
				}
			}
		}
		else
		{
			// NPC vs characters
			P_NPC npc = dynamic_cast<P_NPC>( pChar );
			if ( npc && CheckForCharacterAtXYZ( pChar, newCoord ) )
			{
				npc->clearPath();
				return false;
			}
		}

		// Check if the char can move to those new coordinates
		// It is going to automatically calculate the new coords (!)
		if ( !mayWalk( pChar, newCoord ) )
		{
			if ( player && player->socket() )
				player->socket()->denyMove( sequence );
			return false;
		}
		else
		{
			if ( player && player->socket() )
				player->socket()->allowMove( sequence );
		}

		// We moved so let's update our location
		pChar->moveTo( newCoord );
		pChar->setStepsTaken( pChar->stepsTaken() + 1 );
		pChar->setLastMovement( Server::instance()->time() );
		checkStealth( pChar ); // Reveals the user if neccesary
	}
	else
	{
		if ( player && player->socket() )
			player->socket()->allowMove( sequence );
	}

	// do all of the following regardless of whether turning or moving i guess
	// set the player direction to contain only the cardinal direction bits
	pChar->setDirection( dir );

	Coord upperLeft = pChar->pos() - Coord( ( VISRANGE + 1 ), ( VISRANGE + 1 ) );
	Coord lowerRight = pChar->pos() + Coord( ( VISRANGE + 1 ), ( VISRANGE + 1 ) );

	MapCharsIterator ri = MapObjects::instance()->listCharsInRect( upperLeft, lowerRight );
	for ( P_CHAR observer = ri.first(); observer; observer = ri.next() )
	{
		if ( observer == pChar )
			continue;

		bool wasVisible = observer->pos().distance( oldpos ) < VISRANGE; // We were previously in range
		bool isVisible = pChar->dist( observer ) < VISRANGE; // We are now in range

		// If we are a player, send us new characters
		if ( player && player->socket() )
		{
			// Send the observer to us if he was previously not visible and came into range recently
			if ( !wasVisible && isVisible )
			{
				player->socket()->sendChar( observer );
			}
		}

		// Send our movement to the observer
		P_PLAYER otherplayer = dynamic_cast<P_PLAYER>( observer );

		if ( !otherplayer || !otherplayer->socket() )
		{
			continue; // Skip this character, it's a player.
			// TODO: OnSeePlayer, OnLoosePlayer
		}

		if ( wasVisible )
		{
			if ( isVisible )
			{
				otherplayer->socket()->updateChar( pChar ); // We walked inside the visible range
			}
			else
			{
				otherplayer->socket()->removeObject( pChar ); // We walked out of visible range
			}
		}
		else if ( isVisible )
		{
			otherplayer->socket()->sendChar( pChar ); // We walked into visible range
		}
	}

	// If we really moved handle teleporters and new items
	if ( !turning )
	{
		handleItems( pChar, oldpos );
		handleMultis( pChar, oldpos );
		handleTeleporters( pChar, oldpos );
	}

	return true;
}
Exemplo n.º 18
0
void DragAndDrop::equipItem( cUOSocket* socket, cUORxWearItem* packet )
{
	P_ITEM pItem = FindItemBySerial( packet->serial() );
	P_CHAR pWearer = FindCharBySerial( packet->wearer() );

	if ( !pItem || !pWearer )
		return;

	P_PLAYER pChar = socket->player();

	// We're dead and can't do that
	if ( pChar->isDead() )
	{
		socket->clilocMessage( 0x7A4D5, "", 0x3b2 ); // You can't do that when you're dead.
		socket->bounceItem( pItem, BR_NO_REASON );
		return;
	}

	// No Special Layer Equipping
	if ( ( packet->layer() > cBaseChar::InnerLegs || packet->layer() <= cBaseChar::TradeWindow ) && !pChar->isGM() )
	{
		socket->sysMessage( tr( "You can't equip on that layer." ) );
		socket->bounceItem( pItem, BR_NO_REASON );
		return;
	}

	// Our target is dead
	if ( ( pWearer != pChar ) && pWearer->isDead() )
	{
		socket->sysMessage( tr( "You can't equip dead players." ) );
		socket->bounceItem( pItem, BR_NO_REASON );
		return;
	}

	// Only GM's can equip other People
	if ( pWearer != pChar && !pChar->isGM() )
	{
		P_NPC pNpc = dynamic_cast<P_NPC>( pWearer );

		// But we are allowed to equip our own humans
		if ( !pNpc || ( pNpc->owner() != pChar && pWearer->isHuman() ) )
			socket->sysMessage( tr( "You can't equip other players." ) );

		socket->bounceItem( pItem, BR_NO_REASON );
		return;
	}

	// Get our tile-information
	tile_st pTile = TileCache::instance()->getTile( pItem->id() );

	// Is the item wearable ? ( layer == 0 | equip-flag not set )
	// Multis are not wearable are they :o)
	if ( pTile.layer == 0 || !( pTile.flag3 & 0x40 ) || pItem->isMulti() )
	{
		socket->sysMessage( tr( "This item cannot be equipped." ) );
		socket->bounceItem( pItem, BR_NO_REASON );
		return;
	}

	// Check the Script for it
	if ( pItem->onWearItem( pChar, pWearer, packet->layer() ) )
	{
		socket->bounceItem( pItem, BR_NO_REASON );
		return;
	}

	// Males can't wear female armor
	if ( ( pChar->body() == 0x0190 ) && ( pItem->id() >= 0x1C00 ) && ( pItem->id() <= 0x1C0D ) )
	{
		socket->sysMessage( tr( "You cannot wear female armor." ) );
		socket->bounceItem( pItem, BR_NO_REASON );
		return;
	}

	// Needs a check (!)
	// Checks for equipment on the same layer
	// If there is any it tries to unequip it
	// If that fails it cancels
	// we also need to check if there is a twohanded weapon if we want to equip another weapon.
	UI08 layer = pTile.layer;

	P_ITEM equippedLayerItem = pWearer->atLayer( static_cast<cBaseChar::enLayer>( layer ) );

	// we're equipping so we do the check
	if ( equippedLayerItem )
	{
		if ( pChar->canPickUp( equippedLayerItem ) )
		{
			equippedLayerItem->toBackpack( pWearer );
		}
		else
		{
			socket->sysMessage( tr( "You can't wear another item there!" ) );
			socket->bounceItem( pItem, BR_NO_REASON );
			return;
		}
	}

	// Check other layers if neccesary
	bool occupied = false;

	if ( pItem->twohanded() && layer == 1 )
	{
		occupied = pWearer->leftHandItem() != 0;  // Twohanded weapon on layer 1 forbids item on layer 2
	}
	else if ( pItem->twohanded() && layer == 2 )
	{
		occupied = pWearer->rightHandItem() != 0;  // Twohanded weapon on layer 2 forbids item on layer 1
	}
	else if ( layer == 1 )
	{
		P_ITEM lefthand = pWearer->leftHandItem();
		occupied = lefthand && lefthand->twohanded();
	}
	else if ( layer == 2 )
	{
		P_ITEM righthand = pWearer->rightHandItem();
		occupied = righthand && righthand->twohanded();
	}

	if ( occupied )
	{
		socket->sysMessage( tr( "You can't hold another item while wearing a twohanded item!" ) );
		socket->bounceItem( pItem, BR_NO_REASON );
		return;
	}

	// At this point we're certain that we can wear the item
	pWearer->addItem( static_cast<cBaseChar::enLayer>( pTile.layer ), pItem );

	if ( pWearer->objectType() == enPlayer )
	{
		P_PLAYER pp = dynamic_cast<P_PLAYER>( pWearer );
		if ( pp->socket() )
			pp->socket()->sendStatWindow();
	}

	// I don't think we need to remove the item
	// as it's only visible to the current char
	// And he looses contact anyway

	// Build our packets
	cUOTxCharEquipment wearItem;
	wearItem.fromItem( pItem );

	cUOTxSoundEffect soundEffect;
	soundEffect.setSound( 0x57 );
	soundEffect.setCoord( pWearer->pos() );

	// Send to all sockets in range
	// ONLY the new equipped item and the sound-effect
	for ( cUOSocket*mSock = Network::instance()->first(); mSock; mSock = Network::instance()->next() )
	{
		if ( mSock->player() && ( mSock->player()->dist( pWearer ) <= mSock->player()->visualRange() ) )
		{
			mSock->send( &wearItem );
			mSock->send( &soundEffect );
		}
	}
}
Exemplo n.º 19
0
/////////////////
// 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;
}
Exemplo n.º 20
0
	// Is the target dispellable?
	bool canDispel( P_CHAR target )
	{
		P_NPC npc = dynamic_cast<P_NPC>( target );
		return npc && npc->summoned() && m_npc->inRange( npc, 12 );
	}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
0
	/*
		Find something to dispel we are fighting.
	*/
	P_NPC findDispelOpponent()
	{
		if ( m_npc->intelligence() < 95 || m_npc->summoned() )
		{
			return 0; // No dispelling below 95 int or if the NPC is summoned itself.
		}

		QPtrList<cFightInfo> &fights = m_npc->fights();
		Monster_Aggressive *ai = static_cast<Monster_Aggressive*>( m_ai );

		P_NPC currentTarget = 0;
		unsigned int currentPriority = 0;

		/*
				Check our current attack target. It has the highest priority of all since
				we are fighting it anyway.
			*/
		if ( !invalidTarget( m_npc, ai->currentVictim() ) && canDispel( ai->currentVictim() ) )
		{
			currentTarget = dynamic_cast<P_NPC>( ai->currentVictim() );
			currentPriority = m_npc->dist( ai->currentVictim() );
			if ( currentPriority <= 2 )
			{
				return currentTarget; // We found a threat in our range, so dispel it now.
			}
		}

		/*
				Now check everyone who is fighting us
			*/
		for ( cFightInfo*info = fights.first(); info; info = fights.next() )
		{
			P_NPC checkTarget;
			if ( info->victim() == m_npc )
			{
				checkTarget = dynamic_cast<P_NPC>( info->attacker() );
			}
			else
			{
				checkTarget = dynamic_cast<P_NPC>( info->victim() );
			}

			// They have to be fighting us or they are uninteresting for this check
			if ( !checkTarget || checkTarget->attackTarget() != m_npc )
			{
				continue;
			}

			if ( !invalidTarget( m_npc, checkTarget ) && canDispel( checkTarget ) )
			{
				unsigned int newPriority = m_npc->dist( checkTarget );
				if ( !currentTarget || currentPriority > newPriority )
				{
					currentTarget = dynamic_cast<P_NPC>( ai->currentVictim() );
					currentPriority = m_npc->dist( ai->currentVictim() );
					if ( currentPriority <= 2 )
					{
						return currentTarget; // We found a threat in our range, so dispel it now.
					}
				}
			}
		}

		return currentTarget;
	}
Exemplo n.º 23
0
P_NPC cCharStuff::createScriptNpc( const QString &section, const Coord_cl &pos )
{
	if( section.isNull() || section.isEmpty() )
		return NULL;

	const QDomElement* DefSection = DefManager->getSection( WPDT_NPC, section );

	if( !DefSection || DefSection->isNull() )
	{
		clConsole.log( LOG_ERROR, QString( "Unable to create unscripted npc: %1\n" ).arg( section ) );
		return NULL;
	}

	P_NPC pChar = new cNPC;
	pChar->Init();

	pChar->setMinDamage(1);
	pChar->setMaxDamage(1);
	pChar->setBodyArmor(1);

	pChar->moveTo( pos );

	pChar->setRegion( AllTerritories::instance()->region( pChar->pos().x, pChar->pos().y, pChar->pos().map ) );

	pChar->applyDefinition( *DefSection );

	// Now we call onCreate
	pChar->onCreate( section );

	pChar->resend( false );

	return pChar;
}
Exemplo n.º 24
0
bool cPlayer::mount( P_NPC pMount )
{
	if ( !pMount )
		return false;

	if ( isDead() )
	{
		return false;
	}

	unsigned short mountId = pMount->mountId();

	if ( !mountId )
	{
		return false; // Not mountable
	}

	cUOSocket* socket = this->socket();
	if ( !inRange( pMount, Config::instance()->mountRange() ) && !isGM() )
	{
		if ( socket )
			socket->sysMessage( 500206 ); // That is too far away to ride.
		return true; // Mountable, but not in range
	}

	if ( pMount->owner() == this || isGM() )
	{
		unmount();

		P_ITEM pMountItem = new cItem;
		pMountItem->Init();
		pMountItem->setId( mountId );
		pMountItem->setColor( pMount->skin() );

		if ( direction() != pMount->direction() )
		{
			setDirection( pMount->direction() );
			update();
		}

		this->addItem( cBaseChar::Mount, pMountItem );
		pMountItem->setTag( "pet", cVariant( pMount->serial() ) );
		pMountItem->update();

		// if this is a gm lets tame the animal in the process
		if ( isGM() )
		{
			pMount->setOwner( this );
			pMount->setTamed( true );
		}

		// remove it from screen!
		pMount->bark( Bark_Idle );
		pMount->removeFromView( false );
		pMount->fight( 0 );
		pMount->setStablemasterSerial( serial_ );
	}
	else if ( pMount->owner() == 0 )
	{
		socket->clilocMessage( 501263, 0, 0x3b2, 3, this ); // That mount does not look broken! You would have to tame it to ride it.
	}
	else
		socket->clilocMessage( 501264, 0, 0x3b2, 3, this ); // This isn't your mount; it refuses to let you ride.

	return true;
}
Exemplo n.º 25
0
	bool responsed( cUOSocket* socket, cUORxTarget* target )
	{
		if ( !isCharSerial( target->serial() ) )
		{
			socket->clilocMessage( 1005442 );
		}
		else
		{
			P_PLAYER leader = dynamic_cast<P_PLAYER>( World::instance()->findChar( this->player ) );
			P_CHAR character = World::instance()->findChar( target->serial() );
			P_NPC npc = dynamic_cast<P_NPC>( character );
			P_PLAYER player = dynamic_cast<P_PLAYER>( character );

			if ( !leader || ( leader->party() && leader->party()->leader() != leader ) )
			{
				socket->clilocMessage( 1005453 );
			}
			else if ( leader->party() && leader->party()->members().count() + leader->party()->canidates().count() >= 10 )
			{
				socket->clilocMessage( 1008095 );
				// NPC targetted
			}
			else if ( npc )
			{
				if ( npc->isHuman() )
					socket->clilocMessage( 1005443, 0, npc->saycolor(), 3, npc );
				else
					socket->clilocMessage( 1005444 );
			}
			else if ( leader == player )
			{
				socket->clilocMessage( 1005439 );
			}
			else if ( player && player->party() && player->party() == leader->party() )
			{
				socket->clilocMessage( 1005440 );
			}
			else if ( player && leader->party() && leader->party()->canidates().contains( player ) )
			{
				socket->clilocMessage( 1005440 );
			}
			else if ( player && player->party() )
			{
				socket->clilocMessage( 1005441 );
			}
			else if ( player && player->socket() )
			{
				if ( !leader->party() )
				{
					new cParty( leader );
					leader->party()->update();
				}

				player->socket()->clilocMessageAffix( 1008089, 0, leader->name(), 0x3b2, 3, 0, false, true );
				leader->party()->addCanidate( player );
				socket->log( LOG_TRACE, tr( "Invited '%1' to join his party.\n" ).arg( player->account()->login() ) );

				// Send a party invitation request
				cUOTxPartyInvitation invitation;
				invitation.setSerial( leader->serial() );
				player->socket()->send( &invitation );

				// Attach a tempeffect that'll cancel the invitation after ten seconds
				Timers::instance()->insert( new cPartyCancelInvitation( leader->serial(), player->serial() ) );
			}
		}

		return true;
	}
Exemplo n.º 26
0
void cSkills::RandomSteal( cUOSocket* socket, SERIAL victim )
{
	P_PLAYER pChar = socket->player();
	P_CHAR pVictim = FindCharBySerial( victim );

	if ( !pVictim || !pChar )
		return;

	if ( pVictim->serial() == pChar->serial() )
	{
		socket->sysMessage( tr( "Why don't you simply take it?" ) );
		return;
	}

	/*	if( pVictim->npcaitype() == 17 )
		{
			socket->sysMessage( tr( "You cannot steal from Playervendors." ) );
			return;
		}
	*/
	if ( pVictim->objectType() == enPlayer )
	{
		P_PLAYER pp = dynamic_cast<P_PLAYER>( pVictim );
		if ( pp->isGMorCounselor() )
			socket->sysMessage( tr( "You can't steal from game masters." ) );
		return;
	}

	if ( !pChar->inRange( pVictim, 1 ) )
	{
		socket->sysMessage( tr( "You are too far away to steal from that person." ) );
		return;
	}

	P_ITEM pBackpack = pVictim->getBackpack();

	if ( !pBackpack )
	{
		socket->sysMessage( tr( "Bad luck, your victim doesn't have a backpack." ) );
		return;
	}

	float maxWeight = ( float ) QMIN( 1, pChar->skillValue( STEALING ) ); // We can steal max. 10 Stones when we are a GM
	// 1000 Skill == 100 Weight == 10 Stones

	QPtrList<cItem> containment = pBackpack->getContainment();
	Q_UINT32 chance = containment.count();

	P_ITEM pItem = containment.first();
	P_ITEM pToSteal = 0;
	bool sawOkItem = false;

	while ( !pToSteal )
	{
		// We have nothing that could be stolen?
		if ( !pItem && !sawOkItem )
		{
			socket->sysMessage( tr( "Your victim posesses nothing you could steal." ) );
			return;
		}
		// Jump back to the beginning
		else if ( !pItem && sawOkItem )
		{
			pItem = containment.first();
		}

		// Check if our chance becomes true (no spellbooks!)
		if ( pItem->totalweight() <= maxWeight && !pItem->isLockedDown() && !pItem->newbie() && pItem->type() != 9 )
		{
			sawOkItem = true; // We have items that could be stolen (just in case we reach the end of our list)

			// We have the chance of 1/chance that we reached our desired item
			if ( RandomNum( 1, ( int )chance ) == ( int )chance )
			{
				pToSteal = pItem;
				break;
			}
		}

		pItem = containment.next();
	}

	socket->sysMessage( tr( "You reach into %1's backpack and try to steal something..." ).arg( pVictim->name() ) );

	// The success of our Theft depends on the weight of the stolen item
	bool success = pChar->checkSkill( STEALING, 0, ( long int )pToSteal->weight() );
	bool caught = false;

	if ( success )
	{
		socket->sysMessage( tr( "You successfully steal %1." ).arg( pToSteal->getName() ) );
		P_ITEM pPack = pChar->getBackpack();
		pPack->addItem( pToSteal );
		// Update item onyl if still existent
		if ( !pToSteal->free )
			pToSteal->update();

		caught = pChar->skillValue( STEALING ) < rand() % 1001;
	}
	else
	{
		socket->sysMessage( tr( "You fail to steal the item." ) );

		// 1 in 5 Chance if we failed
		caught = RandomNum( 1, 5 ) == 1;
	}

	// Did we get caught?
	if ( caught )
	{
		socket->sysMessage( tr( "You have been cought!" ) );

		// Human non red NPCs need special handling
		if ( pVictim->objectType() == enNPC && pVictim->isInnocent() && pVictim->isHuman() )
		{
			P_NPC pn = dynamic_cast<P_NPC>( pVictim );
			pVictim->talk( tr( "Guards! A thief is amoung us!" ), 0xFFFF, 0x09 );
			if ( pVictim->region() && pVictim->region()->isGuarded() )
				pn->callGuards();
		}

		if ( pVictim->notoriety( pChar ) == 0x01 )
			pChar->makeCriminal();

		// Our Victim always notices it.
		if ( pVictim->objectType() == enPlayer )
		{
			P_PLAYER pp = dynamic_cast<P_PLAYER>( pVictim );
			if ( pp->socket() )
				pp->socket()->showSpeech( pChar, tr( "You notice %1 trying to steal %2 from you." ).arg( pChar->name() ).arg( pToSteal->getName( true ) ) );
		}

		QString message = tr( "You notice %1 trying to steal %2 from %3." ).arg( pChar->name() ).arg( pItem->getName() ).arg( pVictim->name() );

		for ( cUOSocket*mSock = Network::instance()->first(); mSock; mSock = Network::instance()->next() )
		{
			// Everyone within 7 Tiles notices us
			if ( mSock != socket && mSock->player() && mSock->player()->serial() != pVictim->serial() && mSock->player()->inRange( pChar, 7 ) )
				mSock->showSpeech( pChar, message );
		}
	}
}
Exemplo n.º 27
0
/*!
	This handles if a character actually tries to walk (NPC & Player)
*/
bool cMovement::Walking( P_CHAR pChar, Q_UINT8 dir, Q_UINT8 sequence )
{
	if ( !pChar )
		return false;

	// Scripting
	if ( pChar->onWalk( dir, sequence ) )
		return false;

	/*	if( !isValidDirection( dir ) )
		{
			pChar->setPathNum( pChar->pathnum() + PATHNUM );
			return;
		}*/

	P_PLAYER player = dynamic_cast<P_PLAYER>( pChar );

	// Is the sequence in order ?
	if ( player && player->socket() && !verifySequence( player->socket(), sequence ) )
		return false;

	// If checking for weight is more expensive, shouldn't we check for frozen first?
	if ( pChar->isFrozen() )
	{
		if ( player && player->socket() )
			player->socket()->denyMove( sequence );
		return false;
	}

	// save our original location before we even think about moving
	const Coord_cl oldpos( pChar->pos() );

	// If the Direction we're moving to is different from our current direction
	// We're turning and NOT moving into a specific direction
	// Clear the running flag here (!)
	// If the direction we're moving is already equal to our current direction
	bool running = dir & 0x80;
	dir = dir & 0x7F; // Remove the running flag

	pChar->setRunning(running);

	bool turning = dir != pChar->direction();

	// This happens if we're moving
	if ( !turning )
	{
		// Note: Do NOT use the copy constructor as it'll create a reference
		Coord_cl newCoord = calcCoordFromDir( dir, pChar->pos() );

		// Check if the stamina parameters
		if ( player && !consumeStamina( player, running ) )
		{
			if ( player->socket() )
				player->socket()->denyMove( sequence );
			return false;
		}

		// Check for Characters in our way
		if ( !checkObstacles( pChar, newCoord, running ) )
		{
			if ( player && player->socket() )
				player->socket()->denyMove( sequence );
			return false;
		}

		// Check if the char can move to those new coordinates
		// It is going to automatically calculate the new coords (!)
		if ( !mayWalk( pChar, newCoord ) )
		{
			if ( player && player->socket() )
				player->socket()->denyMove( sequence );
			return false;
		}
		else
		{
			if ( player && player->socket() )
				player->socket()->allowMove( sequence );
		}

		// Check if we're going to collide with characters
		if ( !player && CheckForCharacterAtXYZ( pChar, newCoord ) )
		{
			P_NPC npc = dynamic_cast<P_NPC>( pChar );
			if ( npc )
			{
				npc->clearPath();
			}
			return false;
		}

		// We moved so let's update our location
		pChar->moveTo( newCoord );
		pChar->setStepsTaken( pChar->stepsTaken() + 1 );
		pChar->setLastMovement( Server::instance()->time() );
		checkStealth( pChar ); // Reveals the user if neccesary
	}
	else
	{
		if ( player && player->socket() )
			player->socket()->allowMove( sequence );
	}

	// do all of the following regardless of whether turning or moving i guess
	// set the player direction to contain only the cardinal direction bits
	pChar->setDirection( dir );

	RegionIterator4Chars ri( pChar->pos() );
	for ( ri.Begin(); !ri.atEnd(); ri++ )
	{
		P_CHAR observer = ri.GetData();

		if ( observer == pChar )
		{
			continue;
		}

		unsigned int distance = observer->pos().distance( oldpos );

		// If we are a player, send us new characters
		if ( player && player->socket() )
		{
			if ( distance > player->visualRange() )
			{
				player->socket()->sendChar( observer ); // We were previously out of range.
			}
		}

		// Send our movement to the observer
		P_PLAYER otherplayer = dynamic_cast<P_PLAYER>( observer );

		if ( otherplayer && otherplayer->socket() )
		{
			if ( distance > otherplayer->visualRange() )
			{
				otherplayer->socket()->sendChar( pChar ); // Previously we were out of range
			}
			else
			{
				otherplayer->socket()->updateChar( pChar ); // Previously we were already known
			}
		}
	}

	// If we really moved handle teleporters and new items
	if ( !turning )
	{
		handleItems( pChar, oldpos );
		handleTeleporters( pChar, oldpos );
	}

	return true;
}
static P_CHAR findBestTarget( P_NPC npc )
{
	int targetAttract = -1;
	P_CHAR target = 0;

	// Search for targets in our list of current targets first
	QPtrList<cFightInfo> fights = npc->fights();
	for ( cFightInfo*info = fights.first(); info; info = fights.next() )
	{
		P_CHAR victim = info->victim();
		if ( victim == npc )
		{
			victim = info->attacker();
		}

		// We don't already attack the target, right?
		if ( victim != target )
		{
			// See if it's a target we want
			unsigned int dist = npc->dist(victim);
			int attract = (victim->strength() + victim->skillValue(TACTICS) / 10) / (wpMin<unsigned int>(65535, dist) + 1);
			if ( attract > targetAttract && validTarget( npc, victim, dist ) ) {
				target = victim;
				targetAttract = attract;
			}
		}
	}

	/*
		Attack the target with the highest ((Strength + Tactics) / Distance) value.
	*/

	// If we're not tamed, we attack other players as well.
	if ( !npc->isTamed() )
	{
		MapCharsIterator ri = MapObjects::instance()->listCharsInCircle( npc->pos(), VISRANGE );
		for ( P_CHAR pChar = ri.first(); pChar; pChar = ri.next() )
		{
			// We limit ourself to players and pets owned by players.
			P_PLAYER victim = dynamic_cast<P_PLAYER>( pChar );
			P_NPC npcVictim = dynamic_cast<P_NPC>( pChar );

			// We don't already attack the target, right?
			if ( victim && victim != target )
			{
				// See if it's a target we want
				unsigned int dist = npc->dist(victim);
				int attract = (victim->strength() + victim->skillValue(TACTICS) / 10) / (wpMin<unsigned int>(65535, dist) + 1);
				if ( attract > targetAttract && validTarget( npc, victim, dist ) ) {
					target = victim;
					targetAttract = attract;
				}
			}
			else if ( npcVictim && npcVictim->owner() && npcVictim != target )
			{
				// See if it's a target we want
				unsigned int dist = npc->dist(victim);
				int attract = (npcVictim->strength() + npcVictim->skillValue(TACTICS) / 10) / (wpMin<unsigned int>(65535, dist) + 1);
				if ( attract > targetAttract && validTarget( npc, npcVictim, dist ) ) {
					target = npcVictim;
					targetAttract = attract;
				}
			}
		}
	}

	return target;
}
Exemplo n.º 29
0
void Human_Guard_Called::init( P_NPC npc )
{
	npc->setSummonTime( Server::instance()->time() + MY_CLOCKS_PER_SEC * Config::instance()->guardDispelTime() );
	npc->setSummoned( true );
	AbstractAI::init( npc );
}
Exemplo n.º 30
0
void cPlayer::mount( P_NPC pMount )
{
	if ( !pMount )
		return;

	cUOSocket* socket = this->socket();
	if ( !inRange( pMount, 2 ) && !isGM() )
	{
		if ( socket )
			socket->sysMessage( tr( "You are too far away to mount!" ) );
		return;
	}

	if ( pMount->owner() == this || isGM() )
	{
		unmount();

		P_ITEM pMountItem = new cItem;
		pMountItem->Init();
		pMountItem->setId( 0x915 );
		pMountItem->setColor( pMount->skin() );

		switch ( static_cast<unsigned short>( pMount->body() & 0x00FF ) )
		{
		case 0xC8:
			pMountItem->setId( 0x3E9F ); break; // Horse
		case 0xE2:
			pMountItem->setId( 0x3EA0 ); break; // Horse
		case 0xE4:
			pMountItem->setId( 0x3EA1 ); break; // Horse
		case 0xCC:
			pMountItem->setId( 0x3EA2 ); break; // Horse
		case 0xD2:
			pMountItem->setId( 0x3EA3 ); break; // Desert Ostard
		case 0xDA:
			pMountItem->setId( 0x3EA4 ); break; // Frenzied Ostard
		case 0xDB:
			pMountItem->setId( 0x3EA5 ); break; // Forest Ostard
		case 0xDC:
			pMountItem->setId( 0x3EA6 ); break; // LLama
		case 0x34:
			pMountItem->setId( 0x3E9F ); break; // Brown Horse
		case 0x4E:
			pMountItem->setId( 0x3EA0 ); break; // Grey Horse
		case 0x50:
			pMountItem->setId( 0x3EA1 ); break; // Tan Horse
		case 0x74:
			pMountItem->setId( 0x3EB5 ); break; // Nightmare
		case 0x75:
			pMountItem->setId( 0x3EA8 ); break; // Silver Steed
		case 0x72:
			pMountItem->setId( 0x3EA9 ); break; // Dark Steed
		case 0x7A:
			pMountItem->setId( 0x3EB4 ); break; // Unicorn
		case 0x84:
			pMountItem->setId( 0x3EAD ); break; // Kirin
		case 0x73:
			pMountItem->setId( 0x3EAA ); break; // Etheral
		case 0x76:
			pMountItem->setId( 0x3EB2 ); break; // War Horse-Brit
		case 0x77:
			pMountItem->setId( 0x3EB1 ); break; // War Horse-Mage Council
		case 0x78:
			pMountItem->setId( 0x3EAF ); break; // War Horse-Minax
		case 0x79:
			pMountItem->setId( 0x3EB0 ); break; // War Horse-Shadowlord
		case 0xAA:
			pMountItem->setId( 0x3EAB ); break; // Etheral LLama
		case 0x3A:
			pMountItem->setId( 0x3EA4 ); break; // Forest Ostard
		case 0x39:
			pMountItem->setId( 0x3EA3 ); break; // Desert Ostard
		case 0x3B:
			pMountItem->setId( 0x3EA5 ); break; // Frenzied Ostard
		case 0x90:
			pMountItem->setId( 0x3EB3 ); break; // Seahorse
		case 0xAB:
			pMountItem->setId( 0x3EAC ); break; // Etheral Ostard
		case 0xBB:
			pMountItem->setId( 0x3EB8 ); break; // Ridgeback
		case 0x17:
			pMountItem->setId( 0x3EBC ); break; // giant beetle
		case 0x19:
			pMountItem->setId( 0x3EBB ); break; // skeletal mount
		case 0x1a:
			pMountItem->setId( 0x3EBD ); break; // swamp dragon
		case 0x1f:
			pMountItem->setId( 0x3EBE ); break; // armor dragon
		}

		this->addItem( cBaseChar::Mount, pMountItem );
		pMountItem->setTag( "pet", cVariant( pMount->serial() ) );
		pMountItem->update();

		// if this is a gm lets tame the animal in the process
		if ( isGM() )
		{
			pMount->setOwner( this );
		}

		// remove it from screen!
		pMount->bark( Bark_Idle );
		pMount->removeFromView( false );
		pMount->fight( 0 );
		pMount->setStablemasterSerial( serial_ );
	}
	else
		socket->sysMessage( tr( "You dont own that creature." ) );
}