示例#1
0
bool CChar::NPC_StablePetRetrieve( CChar * pCharPlayer )
{
	ADDTOCALLSTACK("CChar::NPC_StablePetRetrieve");
	// Get pets for this person from my inventory.
	// May want to put up a menu ???

	if ( !m_pNPC || m_pNPC->m_Brain != NPCBRAIN_STABLE )
		return false;

	int iCount = 0;
	CItem *pItemNext = NULL;
	for ( CItem *pItem = GetBank()->GetContentHead(); pItem != NULL; pItem = pItemNext )
	{
		pItemNext = pItem->GetNext();
		if ( pItem->IsType(IT_FIGURINE) && pItem->m_uidLink == pCharPlayer->GetUID() )
		{
			if ( !pCharPlayer->Use_Figurine(pItem) )
			{
				tchar *pszTemp = Str_GetTemp();
				sprintf(pszTemp, g_Cfg.GetDefaultMsg(DEFMSG_NPC_STABLEMASTER_CLAIM_FOLLOWER), pItem->GetName());
				Speak(pszTemp);
				return true;
			}

			pItem->Delete();
			iCount++;
		}
	}

	Speak(g_Cfg.GetDefaultMsg((iCount > 0) ? DEFMSG_NPC_STABLEMASTER_CLAIM : DEFMSG_NPC_STABLEMASTER_CLAIM_NOPETS));
	return true;
}
示例#2
0
CItemMulti::~CItemMulti()
{
	MultiUnRealizeRegion();	// unrealize before removed from ground.
	DeletePrepare();	// Must remove early because virtuals will fail in child destructor.
	// NOTE: ??? This is dangerous to iterators. The "next" item may no longer be valid !

	// Attempt to remove all the accessory junk.
	// NOTE: assume we have already been removed from Top Level

	if ( ! m_pRegion )
		return;

	CWorldSearch Area( m_pRegion->m_pt, Multi_GetMaxDist() );	// largest area.
	while (true)
	{
		CItem * pItem = Area.GetItem();
		if ( pItem == NULL )
			break;
		if ( pItem == this )	// this gets deleted seperately.
			continue;
		if ( ! Multi_IsPartOf( pItem ))
			continue;
		pItem->Delete();	// delete the key id for the door/key/sign.
	}

	delete m_pRegion;
}
示例#3
0
文件: trade.cpp 项目: bholtsclaw/uox3
bool clearTradesFunctor( CBaseObject *a, UI32 &b, void *extraData )
{
	bool retVal = true;
	if( ValidateObject( a ) && a->CanBeObjType( OT_ITEM ) )
	{
		// Body of the functor goes here
		CItem *i = static_cast< CItem * >(a);
		if( ValidateObject( i ) )
		{
			if( i->GetType() == IT_TRADEWINDOW )
			{
				CChar *k = FindItemOwner( i );
				if( ValidateObject( k ) )
				{
					CItem *p = k->GetPackItem();
					if( ValidateObject( p ) )
					{
						CDataList< CItem * > *iCont = i->GetContainsList();
						for( CItem *j = iCont->First(); !iCont->Finished(); j = iCont->Next() )
						{
							if( ValidateObject( j ) )
								j->SetCont( p );
						}
					}
				}
				i->Delete();
				++b;	// let's track how many we cleared
			}
		}
	}
	return retVal;
}
示例#4
0
//o--------------------------------------------------------------------------o
//|	Function		-	Cleanup( void )
//|	Date			-	26th September, 2001
//|	Programmer		-	Abaddon
//|	Modified		-
//o--------------------------------------------------------------------------o
//|	Purpose			-	Makes sure that any items and chars inside the multi
//|						are removed
//o--------------------------------------------------------------------------o
void CMultiObj::Cleanup( void )
{
	for( CItem *iRemove = itemInMulti.First(); !itemInMulti.Finished(); iRemove = itemInMulti.Next() )
	{
		if( ValidateObject( iRemove ) )
		{
			ItemTypes iType = iRemove->GetType();
			if( iType == IT_DOOR || iType == IT_LOCKEDDOOR || iType == IT_HOUSESIGN )
				iRemove->Delete();
			else
			{
				if( iRemove->IsLockedDown() )
					iRemove->SetMovable( 1 );
				iRemove->SetMulti( INVALIDSERIAL );
				iRemove->SetZ( GetZ() );
			}
		}
	}
	for( CChar *cRemove = charInMulti.First(); !charInMulti.Finished(); cRemove = charInMulti.Next() )
	{
		if( ValidateObject( cRemove ) )
		{
			cRemove->SetMulti( INVALIDSERIAL );
			cRemove->SetZ( GetZ() );
		}
	}
	CItem::Cleanup();
}
示例#5
0
文件: trade.cpp 项目: bholtsclaw/uox3
//o---------------------------------------------------------------------------o
//|   Function    :  CItem *startTrade( CSocket *mSock, CChar *nChar )
//|   Date        :  February 2, 2006
//|   Programmer  :  giwo
//o---------------------------------------------------------------------------o
//|   Purpose     :  Handles everything necesarry to start a secure trade
//o---------------------------------------------------------------------------o
CItem *startTrade( CSocket *mSock, CChar *nChar )
{
	if( mSock == NULL || !ValidateObject( nChar ) )
		return NULL;

	CChar *mChar	= mSock->CurrcharObj();
	CSocket *nSock	= nChar->GetSocket();

	if( !ValidateObject( mChar ) || nSock == NULL )
		return NULL;

	CItem *tradeWindowOne = CreateTradeWindow( mSock, nSock, mChar );
	if( !ValidateObject( tradeWindowOne ) )
		return NULL;

	CItem *tradeWindowTwo = CreateTradeWindow( nSock, mSock, nChar );
	if( !ValidateObject( tradeWindowTwo ) )
	{
		tradeWindowOne->Delete();
		return NULL;
	}

	const SERIAL tw1Serial = tradeWindowOne->GetSerial();
	const SERIAL tw2Serial = tradeWindowTwo->GetSerial();

	tradeWindowOne->SetTempVar( CITV_MOREX, tw2Serial );
	tradeWindowTwo->SetTempVar( CITV_MOREX, tw1Serial );

	CPSecureTrading cpstOne( (*nChar), tw1Serial, tw2Serial );
	cpstOne.Name( nChar->GetName() );
	mSock->Send( &cpstOne );
	
	CPSecureTrading cpstTwo( (*mChar), tw2Serial, tw1Serial );
	cpstTwo.Name( mChar->GetName() );
	nSock->Send( &cpstTwo );

	CPWornItem toWear = (*tradeWindowOne);
	mSock->Send( &toWear );
	nSock->Send( &toWear );

	CPWornItem toWear2 = (*tradeWindowTwo);
	mSock->Send( &toWear2 );
	nSock->Send( &toWear2 );

	return tradeWindowOne;
}
示例#6
0
void CSector::OnTick(int iPulseCount)
{
	ADDTOCALLSTACK_INTENSIVE("CSector::OnTick");
	// CWorld gives OnTick() to all CSectors.

	EXC_TRY("Tick");
	EXC_SET("light change");

	//	do not tick sectors on maps not supported by server
	if ( !g_MapList.m_maps[m_map] ) return;

	// Check for light change before putting the sector to sleep, since in other case the
	// world light levels will be shitty
	bool fEnvironChange = false;
	bool fLightChange = false;
	bool fSleeping = false;

	if ( ! ( iPulseCount & 0x7f ))	// 30 seconds or so.
	{
		// check for local light level change ?
		BYTE blightprv = m_Env.m_Light;
		m_Env.m_Light = GetLightCalc( false );
		if ( m_Env.m_Light != blightprv )
		{
			fEnvironChange = true;
			fLightChange = true;
		}
	}

	EXC_SET("sector sleeping?");
	size_t clients = m_Chars_Active.HasClients();

	if ( clients <= 0 ) // having no clients inside
	{
		// Put the sector to sleep if no clients been here in a while.
		fSleeping = IsSectorSleeping();
		if ( fSleeping )
		{
			if ( !g_Cfg.m_iSectorSleepMask )
				return;
			if (( iPulseCount & g_Cfg.m_iSectorSleepMask ) != ( GetIndex() & g_Cfg.m_iSectorSleepMask ))
				return;
		}
	}

	EXC_SET("sound effects");
	// random weather noises and effects.
	SOUND_TYPE sound = 0;
	bool fWeatherChange = false;
	int iRegionPeriodic = 0;

	if ( ! ( iPulseCount & 0x7f ))	// 30 seconds or so.
	{
		// Only do this every x minutes or so (TICK_PER_SEC)
		// check for local weather change ?
		WEATHER_TYPE weatherprv = m_Env.m_Weather;
		if ( ! Calc_GetRandVal( 30 ))	// change less often
		{
			m_Env.m_Weather = GetWeatherCalc();
			if ( weatherprv != m_Env.m_Weather )
			{
				fWeatherChange = true;
				fEnvironChange = true;
			}
		}

		// Random area noises. Only do if clients about.
		if ( clients > 0 )
		{
			iRegionPeriodic = 2;

			static const SOUND_TYPE sm_SfxRain[] = { 0x10, 0x11 };
			static const SOUND_TYPE sm_SfxWind[] = { 0x14, 0x15, 0x16 };
			static const SOUND_TYPE sm_SfxThunder[] = { 0x28, 0x29 , 0x206 };

			// Lightning ?	// wind, rain,
			switch ( GetWeather() )
			{
				case WEATHER_CLOUDY:
					break;

				case WEATHER_SNOW:
					if ( ! Calc_GetRandVal(5) )
						sound = sm_SfxWind[ Calc_GetRandVal( COUNTOF( sm_SfxWind )) ];
					break;

				case WEATHER_RAIN:
					{
						int iVal = Calc_GetRandVal(30);
						if ( iVal < 5 )
						{
							// Mess up the light levels for a sec..
							LightFlash();
							sound = sm_SfxThunder[ Calc_GetRandVal( COUNTOF( sm_SfxThunder )) ];
						}
						else if ( iVal < 10 )
							sound = sm_SfxRain[ Calc_GetRandVal( COUNTOF( sm_SfxRain )) ];
						else if ( iVal < 15 )
							sound = sm_SfxWind[ Calc_GetRandVal( COUNTOF( sm_SfxWind )) ];
					}
					break;

				default:
					break;
			}
		}
	}

	// regen all creatures and do AI

	ProfileTask charactersTask(PROFILE_CHARS);

	//pChar = STATIC_CAST <CChar*>( m_Chars_Active.GetHead());
	CChar * pCharNext = NULL;
	CChar * pChar = dynamic_cast <CChar*>( m_Chars_Active.GetHead());
	for ( ; pChar != NULL; pChar = pCharNext )
	{
		EXC_TRYSUB("TickChar");

		pCharNext = pChar->GetNext();
		if (( fEnvironChange ) && ( IsTrigUsed(TRIGGER_ENVIRONCHANGE) ))
			pChar->OnTrigger(CTRIG_EnvironChange, pChar);

		if ( pChar->IsClient())
		{
			CClient * pClient = pChar->GetClient();
			ASSERT( pClient );
			if ( sound )
				pClient->addSound(sound, pChar);

			if ( fLightChange && ! pChar->IsStatFlag( STATF_DEAD | STATF_NightSight ))
				pClient->addLight();

			if ( fWeatherChange )
				pClient->addWeather(GetWeather());

			if ( iRegionPeriodic && pChar->m_pArea )
			{
				if (( iRegionPeriodic == 2 )&&( IsTrigUsed(TRIGGER_REGPERIODIC) ))
				{
					pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_REGPERIODIC );
					iRegionPeriodic--;
				}
				if ( IsTrigUsed(TRIGGER_CLIPERIODIC) )
					pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_CLIPERIODIC );
			}
		}
		// Can only die on your own tick.
		if ( !pChar->OnTick() )
			pChar->Delete();

		EXC_CATCHSUB("Sector");

		EXC_DEBUGSUB_START;
		CPointMap pt = GetBasePoint();
		g_Log.EventDebug("char 0%lx '%s'\n", static_cast<DWORD>(pChar->GetUID()), pChar->GetName());
		g_Log.EventDebug("sector #%d [%d,%d,%d,%d]\n", GetIndex(),  pt.m_x, pt.m_y, pt.m_z, pt.m_map);
		EXC_DEBUGSUB_END;
	}

	// decay items on ground = time out spells / gates etc.. etc..
	// No need to check these so often !

	ProfileTask itemsTask(PROFILE_ITEMS);

	CItem * pItemNext = NULL;
	CItem * pItem = dynamic_cast <CItem*>( m_Items_Timer.GetHead());
	for ( ; pItem != NULL; pItem = pItemNext )
	{
		EXC_TRYSUB("TickItem");
		pItemNext = pItem->GetNext();

		EXC_SETSUB("TimerExpired");
		if ( pItem->IsTimerExpired() )
		{
			EXC_SETSUB("ItemTick");
			if ( !pItem->OnTick() )
			{
				EXC_SETSUB("ItemDelete");
				pItem->Delete();
			}
			else
			{
				EXC_SETSUB("TimerExpired2");
				if ( pItem->IsTimerExpired() )	// forgot to clear the timer.? strange.
				{
					EXC_SETSUB("SetTimeout");
					pItem->SetTimeout(-1);
				}
			}
		}

		EXC_SETSUB("UpdateFlags");
		pItem->OnTickStatusUpdate();

#ifdef _WIN32
		EXC_CATCHSUB("Sector");

		EXC_DEBUGSUB_START;
		CPointMap pt = GetBasePoint();
		g_Log.EventError("item 0%lx '%s' [timer=%lld, type=%lld]\n", static_cast<DWORD>(pItem->GetUID()), pItem->GetName(), pItem->GetTimerAdjusted(), static_cast<int>(pItem->GetType()));
		g_Log.EventError("sector #%d [%d,%d,%d,%d]\n", GetIndex(),  pt.m_x, pt.m_y, pt.m_z, pt.m_map);
		
		EXC_DEBUGSUB_END;
#else
		}
