// Tries to equip an item // if that fails it tries to put the item in the users backpack // if *that* fails it puts it at the characters feet // That works for NPCs as well void equipItem( P_CHAR wearer, P_ITEM item ) { tile_st tile = TileCache::instance()->getTile( item->id() ); // User cannot wear the item if ( tile.layer == 0 ) { if ( wearer->objectType() == enPlayer ) { P_PLAYER pp = dynamic_cast<P_PLAYER>( wearer ); if ( pp->socket() ) pp->socket()->sysMessage( tr( "You cannot wear that item." ) ); } item->toBackpack( wearer ); return; } cBaseChar::ItemContainer container = wearer->content(); cBaseChar::ItemContainer::const_iterator it( container.begin() ); for ( ; it != container.end(); ++it ) { P_ITEM equip = *it; // Unequip the item and free the layer that way if ( equip && ( equip->layer() == tile.layer ) ) equip->toBackpack( wearer ); } // *finally* equip the item wearer->addItem( static_cast<cBaseChar::enLayer>( item->layer() ), item ); }
/*! Sends custom house to client */ static PyObject* wpMulti_sendcustomhouse( wpMulti* self, PyObject* args ) { Q_UNUSED(args); if( !self->pMulti || self->pMulti->free || !self->pMulti->ishouse() ) return PyFalse; if( !checkArgChar( 0 ) ) { PyErr_BadArgument(); return NULL; } P_PLAYER player = dynamic_cast<P_PLAYER>( getArgChar( 0 ) ); if ( !player ) return PyFalse; // self->pMulti->sendCH( player->socket() ); cUOTxAskCustomHouse askch; askch.setSerial( self->pMulti->serial() ); askch.setId( self->pMulti->revision() ); player->socket()->send( &askch ); return PyTrue; }
void DragAndDrop::dropOnGround( cUOSocket* socket, P_ITEM pItem, const Coord_cl& pos ) { P_PLAYER pChar = socket->player(); // Check if the destination is in line of sight if ( !pChar->lineOfSight( pos.losItemPoint(pItem->id()) ) ) { socket->bounceItem( pItem, BR_OUT_OF_SIGHT ); return; } if ( !pChar->canPickUp( pItem ) ) { socket->bounceItem( pItem, BR_CANNOT_PICK_THAT_UP ); return; } if ( pItem->onDropOnGround( pos ) ) { // We're still dragging something if ( socket->dragging() ) socket->bounceItem( socket->dragging(), BR_NO_REASON ); return; } pItem->removeFromCont(); pItem->moveTo( pos ); pItem->update(); // Play Sounds for non gold items if (pItem->id() != 0xEED) { pItem->soundEffect(0x42); } }
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!" ) ); } } } }
void cMovement::handleTeleporters( P_CHAR pc, const Coord& oldpos ) { cTerritory* territory = pc->region(); if ( !territory ) Territories::instance()->check( pc ); if ( territory && pc->pos() != oldpos ) { if ( territory->haveTeleporters() ) { Coord destination = pc->pos(); if ( territory->findTeleporterSpot( destination ) ) { bool quick = pc->pos().map != destination.map; pc->removeFromView( false ); pc->moveTo( destination ); pc->resend( false ); P_PLAYER player = dynamic_cast<P_PLAYER>( pc ); if ( player && player->socket() ) { player->socket()->resendPlayer( quick ); player->socket()->resendWorld(); } } } } }
float Animal_Wild_Flee::postCondition() { /* * Fleeing from an approaching player has the following postconditions: * - There is no character in flight range. * - There is an character attacking us. * - Our owner has come in range. * */ if ( m_npc->attackTarget() ) return 1.0f; bool found = false; MapCharsIterator ri = MapObjects::instance()->listCharsInCircle( m_npc->pos(), Config::instance()->animalWildFleeRange() ); for ( P_CHAR pChar = ri.first(); pChar; pChar = ri.next() ) { P_PLAYER pPlayer = dynamic_cast<P_PLAYER>( pChar ); if ( pPlayer && !pPlayer->free && !pPlayer->isGMorCounselor() && !pPlayer->isHidden() && !pPlayer->isInvisible() ) found = true; if ( pPlayer && m_npc->owner() == pPlayer ) return 1.0f; } if ( found ) return 0.0f; return 1.0f; }
static void playerRegisterAfterLoading( P_PLAYER pc ) { if ( pc->account() == 0 ) { // We need to remove the equipment here. cBaseChar::ItemContainer container( pc->content() ); cBaseChar::ItemContainer::const_iterator it( container.begin() ); cBaseChar::ItemContainer::const_iterator end( container.end() ); for ( ; it != end; ++it ) { P_ITEM pItem = *it; if ( !pItem ) continue; pItem->remove(); } pc->del(); return; } /* else { pc->setBody(0x0190); Console::instance()->send("player: %s with bugged body-value detected, restored to male shape\n",pc->name().latin1()); }*/ }
cParty::~cParty() { P_PLAYER member; for ( member = members_.first(); member; member = members_.next() ) { member->setParty( 0 ); if ( member->socket() ) { cUOTxPartyRemoveMember updateparty; updateparty.setSerial( member->serial() ); member->socket()->send( &updateparty ); member->socket()->clilocMessage( 1005449 ); } } for ( member = canidates_.first(); member; member = canidates_.next() ) { if ( member->socket() ) { cUOTxPartyRemoveMember updateparty; updateparty.setSerial( member->serial() ); member->socket()->send( &updateparty ); member->socket()->clilocMessage( 1005449 ); } } }
float Animal_Wild_Flee::postCondition() { /* * Fleeing from an approaching player has the following postconditions: * - There is no character in flight range. * - There is an character attacking us. * - Our owner has come in range. * */ if( m_npc->attackTarget() ) return 1.0f; RegionIterator4Chars ri( m_npc->pos(), SrvParams->animalWildFleeRange() ); bool found = false; for(ri.Begin(); !ri.atEnd(); ri++) { P_PLAYER pPlayer = dynamic_cast<P_PLAYER>(ri.GetData()); if( pPlayer && !pPlayer->free && !pPlayer->isGMorCounselor() && !pPlayer->isHidden() && !pPlayer->isInvisible() ) found = true; if( pPlayer && m_npc->owner() == pPlayer ) return 1.0f; } if( found ) return 0.0f; return 1.0f; }
void cNewMagic::execSpell( P_CHAR pMage, UINT8 spell, UINT8 type, cUORxTarget* target ) { stNewSpell *sInfo = findSpell( spell ); P_PLAYER pp = dynamic_cast<P_PLAYER>(pMage); if( ( ( pp || !pp->isGM() ) && !checkReagents( pMage, spell ) ) || !useMana( pMage, spell ) ) { pMage->setCasting( false ); return; } if( !pp || !pp->isGM() ) useReagents( pMage, spell ); if( !checkSkill( pMage, spell, false ) ) { disturb( pMage, true, -1 ); return; } // Call the Spell Effect for this Spell if( sInfo->script ) sInfo->script->onSpellSuccess( pMage, spell, type, target ); // End Casting pMage->setCasting( false ); }
// Main Command processing function void cCommands::process( cUOSocket *socket, const QString &command ) { if( !socket->player() ) return; P_PLAYER pChar = socket->player(); QStringList pArgs = QStringList::split( " ", command, true ); // No Command? No Processing if( pArgs.isEmpty() ) return; QString pCommand = pArgs[0].upper(); // First element should be the command // Remove it from the argument list pArgs.erase( pArgs.begin() ); // Check if the priviledges are ok if( !pChar->account()->authorized("command", pCommand.latin1() )) { socket->sysMessage( tr( "Access to command '%1' was denied" ).arg( pCommand.lower() ) ); socket->log( QString("Access to command '%1' was denied\n").arg(pCommand.lower()) ); return; } // Dispatch the command if ( dispatch( socket, pCommand, pArgs ) ) socket->log( QString( "Used command '%1'.\n" ).arg( command ) ); }
/*! Sends items which came in range and handles collisions with teleporters or damaging items. */ void handleItems( P_CHAR pChar, const Coord& oldpos ) { P_PLAYER player = dynamic_cast<P_PLAYER>( pChar ); MapItemsIterator iter = MapObjects::instance()->listItemsInCircle( pChar->pos(), VISRANGE ); for ( P_ITEM pItem = iter.first(); pItem; pItem = iter.next() ) { // Check for item collisions here. if ( pChar->pos().x == pItem->pos().x && pChar->pos().y == pItem->pos().y ) { if ( pItem->pos().z >= pChar->pos().z - 15 && pItem->pos().z <= pChar->pos().z + 15 ) { if ( handleItemCollision( pChar, pItem ) ) { break; } } } // If we are a connected player then send new items if ( player && player->socket() ) { UI32 oldDist = oldpos.distance( pItem->pos() ); if ( oldDist >= player->visualRange() ) { // was out of range before and now is in range pItem->update( player->socket() ); } } } }
float Animal_Wild_Flee::preCondition() { return 0.0f; /* * Fleeing from an approaching player has the following preconditions: * - There is a player within flight range. * - There is no character attacking us. * - Our owner is not in range. * */ if ( m_npc->attackTarget() ) return 0.0f; MapCharsIterator ri = MapObjects::instance()->listCharsInCircle( m_npc->pos(), Config::instance()->animalWildFleeRange() ); for ( P_CHAR pChar = ri.first(); pChar; pChar = ri.next() ) { P_PLAYER pPlayer = dynamic_cast<P_PLAYER>( pChar ); if ( pPlayer && !pPlayer->free && !pPlayer->isGMorCounselor() && !pPlayer->isHidden() && !pPlayer->isInvisible() ) { pFleeFromSer = pPlayer->serial(); } if ( pPlayer && m_npc->owner() == pPlayer ) return 0.0f; } if ( pFleeFromSer != INVALID_SERIAL ) return 1.0f; return 0.0f; }
// 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; }
/*! If source is 0 and silent is true, nothing happens. Otherwise the canidate is removed from the party without notification. */ void Dispel( P_CHAR /*source*/, bool silent ) { P_PLAYER player = dynamic_cast<P_PLAYER>( World::instance()->findChar( destSer ) ); P_PLAYER leader = dynamic_cast<P_PLAYER>( World::instance()->findChar( this->leader ) ); if ( leader && leader->party() && !silent ) leader->party()->removeMember( player ); }
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 ); } } }
void cParty::update() { cUOTxPartyUpdate update; for ( P_PLAYER player = members_.first(); player; player = members_.next() ) update.addMember( player->serial() ); send( &update ); }
void cDelayedHideChar::Expire() { P_PLAYER pc = dynamic_cast<P_PLAYER>(FindCharBySerial( destSer )); if( !pc || pc->socket() ) // break if the char has relogged in the meantime return; pc->setHidden( 1 ); pc->resend( true ); }
void cParty::send( P_PLAYER from, P_PLAYER target, const QString& message ) { cUOTxPartyTellMember tell; tell.setSerial( from->serial() ); tell.setText( message ); for ( P_PLAYER player = members_.first(); player; player = members_.next() ) if ( player == target && player->socket() ) player->socket()->send( &tell ); }
void cDragItems::dropItem( cUOSocket *socket, cUORxDropItem *packet ) { P_PLAYER pChar = socket->player(); if( !pChar ) return; // Get the data SERIAL contId = packet->cont(); Coord_cl dropPos = pChar->pos(); // plane dropPos.x = packet->x(); dropPos.y = packet->y(); dropPos.z = packet->z(); // Get possible containers P_ITEM pItem = FindItemBySerial( packet->serial() ); if( !pItem ) return; P_ITEM iCont = FindItemBySerial( packet->cont() ); P_CHAR cCont = FindCharBySerial( packet->cont() ); // >> SEE LORD BINARIES DROPFIX << // A completely invalid Drop packet if( !iCont && !cCont && ( dropPos.x == 0xFFFF ) && ( dropPos.y == 0xFFFF ) && ( (unsigned char)dropPos.z == 0xFF ) ) { socket->bounceItem( pItem, BR_NO_REASON ); return; } UINT32 weight = pChar->weight(); // Item dropped on Ground if( !iCont && !cCont ) dropOnGround( socket, pItem, dropPos ); // Item dropped on another item else if( iCont ) dropOnItem( socket, pItem, iCont, dropPos ); // Item dropped on char else if( cCont ) dropOnChar( socket, pItem, cCont ); // Handle the sound-effect if( pItem->id() == 0xEED ) goldsfx( socket, pItem->amount(), true ); // Update our weight. if( weight != pChar->weight() ) socket->sendStatWindow(); }
// 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); } } }
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; }
///////////////// // 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; }
/* \method account.removecharacter \param player The player that should be removed from this account. \description Removes a player from this account. */ static PyObject* wpAccount_removecharacter( wpAccount* /*self*/, PyObject* args ) { if ( !checkArgChar( 0 ) ) { PyErr_BadArgument(); return 0; } P_PLAYER pChar = dynamic_cast<P_PLAYER>( getArgChar( 0 ) ); if ( pChar ) { pChar->setAccount( 0 ); } Py_RETURN_TRUE; }
bool cSetTarget::responsed( cUOSocket* socket, cUORxTarget* target ) { P_CHAR pChar = FindCharBySerial( target->serial() ); P_ITEM pItem = FindItemBySerial( target->serial() ); cUObject* pObject = NULL; if ( pItem ) pObject = pItem; else if ( pChar ) pObject = pChar; // Only characters and items if ( !pObject ) { socket->sysMessage( tr( "Please select a valid character or item" ) ); return true; } // check for rank if ( pChar && pChar->objectType() == enPlayer ) { P_PLAYER pp = dynamic_cast<P_PLAYER>( pChar ); if ( pp->account()->rank() >= socket->player()->account()->rank() && pp != socket->player() ) { socket->sysMessage( tr( "Better do not try that!" ) ); return true; } } cVariant value( this->value ); stError* error = pObject->setProperty( key, value ); if ( error ) { socket->sysMessage( error->text ); delete error; } if ( pChar ) pChar->resend(); else if ( pItem ) pItem->update(); return true; }
virtual void handleResponse( cUOSocket *socket, const gumpChoice_st& choice ) { P_PLAYER player = socket->player(); if( !player ) return; P_CHAR pChar = FindCharBySerial( choice.button ); if( !pChar || pChar->dist( player ) > 32 ) return; // Start the refresh-timer // Start the wearoff-timer player->setTrackingTime( uiCurrentTime + ( 30 * MY_CLOCKS_PER_SEC ) ); TempEffects::instance()->insert( new cRefreshTracking( player->serial(), choice.button ) ); }
void cDelayedHeal::Expire() { P_CHAR pSource = FindCharBySerial( destSer ); P_CHAR pTarget = FindCharBySerial( sourSer ); if( !pSource || !pTarget ) return; if( !pSource->inRange( pTarget, 5 ) ) { if( pSource->objectType() == enPlayer ) { P_PLAYER pp = dynamic_cast<P_PLAYER>(pSource); if( pp->socket() ) pp->socket()->sysMessage( tr( "You are standing too far away to apply any bandages." ) ); } return; } }
// Refresh the quest-arrow // Until our target expires virtual void Expire() { P_PLAYER pChar = dynamic_cast<P_PLAYER>(FindCharBySerial( tracker_ )); if( !pChar || !pChar->socket() ) return; P_CHAR pTarget = FindCharBySerial( target_ ); // Disable the quest-arrow if( !pTarget || pChar->trackingTime() <= uiCurrentTime ) { pChar->socket()->sendQuestArrow( false, 0, 0 ); return; } pChar->socket()->sendQuestArrow( true, pTarget->pos().x, pTarget->pos().y ); TempEffects::instance()->insert( new cRefreshTracking( tracker_, target_ ) ); }
void cDragItems::dropOnGround( cUOSocket *socket, P_ITEM pItem, const Coord_cl &pos ) { P_PLAYER pChar = socket->player(); // Check if the destination is in line of sight if( !lineOfSight( pChar->pos(), pos, WALLS_CHIMNEYS|DOORS|LAVA_WATER ) ) { socket->bounceItem( pItem, BR_OUT_OF_SIGHT ); return; } if( !pChar->canPickUp( pItem ) ) { socket->bounceItem( pItem, BR_CANNOT_PICK_THAT_UP ); return; } if( pItem->onDropOnGround( pos ) ) { // We're still dragging something if( socket->dragging() ) socket->bounceItem( socket->dragging(), BR_NO_REASON ); return; } pItem->removeFromCont(); pItem->moveTo( pos ); pItem->update(); if( pItem->priv() & 0x01 ) pItem->startDecay(); // Multi handling // Has it been dropped into a multi cMulti* pMulti = cMulti::findMulti( pos ); if( pMulti ) { pMulti->addItem( pItem ); } }
/*! Sends multis which came in range and handles collisions with them. */ void handleMultis( P_CHAR pChar, const Coord& oldpos ) { P_PLAYER player = dynamic_cast<P_PLAYER>( pChar ); MapMultisIterator multis = MapObjects::instance()->listMultisInCircle( pChar->pos(), BUILDRANGE ); for ( P_MULTI multi = multis.first(); multi; multi = multis.next() ) { // TODO: handle multi collisions here. // If we are a connected player then send new multis if ( player && player->socket() ) { UI32 oldDist = oldpos.distance( multi->pos() ); if ( oldDist >= BUILDRANGE ) { // was out of range before and now is in range multi->update( player->socket() ); } } } }