#ifndef _DEBUG
		catch ( const CGrayError& e )
示例#7
0
bool CChar::Use_Item_Web( CItem * pItemWeb )
{
	ADDTOCALLSTACK("CChar::Use_Item_Web");
	// IT_WEB
	// IT_EQ_STUCK
	// Try to break out of the web.
	// Or just try to damage it.
	//
	// RETURN: true = held in place.
	//  false = walk thru it.

	if ( GetDispID() == CREID_GIANT_SPIDER || !pItemWeb || !pItemWeb->IsTopLevel() || IsStatFlag(STATF_DEAD|STATF_Insubstantial) || IsPriv(PRIV_GM) )
		return false;	// just walk through it

	// Try to break it.
	int iStr = pItemWeb->m_itWeb.m_Hits_Cur;
	if ( iStr == 0 )
		iStr = pItemWeb->m_itWeb.m_Hits_Cur = 60 + Calc_GetRandVal(250);

	// Since broken webs become spider silk, we should get out of here now if we aren't in a web.
	CItem *pFlag = LayerFind(LAYER_FLAG_Stuck);
	if ( CanMove(pItemWeb, false) )
	{
		if ( pFlag )
			pFlag->Delete();
		return false;
	}

	if ( pFlag )
	{
		if ( pFlag->IsTimerSet() )	// don't allow me to try to damage it too often
			return true;
	}

	int iDmg = pItemWeb->OnTakeDamage(Stat_GetAdjusted(STAT_STR), this);
	switch ( iDmg )
	{
		case 0:			// damage blocked
		case 1:			// web survived
		default:		// unknown
			if ( GetTopPoint() == pItemWeb->GetTopPoint() )		// is character still stuck on the web?
				break;

		case 2:			// web turned into silk
		case INT_MAX:	// web destroyed
			if ( pFlag )
				pFlag->Delete();
			return false;
	}

	// Stuck in it still.
	if ( !pFlag )
	{
		if ( iDmg < 0 )
			return false;

		// First time message.
		pFlag = CItem::CreateBase(ITEMID_WEB1_1);
		ASSERT(pFlag);
		pFlag->SetAttr(ATTR_DECAY);
		pFlag->SetType(IT_EQ_STUCK);
		pFlag->m_uidLink = pItemWeb->GetUID();
		pFlag->SetTimeout(pItemWeb->GetTimerDAdjusted());
		LayerAdd(pFlag, LAYER_FLAG_Stuck);
	}
	else
	{
		if ( iDmg < 0 )
		{
			pFlag->Delete();
			return false;
		}
		SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SWEB_STUCK), pItemWeb->GetName());
	}

	return true;
}
示例#8
0
bool CChar::Use_Seed( CItem * pSeed, CPointMap * pPoint )
{
	ADDTOCALLSTACK("CChar::Use_Seed");
	// Use the seed at the current point on the ground or some new point that i can touch.
	// IT_SEED from IT_FRUIT

	ASSERT(pSeed);
	CPointMap pt;
	if ( pPoint )
		pt = *pPoint;
	else if ( pSeed->IsTopLevel() )
		pt = pSeed->GetTopPoint();
	else
		pt = GetTopPoint();

	if ( !CanTouch(pt) )
	{
		SysMessageDefault(DEFMSG_MSG_SEED_REACH);
		return false;
	}

	// is there soil here ? IT_DIRT
	if ( !IsPriv(PRIV_GM) && !g_World.IsItemTypeNear(pt, IT_DIRT, 0, false) )
	{
		SysMessageDefault(DEFMSG_MSG_SEED_TARGSOIL);
		return(false);
	}

	const CItemBase *pItemDef = pSeed->Item_GetDef();
	ITEMID_TYPE idReset = static_cast<ITEMID_TYPE>(RES_GET_INDEX(pItemDef->m_ttFruit.m_idReset));
	if ( idReset == 0 )
	{
		SysMessageDefault(DEFMSG_MSG_SEED_NOGOOD);
		return false;
	}

	// Already a plant here ?
	CWorldSearch AreaItems(pt);
	for (;;)
	{
		CItem *pItem = AreaItems.GetItem();
		if ( !pItem )
			break;
		if ( pItem->IsType(IT_TREE) || pItem->IsType(IT_FOLIAGE) )		// there's already a tree here
		{
			SysMessageDefault(DEFMSG_MSG_SEED_ATREE);
			return false;
		}
		if ( pItem->IsType(IT_CROPS) )		// there's already a plant here
			pItem->Delete();
	}

	// plant it and consume the seed.

	CItem *pPlant = CItem::CreateScript(idReset, this);
	ASSERT(pPlant);

	pPlant->MoveToUpdate(pt);
	if ( pPlant->IsType(IT_CROPS) || pPlant->IsType(IT_FOLIAGE) )
	{
		pPlant->m_itCrop.m_ReapFruitID = pSeed->GetID();
		pPlant->Plant_CropReset();
	}
	else
	{
		pPlant->SetDecayTime(10 * g_Cfg.m_iDecay_Item);
	}

	pSeed->ConsumeAmount();
	return true;
}
示例#9
0
文件: vendor.cpp 项目: Kitiara/UOX3
//o---------------------------------------------------------------------------o
//|   Function   : void sellItem(CSocket *mSock)
//|   Date       : Unknown
//|   Programmer : UOX3 DevTeam
//o---------------------------------------------------------------------------o
//|   Purpose    : Player sells an item to the vendor
//o---------------------------------------------------------------------------o
bool CPISellItem::Handle(void)
{
    if (tSock->GetByte(8) != 0)
    {
        CChar *mChar = tSock->CurrcharObj();
        CChar *n = calcCharObjFromSer(tSock->GetDWord(3));
        if (!ValidateObject(n) || !ValidateObject(mChar))
            return true;

        CItem *buyPack = n->GetItemAtLayer(IL_BUYCONTAINER);
        CItem *boughtPack = n->GetItemAtLayer(IL_BOUGHTCONTAINER);
        CItem *sellPack = n->GetItemAtLayer(IL_SELLCONTAINER);
        if (!ValidateObject(buyPack) || !ValidateObject(sellPack) || !ValidateObject(boughtPack))
            return true;

        CItem *j = NULL, *k = NULL, *l = NULL;
        UI16 amt = 0, maxsell = 0;
        UI08 i = 0;
        UI32 totgold = 0, value = 0;
        for (i = 0; i < tSock->GetByte(8); ++i)
        {
            j = calcItemObjFromSer(tSock->GetDWord(9 + (6*i)));
            amt = tSock->GetWord(13 + (6*i));
            maxsell += amt;
        }

        if (maxsell > cwmWorldState->ServerData()->SellMaxItemsStatus())
        {
            n->TextMessage(NULL, 1342, TALK, false, mChar->GetName().c_str(), cwmWorldState->ServerData()->SellMaxItemsStatus());
            return true;
        }

        for (i = 0; i < tSock->GetByte(8); ++i)
        {
            j = calcItemObjFromSer(tSock->GetDWord(9 + (6*i)));
            amt = tSock->GetWord(13 + (6*i));
            if (ValidateObject(j))
            {
                if (j->GetAmount() < amt || FindItemOwner(j) != mChar)
                {
                    n->TextMessage(NULL, 1343, TALK, false);
                    return true;
                }

                // Check if onSellToVendor JS event is present for each item being sold
                // If true, and a value of "false" has been returned from the script, halt the sale
                UI16 targTrig = j->GetScriptTrigger();
                cScript *toExecute = JSMapping->GetScript(targTrig);
                if (toExecute != NULL)
                    if (toExecute->OnSellToVendor(tSock, n, j))
                        return true;

                CItem *join = NULL;
                CDataList<CItem *> *pCont = boughtPack->GetContainsList();
                for (k = pCont->First(); !pCont->Finished(); k = pCont->Next())
                    if (ValidateObject(k))
                        if (k->GetID() == j->GetID() && j->GetType() == k->GetType())
                            join = k;

                pCont = buyPack->GetContainsList();
                for (k = pCont->First(); !pCont->Finished(); k = pCont->Next())
                    if (ValidateObject(k))
                        if (k->GetID() == j->GetID() && j->GetType() == k->GetType())
                            value = calcValue(j, k->GetSellValue());

                // If an object already exist in the boughtPack that this one can be joined to...
                if (ValidateObject(join))
                {
                    join->IncAmount(amt);
                    join->SetRestock(join->GetRestock() - amt);
                    l = join;

                    totgold += (amt * value);
                    if (j->GetAmount() == amt)
                        j->Delete();
                    else
                        j->IncAmount(-amt);
                }
                else
                {
                    //Otherwise, move this item to the vendor's boughtPack
                    totgold += (amt * value);

                    if (j->GetAmount() != amt) 
                    {
                        l = Items->DupeItem(tSock, j, amt);
                        j->SetAmount(j->GetAmount() - amt);
                    }
                    else
                        l = j;

                    if (ValidateObject(l))
                        l->SetCont(boughtPack);
                }

                if (l)
                {
                    cScript *toGrab = JSMapping->GetScript(l->GetScriptTrigger());
                    if (toGrab != NULL)
                        toGrab->OnSoldToVendor(tSock, n, l);
                }
            }
        }

        Effects->goldSound(tSock, totgold);
        while (totgold > MAX_STACK)
        {
            Items->CreateScriptItem(tSock, mChar, "0x0EED", MAX_STACK, OT_ITEM, true);
            totgold -= MAX_STACK;
        }

        if (totgold > 0)
            Items->CreateScriptItem(tSock, mChar, "0x0EED", totgold, OT_ITEM, true);
    }
    
    CPBuyItem clrSend;
    clrSend.Serial(tSock->GetDWord(3));
    tSock->Send(&clrSend);
    return true;
}