Exemplo n.º 1
0
void CItemSpawn::GenerateItem(CResourceDef *pDef)
{
	ADDTOCALLSTACK("CitemSpawn:GenerateItem");

	RESOURCE_ID_BASE rid = pDef->GetResourceID();
	ITEMID_TYPE id = static_cast<ITEMID_TYPE>(rid.GetResIndex());

	CItemContainer *pCont = dynamic_cast<CItemContainer *>(GetParent());
	BYTE iCount = pCont ? static_cast<unsigned char>(pCont->ContentCount(rid)) : GetCount();
	if ( iCount >= GetAmount() )
		return;

	CItem *pItem = CreateTemplate(id);
	if ( pItem == NULL )
		return;

	WORD iAmountPile = static_cast<WORD>(minimum(USHRT_MAX,m_itSpawnItem.m_pile));
	if ( iAmountPile > 1 )
	{
		CItemBase *pItemDef = pItem->Item_GetDef();
		ASSERT(pItemDef);
		if ( pItemDef->IsStackableType() )
			pItem->SetAmount(Calc_GetRandVal(iAmountPile) + 1);
	}

	pItem->SetAttr(m_Attr & (ATTR_OWNED | ATTR_MOVE_ALWAYS));
	pItem->SetDecayTime(g_Cfg.m_iDecay_Item);	// it will decay eventually to be replaced later
	pItem->MoveNearObj(this, m_itSpawnItem.m_DistMax);
	AddObj(pItem->GetUID());
}
Exemplo n.º 2
0
CRootItemIterator& CRootItemIterator::operator++() {
	assert( m_pos_stack.size() == (m_base_stack.size() ));

	++m_pos;
	while( m_pos >= m_base->numChildren() && !m_pos_stack.empty()) {
		// go back one in increment that, possibly descending in another leave
		m_pos = m_pos_stack.top();
		m_pos_stack.pop();
		m_base = m_base_stack.top();
		m_base_stack.pop();
		++m_pos;
	}

	if( m_pos < m_base->numChildren() ) { // do not ask for m_base->childAt( "too big" ) => that's itertor::end()
		CItemBase* item = m_base->childAt(m_pos);
		while(item->type() == CItemType::E_CAT) {
			m_base_stack.push(m_base);
			m_base = reinterpret_cast<CCategoryItem*>(item);
			m_pos_stack.push(m_pos);
			m_pos = 0;
			item = m_base->childAt(m_pos);
		}
	}
	return *this;
}
Exemplo n.º 3
0
int CResource::Calc_CombatAttackSpeed( CChar * pChar, CItem * pWeapon )
{
	// Combat: Speed of the attack
	// based on dex and weight of the weapon.
	// ? my tactics ?
	// ? my skill with weapon ?
	// ? How much weight i'm carrying ?
	// RETURN: 
	//  Time in tenths of a sec. (for entire swing, not just time to hit)

	ASSERT(pChar);

	if ( pWeapon != NULL )
	{
		CItemBase * pItemDef = dynamic_cast <CItemBase *> (pWeapon->Base_GetDef());
		if ( pItemDef )
		{
			BYTE speed = pItemDef->GetSpeed();
			if ( speed )
			{
				int iWaitTime = (TICK_PER_SEC * g_Cfg.m_iSpeedScaleFactor) / ( ( pChar->Stat_GetAdjusted(STAT_DEX) + 100 ) * speed );
				return (iWaitTime > 5 ? iWaitTime : 5);
			}
		}
	}
	if ( pChar->m_pNPC &&
		pChar->m_pNPC->m_Brain == NPCBRAIN_GUARD &&
		m_fGuardsInstantKill )
		return( 1 );

	// Base speed is just your DEX range=40 to 0
	int iWaitTime = IMULDIV( 100 - pChar->Stat_GetAdjusted(STAT_DEX), 40, 100 );
	if ( iWaitTime < 5 )	// no-one needs to be this fast.
		iWaitTime = 5;
	else
		iWaitTime += 5;

	// Speed of the weapon as well effected by strength (minor).

	if ( pWeapon != NULL )
	{
		DEBUG_CHECK( pWeapon->IsItemEquipped());
		int iWeaponWait = (pWeapon->GetWeight() * 10 ) / ( 4 * WEIGHT_UNITS );	// tenths of a stone.
		if ( pWeapon->GetEquipLayer() == LAYER_HAND2 )	// 2 handed is slower
		{
			iWeaponWait += iWaitTime/2;
		}
		iWaitTime += iWeaponWait;
	}
	else
	{
		iWaitTime += 2;
	}

	return( iWaitTime );
}
Exemplo n.º 4
0
void CWndShopCtrl::OnDraw(C2DRender* p2DRender) 
{
	CPoint pt( 3, 3 );
	CRect rect = GetClientRect();

	for( int i = 0; i < MAX_CART; i++ )
	{
		int x = i % 6;
		int y = i / 6;		
		CItemBase* pItemBase = m_pItemElem[ i ];
		if( pItemBase )
		{
			if( ((CItemElem*)pItemBase)->IsFlag( CItemElem::expired ) )
				pItemBase->GetTexture()->Render2( p2DRender, CPoint( x * 35, y * 35 ), D3DCOLOR_ARGB( 255, 255, 100, 100 ) );
			else
				pItemBase->GetTexture()->Render( p2DRender, CPoint( x * 35, y * 35 ) );
			
			CRect rectHittest = CRect( x * 35, y * 35 + 3, x * 35 + 35, y * 35 + 35 + 3);
			CPoint point = GetMousePoint();
			if( rectHittest.PtInRect( point ) )
			{
				CPoint point2 = point;
				ClientToScreen( &point2 );
				ClientToScreen( &rectHittest );

				g_WndMng.PutToolTip_Item( pItemBase, point2, &rectHittest );
			}

			CItemElem* pItemElem = (CItemElem*)pItemBase;
			if( pItemElem->GetProp()->dwPackMax > 1 )
			{
				//short n	= m_nBuy[i];
				//if( IsUsingItem( pItemBase ) )
				//	n = pItemBase->GetExtra();																		
				short m_nItemNum	= pItemElem->m_nItemNum;
				if( pItemElem->GetExtra() > 0 )
				    m_nItemNum	-= (short)pItemElem->GetExtra();

				TCHAR szTemp[ 35 ];
				_stprintf( szTemp, "%d", m_nItemNum );
				//_stprintf( szTemp, "%d", n );
			    CD3DFont* pOldFont = p2DRender->GetFont();//adeilson
		        p2DRender->SetFont( CWndBase::m_Theme.m_pFontWndNewTitle );
				CSize size = m_p2DRender->m_pFont->GetTextExtent( szTemp );
				m_p2DRender->TextOut( x * 35 + 35 - size.cx, y * 35 + 35 - size.cy, szTemp, 0xFF000000 );
				m_p2DRender->TextOut( x * 35 + 34 - size.cx, y * 35 + 34 - size.cy, szTemp, 0xFF85FF8A );
				p2DRender->SetFont( pOldFont );

				//_stprintf( szTemp, "%d", n );
				//CSize size = p2DRender->m_pFont->GetTextExtent( szTemp );
				//p2DRender->TextOut( x * 35 + 35 - size.cx, y * 35 + 35 - size.cy, szTemp, 0xff1010ff );
			}
		}
	}
}
Exemplo n.º 5
0
void CWndGuildMeritCtrl::OnDraw( C2DRender* p2DRender )
{
	if( m_pItemContainer.size() <= 0 )
		return;

	CRect rect	= GetClientRect();
	int nWidth	= rect.Width() / 32;
	int nHeight		= rect.Height() / 32;

	// 스크롤바 관련   
	CPoint pt( 0, 0 );

	nWidth = 6;
	int nPage = nHeight;
	int nRange = m_pItemContainer.size() / nWidth;// - nPage;
	if( m_pItemContainer.size() % nWidth )
		nRange++;

	m_wndScrollBar.SetScrollRange( 0, nRange );
	m_wndScrollBar.SetScrollPage( nPage );
	
	pt.y = 0;
	pt.y += m_wndScrollBar.GetScrollPos() * nWidth;

	for( int i = pt.y; i < (int)( m_pItemContainer.size() ); i++ )
	{
		int x	= ( i - pt.x ) % 6;
		int y	= ( i - pt.y ) / 6;
		CItemBase* pItemBase	= m_pItemContainer[i];
		if( pItemBase )
		{
			pItemBase->GetTexture()->Render( p2DRender, CPoint( x * 32 + 13, y * 32 + 7 ) );
			CRect rectHittest	= CRect( x * 32 + 13, y * 32  + 7, x * 32  + 13 + 32, y * 32 + 32 + 7 );
			CPoint point	= GetMousePoint();
			if( rectHittest.PtInRect( point ) )
			{
				CPoint point2 = point;
				ClientToScreen( &point2 );
				ClientToScreen( &rectHittest );
				g_WndMng.PutToolTip_Item( pItemBase, point2, &rectHittest, APP_VENDOR );
			}
			if( i == m_nCurSel )
				p2DRender->RenderRect( CRect( x * 32 + 7, y * 32 + 11, x * 32 + 32 + 5, y * 32 + 32 + 9 ), 0xff00ffff );
			CItemElem* pItemElem	= (CItemElem*)pItemBase;
			if( pItemElem->GetProp()->dwPackMax > 1 )
			{
				short nItemNum	= pItemBase->GetExtra();
				TCHAR szTemp[32];
				_stprintf( szTemp, "%d", nItemNum );
				CSize size	= p2DRender->m_pFont->GetTextExtent( szTemp );
				p2DRender->TextOut( x * 32 + 32 - size.cx + 17, y * 32 + 32 - size.cy + 10, szTemp, 0xff1010ff );
			}
		}
	}
}
Exemplo n.º 6
0
void CRenderClientsListView::performDrag()
{
	qDebug() << QString("performDrag");

    CRenderClientsListModel* lmodel = reinterpret_cast<CRenderClientsListModel*>(model());

    QModelIndexList indexList = selectedIndexes();
    CModelDiff md(m_role);

    for(int i = 0; i < indexList.size(); i++)
    {
    	comb_hash_t combhash;
		CItemBase* item = lmodel->itemFromIndex(indexList.at(i));
		switch(item->type()) {
		case CItemType::E_STREAM_CLIENT:
		{
    		CStreamClientItem* scItem = reinterpret_cast<CStreamClientItem*>(item);
			combhash.type = scItem->type();
			if(m_role == E_OWN_RENDER_CLIENT) {
			    int filteredline = lmodel->own2availIndex(indexList.at(i).row());
	            combhash.line = filteredline;
			}
			else {
                combhash.line = indexList.at(i).row();
			}

			md.appendToSelectedItems(combhash);
		}
		default:
			break;
		}
    }

    if (md.getNumSelected() > 0)
    {
    	QMimeData *mimeData = new QMimeData;
        //mimeData->setText(item->asString());
        mimeData->setData(dndMimeType, md.toQByteArray());

        m_dragActive = true;
        QDrag *drag = new QDrag(this);
        drag->setMimeData(mimeData);
        // drag->setPixmap(QPixmap(":/images/person.png"));

        Qt::DropAction action = drag->exec(Qt::MoveAction);

        m_dragActive = false;
        qDebug() << QString("DropAction: %1").arg(action);

    }
}
Exemplo n.º 7
0
LONG CItemVendable::GetVendorPrice( int iConvertFactor )
{
	ADDTOCALLSTACK("CItemVendable::GetVendorPrice");
	// Player is buying/selling from a vendor.
	// ASSUME this item is on the vendor !
	// Consider: (if not on a player vendor)
	//  Quality of the item.
	//  rareity of the item.
	// ARGS:
	// iConvertFactor will consider:
	//  Vendors Karma.
	//  Players Karma
	// -100 = reduce price by 100%   (player selling to vendor?)
	//    0 = base price
	// +100 = increase price by 100% (vendor selling to player?)

	INT64 lPrice = m_price;
	if ( lPrice <= 0 )	// set on player vendor.
	{
		if ( lPrice == 0 )	// set a new randomized price for the item
		{
			CItemBase * pItemDef;
			if ( IsType( IT_DEED ))
			{
				// Deeds just represent the item they are deeding.
				pItemDef = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(RES_GET_INDEX(m_itDeed.m_Type)));
				if ( pItemDef == NULL )
					return( 1 );
			}
			else
			{
				pItemDef = Item_GetDef();
			}
			lPrice = pItemDef->GetMakeValue(GetQuality());
			m_price = static_cast<long>(-lPrice);
		}
		else
		{
			lPrice = -lPrice;
		}
	}

	lPrice += IMULDIV( lPrice, maximum(iConvertFactor, -100), 100 );
	if (lPrice > LONG_MAX)
		return LONG_MAX;
	else if (lPrice <= 0)
		return 0;
	
	return static_cast<long>(lPrice);
}
Exemplo n.º 8
0
void CPlaylistView::performDrag()
{
	qDebug() << QString("performDrag");

    CMuroaListModel* plModel = reinterpret_cast<CMuroaListModel*>(model());

    QModelIndexList indexList = selectedIndexes();
    CModelDiff md(m_role);

    for(int i = 0; i < indexList.size(); i++)
    {
    	comb_hash_t combhash;
		CItemBase* item = plModel->itemFromIndex(indexList.at(i));
		switch(item->type()) {

			case CItemType::E_PLAYLISTITEM:
			{
				CPlaylistItem* plitem = reinterpret_cast<CPlaylistItem*>(item);
				combhash.type = plitem->type();
				combhash.hash = plitem->getMediaItemHash();
				combhash.pl_id = plitem->getHash();
				combhash.line = indexList.at(i).row();
				md.appendToSelectedItems(combhash);
				break;
			}
			default:
				// error, there should only be playlist items in the playlist.
				break;
		}
    }

    if (md.getNumSelected() > 0)
    {
    	QMimeData *mimeData = new QMimeData;
        //mimeData->setText(item->asString());
        mimeData->setData("application/x-muroa-playlist-diff", md.toQByteArray());

        m_dragActive = true;
        QDrag *drag = new QDrag(this);
        drag->setMimeData(mimeData);
        // drag->setPixmap(QPixmap(":/images/person.png"));

        Qt::DropAction action = drag->exec(Qt::MoveAction);

        m_dragActive = false;
        qDebug() << QString("DropAction: %1").arg(action);

    }
}
Exemplo n.º 9
0
CRootItemIterator::CRootItemIterator(CCategoryItem* base, int pos) : m_base(base),
		                                                             m_pos(pos),
		                                                             m_base_stack(),
		                                                             m_pos_stack()
{
	if(m_pos == 0) {
		if(m_base->numChildren() > 0) {
			CItemBase* item = m_base->childAt(0);
			while(item->type() == CItemType::E_CAT) {
				m_base_stack.push(m_base);
				m_base = reinterpret_cast<CCategoryItem*>(item);
				m_pos_stack.push(0);
				item = m_base->childAt(0);
			}
		}
	}
}
Exemplo n.º 10
0
void CItemSpawn::GenerateItem(CResourceDef * pDef)
{
	ADDTOCALLSTACK("CitemSpawn:GenerateItem");

	RESOURCE_ID_BASE rid = pDef->GetResourceID();
	ITEMID_TYPE id = static_cast<ITEMID_TYPE>(rid.GetResIndex());
	int iDistMax = m_itSpawnItem.m_DistMax;
	int iAmountPile = m_itSpawnItem.m_pile;

	int iCount = 0;
	CItemContainer * pCont = dynamic_cast <CItemContainer *>( GetParent());

	if ( pCont != NULL )
		iCount = pCont->ContentCount( rid );
	else
		iCount = GetCount();

	if ( iCount >= GetAmount())
		return;

	CItem * pItem = CreateTemplate( id );
	if ( pItem == NULL )
		return;

	pItem->SetAttr( m_Attr & ( ATTR_OWNED | ATTR_MOVE_ALWAYS ));

	if ( iAmountPile > 1 )
	{
		CItemBase * pItemDef = pItem->Item_GetDef();
		ASSERT(pItemDef);
		if ( pItemDef->IsStackableType())
		{
			if ( iAmountPile == 0 || iAmountPile > GetAmount())
				iAmountPile = GetAmount();
			pItem->SetAmount( Calc_GetRandVal(iAmountPile) + 1 );
		}
	}

	pItem->SetDecayTime( g_Cfg.m_iDecay_Item );	// It will decay eventually to be replaced later.
	pItem->MoveNearObj( this, iDistMax );
	AddObj(pItem->GetUID());
	pItem->m_uidSpawnItem = GetUID();
}
Exemplo n.º 11
0
void CWndVendorCtrl::OnMouseMove( UINT nFlags, CPoint point )
{
	if( m_bDrag == FALSE )
		return;
	m_bDrag		= FALSE;
	CPoint pt( 3, 3 );
	CRect rect;

	CItemBase* pItemBase	= m_pFocusItem;
	if( IsUsingItem( pItemBase ) )
	{
		m_GlobalShortcut.m_pFromWnd		= this;
		m_GlobalShortcut.m_dwShortcut	= SHORTCUT_ITEM;
		m_GlobalShortcut.m_dwIndex	= m_nCurSel;
		m_GlobalShortcut.m_dwType	= 0;
		m_GlobalShortcut.m_dwId		= pItemBase->m_dwObjId;
		m_GlobalShortcut.m_pTexture		= pItemBase->GetTexture();
		m_GlobalShortcut.m_dwData	= (DWORD)pItemBase;
		_tcscpy( m_GlobalShortcut.m_szString, pItemBase->GetProp()->szName );
	}
}
Exemplo n.º 12
0
void CWndSelectAwakeCase::SetData( BYTE byObjID, DWORD dwSerialNum, __int64 n64NewOption ) 
{ 
	//server로 전송할 데이터를 유지하고, 아이템 Index를 뽑아서 아이콘을 그려줄 준비
	m_byObjID = byObjID;
	m_dwSerialNum = dwSerialNum;
	m_n64NewOption = n64NewOption; 

	if( !g_pPlayer )
	{
		assert( 0 );
		return;
	}

	CItemBase* pItemBase = g_pPlayer->GetItemId( m_byObjID );
	if( pItemBase )
	{
		ItemProp* pProp = pItemBase->GetProp( );
		if(pProp)
			m_dwItemIndex = pProp->dwID;
	}
}
Exemplo n.º 13
0
bool CRegionResourceDef::r_WriteVal( LPCTSTR pszKey, CGString & sVal, CTextConsole * pSrc )
{
	ADDTOCALLSTACK("CRegionResourceDef::r_WriteVal");
	EXC_TRY("r_WriteVal");
	// RES_REGIONRESOURCE
	switch ( FindTableSorted( pszKey, sm_szLoadKeys, COUNTOF( sm_szLoadKeys )-1 ))
	{
		case RMC_AMOUNT:
			sVal = m_Amount.Write();
			break;
		case RMC_REAP: // "REAP",
			{
				CItemBase * pItemDef = CItemBase::FindItemBase(m_ReapItem);
				if ( !pItemDef )
				{
					return false;
				}

				sVal = pItemDef->GetResourceName();
			} break;
		case RMC_REAPAMOUNT:
			sVal = m_ReapAmount.Write();
			break;
		case RMC_REGEN:
			sVal = m_iRegenerateTime.Write();
			break;
		case RMC_SKILL:
			sVal = m_Skill.Write();
			break;
		default:
			return( CResourceDef::r_WriteVal( pszKey, sVal, pSrc ));
	}
	return true;
	EXC_CATCH;

	EXC_DEBUG_START;
	EXC_ADD_KEYRET(pSrc);
	EXC_DEBUG_END;
	return false;
}
Exemplo n.º 14
0
bool CItemVendable::IsValidNPCSaleItem() const
{
	ADDTOCALLSTACK("CItemVendable::IsValidNPCSaleItem");
	// This item is in an NPC's vendor box.
	// Is it a valid item that NPC's should be selling ?

	CItemBase * pItemDef = Item_GetDef();

	if ( m_price <= 0 && pItemDef->GetMakeValue(0) <= 0 )
	{
		DEBUG_ERR(( "Vendor uid=0%lx selling unpriced item %s='%s'\n", static_cast<DWORD>(GetTopLevelObj()->GetUID()), GetResourceName(), GetName()));
		return( false );
	}

	if ( ! IsValidSaleItem( true ))
	{
		DEBUG_ERR(( "Vendor uid=0%lx selling bad item %s='%s'\n", static_cast<DWORD>(GetTopLevelObj()->GetUID()), GetResourceName(), GetName()));
		return( false );
	}

	return( true );
}
Exemplo n.º 15
0
bool CPointBase::r_WriteVal( LPCTSTR pszKey, CGString & sVal ) const
{
	ADDTOCALLSTACK("CPointBase::r_WriteVal");
	if ( !strnicmp( pszKey, "STATICS", 7 ) )
	{
		pszKey	+= 7;
		const CGrayMapBlock * pBlock = g_World.GetMapBlock( *(this) );
		if ( !pBlock ) return false;

		if ( *pszKey == '\0' )
		{
			int iStaticQty = 0;
			for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); i++ )
			{
				const CUOStaticItemRec * pStatic = pBlock->m_Statics.GetStatic( i );
				CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map );
				if ( this->GetDist( ptTest ) > 0 )
					continue;
				iStaticQty++;
			}

			sVal.FormatVal( iStaticQty );
			return true;
		}

		SKIP_SEPARATORS( pszKey );

		const CUOStaticItemRec * pStatic = NULL;
		int iStatic = 0;
		int type = 0;
		
		if ( !strnicmp( pszKey, "FINDID", 6 ) )
		{
			pszKey += 6;
			SKIP_SEPARATORS( pszKey );
			iStatic = Exp_GetVal( pszKey );
			type = RES_GET_TYPE( iStatic );
			if ( type == 0 )
				type = RES_ITEMDEF;
			SKIP_SEPARATORS( pszKey );
		}
		else
		{
			iStatic = Exp_GetVal( pszKey );
			type = RES_GET_TYPE( iStatic );
		}
		
		if ( type == RES_ITEMDEF )
		{
			const CItemBase * pItemDef = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(RES_GET_INDEX(iStatic)));
			if ( !pItemDef )
			{
				sVal.FormatVal( 0 );
				return false;
			}
			for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); pStatic = NULL, i++ )
			{
				pStatic = pBlock->m_Statics.GetStatic( i );
				CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map);
				if ( this->GetDist( ptTest ) > 0 )
					continue;
				if ( pStatic->GetDispID() == pItemDef->GetDispID() )
					break;
			}
		}
		else
		{
			for ( size_t i = 0; i < pBlock->m_Statics.GetStaticQty(); pStatic = NULL, i++ )
			{
				pStatic = pBlock->m_Statics.GetStatic( i );
				CPointMap ptTest( pStatic->m_x+pBlock->m_x, pStatic->m_y+pBlock->m_y, pStatic->m_z, this->m_map);
				if ( this->GetDist( ptTest ) > 0 )
					continue;
				if ( iStatic == 0 )
					break;
				iStatic--;
			}
		}

		if ( !pStatic )
		{
			sVal.FormatHex(0);
			return true;
		}

		SKIP_SEPARATORS( pszKey );
		if ( !*pszKey )
			pszKey	= "ID";

		ITEMID_TYPE idTile = pStatic->GetDispID();

		if ( !strnicmp( pszKey, "COLOR", 5 ) )
		{
			sVal.FormatHex( pStatic->m_wHue );
			return true;
		}
		else if ( !strnicmp( pszKey, "ID", 2 ) )
		{
			sVal.FormatHex( idTile );
			return true;
		}
		else if ( !strnicmp( pszKey, "Z", 1 ) )
		{
			sVal.FormatVal( pStatic->m_z );
			return true;
		}

		// Check the script def for the item.
		CItemBase * pItemDef = CItemBase::FindItemBase( idTile );
		if ( pItemDef == NULL )
		{
			DEBUG_ERR(("Must have ITEMDEF section for item ID 0%x\n", idTile ));
			return false;
		}

		return pItemDef->r_WriteVal( pszKey, sVal, &g_Serv );
	}
	else if ( !strnicmp( pszKey, "COMPONENTS", 10) )
	{
		pszKey += 10;
		
		CRegionLinks rlinks;
		const CRegionBase* pRegion = NULL;
		CItem* pItem = NULL;
		const CGrayMulti* pMulti = NULL;
		const CUOMultiItemRec2* pMultiItem = NULL;
		size_t iMultiQty = GetRegions(REGION_TYPE_MULTI, rlinks);

		if ( *pszKey == '\0' )
		{
			int iComponentQty = 0;
			for (size_t i = 0; i < iMultiQty; i++)
			{
				pRegion = rlinks.GetAt(i);
				if (pRegion == NULL)
					continue;

				pItem = pRegion->GetResourceID().ItemFind();
				if (pItem == NULL)
					continue;

				const CPointMap ptMulti = pItem->GetTopPoint();
				pMulti = g_Cfg.GetMultiItemDefs(pItem);
				if (pMulti == NULL)
					continue;

				size_t iQty = pMulti->GetItemCount();
				for (size_t ii = 0; ii < iQty; ii++)
				{
					pMultiItem = pMulti->GetItem(ii);
					if (pMultiItem == NULL)
						break;
					if (pMultiItem->m_visible == 0)
						continue;

					CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map);
					if (GetDist(ptTest) > 0)
						continue;

					iComponentQty++;
				}
			}

			sVal.FormatVal( iComponentQty );
			return true;
		}

		SKIP_SEPARATORS( pszKey );

		int iComponent = 0;
		int type = 0;
		
		if ( strnicmp( pszKey, "FINDID", 6 ) == 0 )
		{
			pszKey += 6;
			SKIP_SEPARATORS( pszKey );
			iComponent = Exp_GetVal( pszKey );
			type = RES_GET_TYPE( iComponent );
			if ( type == 0 )
				type = RES_ITEMDEF;
			SKIP_SEPARATORS( pszKey );
		}
		else
		{
			iComponent = Exp_GetVal( pszKey );
			type = RES_GET_TYPE( iComponent );
		}
		
		if ( type == RES_ITEMDEF )
		{
			const CItemBase * pItemDef = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(RES_GET_INDEX(iComponent)));
			if ( pItemDef == NULL )
			{
				sVal.FormatVal( 0 );
				return false;
			}
			
			for (size_t i = 0; i < iMultiQty; i++)
			{
				pRegion = rlinks.GetAt(i);
				if (pRegion == NULL)
					continue;

				pItem = pRegion->GetResourceID().ItemFind();
				if (pItem == NULL)
					continue;

				const CPointMap ptMulti = pItem->GetTopPoint();
				pMulti = g_Cfg.GetMultiItemDefs(pItem);
				if (pMulti == NULL)
					continue;

				size_t iQty = pMulti->GetItemCount();
				for (size_t ii = 0; ii < iQty; pMultiItem = NULL, ii++)
				{
					pMultiItem = pMulti->GetItem(ii);
					if (pMultiItem == NULL)
						break;
					if (pMultiItem->m_visible == 0)
						continue;
					CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map);
					if (GetDist(ptTest) > 0)
						continue;

					const CItemBase* pMultiItemDef = CItemBase::FindItemBase(pMultiItem->GetDispID());
					if (pMultiItemDef != NULL && pMultiItemDef->GetDispID() == pItemDef->GetDispID())
						break;
				}

				if (pMultiItem != NULL)
					break;
			}
		}
		else
		{
			for (size_t i = 0; i < iMultiQty; i++)
			{
				pRegion = rlinks.GetAt(i);
				if (pRegion == NULL)
					continue;

				pItem = pRegion->GetResourceID().ItemFind();
				if (pItem == NULL)
					continue;

				const CPointMap ptMulti = pItem->GetTopPoint();
				pMulti = g_Cfg.GetMultiItemDefs(pItem);
				if (pMulti == NULL)
					continue;

				size_t iQty = pMulti->GetItemCount();
				for (size_t ii = 0; ii < iQty; pMultiItem = NULL, ii++)
				{
					pMultiItem = pMulti->GetItem(ii);
					if (pMultiItem == NULL)
						break;
					if (pMultiItem->m_visible == 0)
						continue;
					CPointMap ptTest(static_cast<WORD>(ptMulti.m_x + pMultiItem->m_dx), static_cast<WORD>(ptMulti.m_y + pMultiItem->m_dy), static_cast<signed char>(ptMulti.m_z + pMultiItem->m_dz), this->m_map);
					if (GetDist(ptTest) > 0)
						continue;

					if (iComponent == 0)
						break;

					iComponent--;
				}

				if (pMultiItem != NULL)
					break;
			}
		}

		if ( pMultiItem == NULL )
		{
			sVal.FormatHex(0);
			return true;
		}

		SKIP_SEPARATORS( pszKey );
		if ( !*pszKey )
			pszKey	= "ID";

		ITEMID_TYPE idTile = pMultiItem->GetDispID();

		if ( strnicmp( pszKey, "ID", 2 ) == 0 )
		{
			sVal.FormatHex( idTile );
			return true;
		}
		else if ( strnicmp( pszKey, "MULTI", 5 ) == 0 )
		{
			pszKey += 5;
			if (*pszKey != '\0')
			{
				SKIP_SEPARATORS(pszKey);
				return pItem->r_WriteVal( pszKey, sVal, &g_Serv );
			}

			sVal.FormatHex( pItem->GetUID() );
			return true;
		}
		else if ( strnicmp( pszKey, "Z", 1 ) == 0 )
		{
			sVal.FormatVal( pItem->GetTopZ() + pMultiItem->m_dz );
			return true;
		}

		// Check the script def for the item.
		CItemBase * pItemDef = CItemBase::FindItemBase( idTile );
		if ( pItemDef == NULL )
		{
			DEBUG_ERR(("Must have ITEMDEF section for item ID 0%x\n", idTile ));
			return false;
		}

		return pItemDef->r_WriteVal( pszKey, sVal, &g_Serv );
	}
	
	int index = FindTableHeadSorted( pszKey, sm_szLoadKeys, COUNTOF(sm_szLoadKeys)-1 );
	if ( index < 0 )
		return false;

	switch ( index )
	{
		case PT_M:
		case PT_MAP:
			sVal.FormatVal(m_map);
			break;
		case PT_X:
			sVal.FormatVal(m_x);
			break;
		case PT_Y:
			sVal.FormatVal(m_y);
			break;
		case PT_Z:
			sVal.FormatVal(m_z);
			break;
		case PT_ISNEARTYPE:
		{
			pszKey += 10;
			SKIP_SEPARATORS( pszKey );
			SKIP_ARGSEP( pszKey );

			int iType = g_Cfg.ResourceGetIndexType( RES_TYPEDEF, pszKey );
			int iDistance = 0;
			bool bCheckMulti = false;

			SKIP_IDENTIFIERSTRING( pszKey );
			SKIP_SEPARATORS( pszKey );
			SKIP_ARGSEP( pszKey );

			if ( *pszKey ) iDistance = Exp_GetVal(pszKey);
			if ( *pszKey ) bCheckMulti = Exp_GetVal(pszKey) != 0;
			sVal.FormatVal( g_World.IsItemTypeNear(*this, static_cast<IT_TYPE>(iType), iDistance, bCheckMulti));
			break;
		}
		case PT_REGION:
		{
			// Check that the syntax is correct.
			if ( pszKey[6] && pszKey[6] != '.' )
				return false;

			CRegionWorld * pRegionTemp = dynamic_cast <CRegionWorld*>(this->GetRegion(REGION_TYPE_AREA | REGION_TYPE_MULTI));

			if ( !pszKey[6] )
			{
				// We're just checking if the reference is valid.
				sVal.FormatVal( pRegionTemp? 1:0 );
				return true;
			}
			
			// We're trying to retrieve a property from the region.
			pszKey += 7;
			if ( pRegionTemp )
				return pRegionTemp->r_WriteVal( pszKey, sVal, &g_Serv );

			return false;
		}
		case PT_ROOM:
		{
			if ( pszKey[4] && pszKey[4] != '.' )
				return false;

			CRegionBase * pRegionTemp = this->GetRegion( REGION_TYPE_ROOM );

			if ( !pszKey[4] )
			{
				sVal.FormatVal( pRegionTemp? 1:0 );
				return true;
			}

			pszKey += 5;
			if ( pRegionTemp )
				return pRegionTemp->r_WriteVal( pszKey, sVal, &g_Serv );

			return false;
		}
		case PT_SECTOR:
		{
			if ( pszKey[6] == '.' )
			{
				pszKey += 7;
				CSector * pSectorTemp = this->GetSector();
				if (pSectorTemp)
					return pSectorTemp->r_WriteVal(pszKey, sVal, &g_Serv);
			}
			return false;
		}
		default:
		{
			const CUOMapMeter * pMeter = g_World.GetMapMeter(*this);
			if ( pMeter )
			{
				switch( index )
				{
					case PT_TYPE:
						{
							CItemTypeDef * pTypeDef = g_World.GetTerrainItemTypeDef( pMeter->m_wTerrainIndex );
							if ( pTypeDef != NULL )
								sVal = pTypeDef->GetResourceName();
							else
								sVal = "";
						} return true;	
					case PT_TERRAIN:
						{
							pszKey += strlen(sm_szLoadKeys[index]);
							if ( *pszKey == '.' )	// do we have an argument?
							{
								SKIP_SEPARATORS( pszKey );
								if ( !strnicmp( pszKey, "Z", 1 ))
								{
									sVal.FormatVal( pMeter->m_z );
									return( true );
								}
								
								return( false );
							}
							else
							{
								sVal.FormatHex( pMeter->m_wTerrainIndex );
							}
						} return true;
				}
			}
			return false;
		}
	}

	return true;
}
Exemplo n.º 16
0
BOOL CWndRegVend::OnChildNotify( UINT message, UINT nID, LRESULT* pLResult )
{
	CString str;

	SetFocus();
	
	CWndStatic* pWndStatic;
	pWndStatic = (m_dwFocus == 0) ? (CWndStatic*)GetDlgItem( WIDC_SELLNUM ): (CWndStatic*)GetDlgItem( WIDC_SELLPRI );

	str = pWndStatic->GetTitle();

	switch( nID )
	{
	case WIDC_VENEQUA:
		{
			if( m_bIsFirst )
			{
				char buffer[20] = { 0 };
				int i = ProcessCalc( m_Calc, atoi(str) );

				if(i < 0)
					_itoa( 2100000000, buffer, 10 );
				else
					_itoa( i, buffer, 10 );

				str = buffer;
				pWndStatic->SetTitle(str);
				m_bIsFirst = FALSE;
				m_Calc.m_nValue = 0;
			}
		}
		break;
	case WIDC_VENPLUS:
		OnChar('+');
		break;
	case WIDC_VENMINUS:
		OnChar('-');
		break;
	case WIDC_VENMULTI:
		OnChar('*');
		break;
	case WIDC_VENDIVID:
		OnChar('/');
		break;
	case WIDC_NUM0:
		OnChar('0');
		break;
	case WIDC_NUM1:
		OnChar('1');
		break;
	case WIDC_NUM2:
		OnChar('2');
		break;
	case WIDC_NUM3:
		OnChar('3');
		break;
	case WIDC_NUM4:
		OnChar('4');
		break;
	case WIDC_NUM5:
		OnChar('5');
		break;
	case WIDC_NUM6:
		OnChar('6');
		break;
	case WIDC_NUM7:
		OnChar('7');
		break;
	case WIDC_NUM8:
		OnChar('8');
		break;
	case WIDC_NUM9:
		OnChar('9');
		break;
	case WIDC_NUM00:
		{
			if(str == "0")
				break;

			CString strSum;
			strSum = str + "00";
			if(strlen(strSum) <= 9)
			{
				str+="00";
				pWndStatic->SetTitle(str);
			}
			break;
		}
	case WIDC_NUM000:
		{
			if(str == "0")
				break;

			CString strSum;
			strSum = str + "000";
			if(strlen(strSum) <= 9)
			{
				str+="000";
				pWndStatic->SetTitle(str);
			}
			break;
		}
	case WIDC_VENMIN:
		{
			pWndStatic->SetTitle( "1" );
			break;
		}
	case WIDC_VENMAX:
		{
			if(m_pItemBase)
			{
				ItemProp *pItemProp = m_pItemBase->GetProp();

				int nValue = 0;
#if __VER >= 8 // __S8_VENDOR_REVISION
				nValue = ( m_dwFocus == 0 ) ? ( (CItemElem*)m_pItemBase )->m_nItemNum: 2100000000;
#else // __VER >= 8 // __S8_VENDOR_REVISION
				nValue = ( m_dwFocus == 0 ) ? ( (CItemElem*)m_pItemBase )->m_nItemNum: pItemProp->dwCost;
#endif // __VER >= 8 // __S8_VENDOR_REVISION
				
				CString str;
				str.Format( "%d", nValue );
				
				pWndStatic->SetTitle(str);
				
			}
			break;
		}
	}
	
	if( nID == WIDC_OK || message ==  EN_RETURN )
	{
		pWndStatic	= (CWndStatic*)GetDlgItem( WIDC_SELLNUM );
		LPCTSTR str	= pWndStatic->GetTitle();
		int nNum	= 1;
		nNum	= atoi( str );
		CItemElem* pItemElem	= (CItemElem*)m_pItemBase;
		if( nNum < 1 )	return TRUE;	// 개수가 너무 작습니다.
		if( nNum > pItemElem->m_nItemNum )	nNum	= pItemElem->m_nItemNum;

		int nCost	= 0;
		pWndStatic	= (CWndStatic*)GetDlgItem( WIDC_SELLPRI );
		str		= pWndStatic->GetTitle();
#if __VER < 8 // __S8_VENDOR_REVISION
		if( strlen( str ) > 9 )	return TRUE;	// 숫자가 너무 큽니다.
#endif // __VER < 8 // __S8_VENDOR_REVISION
		//nCost	= atoi( str );

		__int64  n64Cost = 0;
		n64Cost = _atoi64(str);
		if( n64Cost > INT_MAX )
			n64Cost = INT_MAX;
		nCost = static_cast<int>( n64Cost );

		if( nCost < 1 )	return TRUE;	// 비정상적인 수치가 입력되었습니다.
		
		ItemProp* pItemProp	= m_pItemBase->GetProp();

		
#if __VER >= 8 // __S8_VENDOR_REVISION
//		if( 999999999 < ((EXPINTEGER)nCost*nNum) )
//		{
//			g_WndMng.OpenMessageBox( _T(prj.GetText(TID_GAME_VENDOR_MAX_ONE_GOLD)), MB_OK, this );
//			return TRUE;
//		}
		
		int nGold = g_pPlayer->GetGold();
		for( int iv = 0 ; iv < MAX_VENDITEM ; ++iv )
		{
			CItemBase *pItemBase = g_pPlayer->m_vtInfo.GetItem( iv );
			if( pItemBase == NULL )
				continue;

			nGold += ((CItemElem*)pItemBase)->m_nCost * pItemBase->GetExtra();
		}					
		int nOldGold = nGold;
		//nGold += (nCost * nNum);

		INT64 n64Sum(0);
		INT64 n64Gold(nGold);
		INT64 n64itemCost(nCost);
		INT64 n64Num(nNum);
		n64Sum = n64Gold + (n64itemCost * n64Num);

		if( n64Sum <= 0 || 2100000000 <= n64Sum || nOldGold >= n64Sum )
		{
			g_WndMng.OpenMessageBox( _T(prj.GetText(TID_GAME_VENDOR_MAX_ALL_GOLD)), MB_OK, this );
			return TRUE;
		}

//		if( nGold <= 0 || nOldGold >= nGold || 2100000000 <= nGold )
//		{
//			g_WndMng.OpenMessageBox( _T(prj.GetText(TID_GAME_VENDOR_MAX_ALL_GOLD)), MB_OK, this );
//			return TRUE;
//		}
#endif // __VER >= 8 // __S8_VENDOR_REVISION
		
#if __VER < 8     //8차게임내아이템판매가격제한풀기
		if( nCost > pItemProp->dwCost * 1000 )
		{
			g_WndMng.OpenMessageBox( _T( prj.GetText(TID_GAME_LIMITSELL)), MB_OK, this );
			return TRUE;
		}
#endif	//	   __VER < 8  

		g_DPlay.SendRegisterPVendorItem( m_iIndex, 0, (BYTE)( m_pItemBase->m_dwObjId ), nNum, nCost );
		Destroy( FALSE );
	}
	else if( nID == WIDC_CANCEL )	// WIDC_CANCEL
	{
		Destroy( FALSE );
	}
	

	return CWndNeuz::OnChildNotify( message, nID, pLResult );
}
Exemplo n.º 17
0
CPointMap CItemContainer::GetRandContainerLoc() const
{
	ADDTOCALLSTACK("CItemContainer::GetRandContainerLoc");
	// Max/Min Container Sizes.

	static const struct // we can probably get this from MUL file some place.
	{
		GUMP_TYPE m_gump;
		WORD m_minx;
		WORD m_miny;
		WORD m_maxx;
		WORD m_maxy;
	} sm_ContSize[] =
	{
		{ GUMP_RESERVED, 40, 50, 100, 100 },		// default.
		{ GUMP_CORPSE, 20, 85, 80, 185 },
		{ GUMP_PACK, 44, 65, 142, 150 },			// Open backpack
		{ GUMP_BAG, 29, 34, 93, 119 },				// Leather Bag
		{ GUMP_BARREL, 33, 36, 98, 139 },			// Barrel
		{ GUMP_BASKET_SQ, 19, 47, 138, 114 },		// Square picknick Basket
		{ GUMP_BOX_WOOD, 16, 51, 140, 115 },		// small wood box with a lock
		{ GUMP_BASKET_RO, 33, 36,  98, 134 },		// Round Basket
		{ GUMP_CHEST_GO_SI, 18, 105, 118, 169 },	// Gold and Silver Chest.
		{ GUMP_BOX_WOOD_OR, 16, 51, 140, 115 },		// Small wood box (ornate)(no lock)
		{ GUMP_CRATE, 20, 10, 126, 91 },			// Wood Crate
		{ GUMP_DRAWER_DK, 16, 17, 110, 85 },
		{ GUMP_CHEST_WO_GO, 18, 105, 118, 169 },	// Wood with gold trim.
		{ GUMP_CHEST_SI, 18, 105, 118, 169 },		// silver chest.
		{ GUMP_BOX_GO_LO, 16, 51, 140, 115 },		// Gold/Brass box with a lock.
		{ GUMP_SHIP_HOLD, 46, 74, 152, 175 },
		{ GUMP_BOOK_SHELF, 76, 12, 96, 59 },
		{ GUMP_CABINET_DK, 24, 96, 91, 143 },
		{ GUMP_CABINET_LT, 24, 96, 91, 143 },
		{ GUMP_DRAWER_LT, 16, 17, 110, 85 },
		{ GUMP_GIFT_BOX, 35, 10, 155, 85 },
		{ GUMP_ARMOIRE_RED, 10, 10, 150, 95 },
		{ GUMP_ARMOIRE_MAPLE, 10, 10, 150, 95 },
		{ GUMP_ARMOIRE_CHERRY, 10, 10, 150, 95 },
		{ GUMP_BASKET_TALL, 10, 10, 116, 71 },
		{ GUMP_CHEST_WOOD_PLAIN, 10, 10, 150, 95 },
		{ GUMP_CHEST_WOOD_GILDED, 10, 10, 150, 95 },
		{ GUMP_CHEST_WOOD_ORNATE, 10, 10, 150, 95 },
		{ GUMP_TALL_CABINET, 10, 10, 150, 95 },
		{ GUMP_CHEST_WOOD_FINISH, 10, 10, 150, 95 },
		{ GUMP_HEART_SHAPED, 56, 30, 102, 74},
		{ GUMP_SECURE_TRADE, 1, 1, 66, 26 },
		{ GUMP_GAME_BOARD,	 4, 10, 220, 185 },		// Chess or checker board.
		{ GUMP_GAME_BACKGAM, 4, 10, 220, 185 },
	};

	// ??? pItemDef->m_ttContainer.m_dwMinXY to m_dwMaxXY
	// Get a random location in the container.

	CItemBase * pItemDef = Item_GetDef();
	GUMP_TYPE gump = pItemDef->IsTypeContainer();

	// check for custom values in TDATA3/TDATA4
	if ( pItemDef->m_ttContainer.m_dwMaxXY )
	{
		int tmp_MinX = (pItemDef->m_ttContainer.m_dwMinXY & 0xFFFF0000) >> 16;
		int tmp_MinY = (pItemDef->m_ttContainer.m_dwMinXY & 0xFFFF);
		int tmp_MaxX = (pItemDef->m_ttContainer.m_dwMaxXY & 0xFFFF0000) >> 16;
		int tmp_MaxY = (pItemDef->m_ttContainer.m_dwMaxXY & 0xFFFF);
		DEBUG_WARN(("Custom container gump id %d for 0%x\n", gump, GetDispID()));
		return( CPointMap(
			static_cast<WORD>(tmp_MinX + Calc_GetRandVal(tmp_MaxX - tmp_MinX)),
			static_cast<WORD>(tmp_MinY + Calc_GetRandVal(tmp_MaxY - tmp_MinY)),
			0 ));
	}
Exemplo n.º 18
0
void CWorld::GetHeightPoint2( const CPointMap & pt, CGrayMapBlockState & block, bool fHouseCheck )
{
	ADDTOCALLSTACK("CWorld::GetHeightPoint2");
	// Height of statics at/above given coordinates
	// do gravity here for the z.

	DWORD wBlockThis = 0;
	const CGrayMapBlock * pMapBlock = GetMapBlock( pt );
	if ( !pMapBlock )
	{
		g_Log.EventWarn("GetMapBlock failed at %s.\n", pt.WriteUsed());
		return;
	}

	{
		size_t iStaticQty = pMapBlock->m_Statics.GetStaticQty();
		if ( iStaticQty > 0 )  // no static items here.
		{
			int x2 = pMapBlock->GetOffsetX(pt.m_x);
			int y2 = pMapBlock->GetOffsetY(pt.m_y);
			for ( size_t i = 0; i < iStaticQty; i++ )
			{
				if ( ! pMapBlock->m_Statics.IsStaticPoint( i, x2, y2 ))
					continue;
				const CUOStaticItemRec * pStatic = pMapBlock->m_Statics.GetStatic( i );
				signed char z = pStatic->m_z;
				if ( ! block.IsUsableZ(z,PLAYER_HEIGHT))
					continue;

				// This static is at the coordinates in question.
				// enough room for me to stand here ?
				wBlockThis = 0;
				height_t zHeight = CItemBase::GetItemHeight( pStatic->GetDispID(), wBlockThis );
				block.CheckTile( wBlockThis, z, zHeight, pStatic->GetDispID() + TERRAIN_QTY );
			}
		}
	}

	// Any multi items here ?
	if ( fHouseCheck )
	{
		CRegionLinks rlinks;
		size_t iRegionQty = pt.GetRegions( REGION_TYPE_MULTI, rlinks );
		if ( iRegionQty > 0 )
		{
			for ( size_t i = 0; i < iRegionQty; i++)
			{
				CRegionBase * pRegion = rlinks.GetAt(i);
				CItem * pItem = pRegion->GetResourceID().ItemFind();
				if ( pItem != NULL )
				{
					const CGrayMulti * pMulti = g_Cfg.GetMultiItemDefs(pItem);
					if ( pMulti )
					{
						int x2 = pt.m_x - pItem->GetTopPoint().m_x;
						int y2 = pt.m_y - pItem->GetTopPoint().m_y;

						size_t iMultiQty = pMulti->GetItemCount();
						for ( size_t j = 0; j < iMultiQty; j++ )
						{
							const CUOMultiItemRec2 * pMultiItem = pMulti->GetItem(j);
							ASSERT(pMultiItem);

							if ( ! pMultiItem->m_visible )
								continue;
							if ( pMultiItem->m_dx != x2 || pMultiItem->m_dy != y2 )
								continue;

							signed char zitem = static_cast<signed char>( pItem->GetTopZ() + pMultiItem->m_dz );
							if ( ! block.IsUsableZ(zitem,PLAYER_HEIGHT))
								continue;

							wBlockThis = 0;
							height_t zHeight = CItemBase::GetItemHeight( pMultiItem->GetDispID(), wBlockThis );
							block.CheckTile( wBlockThis, zitem, zHeight, pMultiItem->GetDispID() + TERRAIN_QTY );
						}
					}
				}
			}
		}
	}

	{
	// Any dynamic items here ?
	// NOTE: This could just be an item that an NPC could just move ?
	CWorldSearch Area( pt );
	for (;;)
	{
		CItem * pItem = Area.GetItem();
		if ( pItem == NULL )
			break;

		signed char zitem = pItem->GetTopZ();
		if ( ! block.IsUsableZ(zitem,PLAYER_HEIGHT))
			continue;

		// Invis items should not block ???
		CItemBase * pItemDef = pItem->Item_GetDef();
		ASSERT(pItemDef);

		// Get Attributes from ItemDef. If they are not set, get them from the static object (DISPID)
		wBlockThis = pItemDef->m_Can & (CAN_I_DOOR | CAN_I_WATER | CAN_I_CLIMB | CAN_I_BLOCK | CAN_I_PLATFORM);
		height_t zHeight = pItemDef->GetHeight();

		DWORD wStaticBlockThis = 0;
		height_t zStaticHeight = CItemBase::GetItemHeight(pItem->GetDispID(), wStaticBlockThis);

		if (wBlockThis == 0)
			wBlockThis = wStaticBlockThis;
		if (zHeight == 0)
			zHeight = zStaticHeight;

		if ( !block.CheckTile( 
			wBlockThis,
			zitem, zHeight, pItemDef->GetDispID() + TERRAIN_QTY ) )
		{
		}
	}
	}

	// Check Terrain here.
	// Terrain height is screwed. Since it is related to all the terrain around it.

	{
	const CUOMapMeter * pMeter = pMapBlock->GetTerrain( UO_BLOCK_OFFSET(pt.m_x), UO_BLOCK_OFFSET(pt.m_y));
	ASSERT(pMeter);

	if ( block.IsUsableZ(pMeter->m_z,0))
	{
		if ( pMeter->m_wTerrainIndex == TERRAIN_HOLE )
			wBlockThis = 0;
		else if ( pMeter->m_wTerrainIndex == TERRAIN_NULL )	// inter dungeon type.
			wBlockThis = CAN_I_BLOCK;
		else
		{
			CGrayTerrainInfo land( pMeter->m_wTerrainIndex );
			if ( land.m_flags & UFLAG2_PLATFORM ) // Platform items should take precendence over non-platforms.
				wBlockThis = CAN_I_PLATFORM;
			else if ( land.m_flags & UFLAG1_WATER )
				wBlockThis = CAN_I_WATER;
			else if ( land.m_flags & UFLAG1_DAMAGE )
				wBlockThis = CAN_I_FIRE;
			else if ( land.m_flags & UFLAG1_BLOCK )
				wBlockThis = CAN_I_BLOCK;
			else
				wBlockThis = CAN_I_PLATFORM;
		}
		block.CheckTile( wBlockThis, pMeter->m_z, 0, pMeter->m_wTerrainIndex );
	}
	}

	if ( block.m_Bottom.m_z == UO_SIZE_MIN_Z )
	{
		block.m_Bottom = block.m_Lowest;
	}
}
Exemplo n.º 19
0
bool CChar::CanSeeLOS_New( const CPointMap &ptDst, CPointMap *pptBlock, int iMaxDist, word flags, bool bCombatCheck ) const
{
	ADDTOCALLSTACK("CChar::CanSeeLOS_New");
	// WARNING: CanSeeLOS is an expensive function (lot of calculations but	most importantly it has to read the UO files, and file I/O is slow).

	if ( !bCombatCheck && IsPriv(PRIV_GM) )	// If i'm checking the LOS during a combat, i don't want to shoot through the walls even if i'm a GM
	{
		WARNLOS(("GM Pass\n"));
		return true;
	}

	CPointMap ptSrc = GetTopPoint();
	CPointMap ptNow(ptSrc);

	if ( ptSrc.m_map != ptDst.m_map )	// Different map
		return this->CanSeeLOS_New_Failed(pptBlock, ptNow);

	if ( ptSrc == ptDst )	// Same point ^^
		return true;

	short iTotalZ = ptSrc.m_z + GetHeightMount(true);
	ptSrc.m_z = (char)minimum(iTotalZ, UO_SIZE_Z);	//true - substract one from the height because of eyes height
	WARNLOS(("Total Z: %d\n", ptSrc.m_z));

	int dx, dy, dz;
	dx = ptDst.m_x - ptSrc.m_x;
	dy = ptDst.m_y - ptSrc.m_y;
	dz = ptDst.m_z - ptSrc.m_z;

    float dist2d, dist3d;
	dist2d = sqrt((float)(dx*dx + dy*dy));
	if ( dz )
		dist3d = sqrt((float)(dist2d*dist2d + dz*dz));
	else
		dist3d = dist2d;

	if ( APPROX(dist2d) > (float)iMaxDist )
	{
		WARNLOS(("( APPROX(dist2d)(%f) > ((double)iMaxDist)(%f) ) --> NOLOS\n", APPROX(dist2d), (float)iMaxDist));
		return CanSeeLOS_New_Failed(pptBlock, ptNow);
	}

	float dFactorX, dFactorY, dFactorZ;
	dFactorX = dx / dist3d;
	dFactorY = dy / dist3d;
	dFactorZ = dz / dist3d;

    float nPx, nPy, nPz;
	nPx = ptSrc.m_x;
	nPy = ptSrc.m_y;
	nPz = ptSrc.m_z;

	std::vector<CPointMap> path;
	for (;;)
	{
		if ( BETWEENPOINT(nPx, ptDst.m_x, ptSrc.m_x) && BETWEENPOINT(nPy, ptDst.m_y, ptSrc.m_y) && BETWEENPOINT(nPz, ptDst.m_z, ptSrc.m_z) )
		{
			dx = (int)APPROX(nPx);
			dy = (int)APPROX(nPy);
			dz = (int)APPROX(nPz);

			// Add point to vector
			if ( !path.empty() )
			{
				CPointMap ptEnd = path[path.size() - 1];
				if ( ptEnd.m_x != dx || ptEnd.m_y != dy || ptEnd.m_z != dz )
					path.emplace_back((word)dx, (word)dy, (char)dz, ptSrc.m_map);
			}
			else
			{
				path.emplace_back((word)dx, (word)dy, (char)dz, ptSrc.m_map);
			}
			WARNLOS(("PATH X:%d Y:%d Z:%d\n", dx, dy, dz));

			nPx += dFactorX;
			nPy += dFactorY;
			nPz += dFactorZ;
		}
		else
			break;
	}

	if ( !path.empty() )
	{
		if ( path[path.size() - 1] != ptDst )
			path.emplace_back(ptDst.m_x, ptDst.m_y, ptDst.m_z, ptDst.m_map);
	}
	else
	{
		path.clear();
		return CanSeeLOS_New_Failed(pptBlock, ptNow);
	}

	WARNLOS(("Path calculated %" PRIuSIZE_T "\n", path.size()));
	// Ok now we should loop through all the points and checking for maptile, staticx, items, multis.
	// If something is in the way and it has the wrong flags LOS return false

	const CServerMapBlock *pBlock			= nullptr;		// Block of the map (for statics)
	const CUOStaticItemRec *pStatic			= nullptr;		// Statics iterator (based on SphereMapBlock)
	const CSphereMulti *pMulti 				= nullptr;		// Multi Def (multi check)
	const CUOMultiItemRec_HS *pMultiItem	= nullptr;		// Multi item iterator
	CRegion *pRegion					= nullptr;		// Nulti regions
	CRegionLinks rlinks;								// Links to multi regions
	CItem *pItem						= nullptr;
	CItemBase *pItemDef 				= nullptr;
	CItemBaseDupe *pDupeDef				= nullptr;

	dword wTFlags = 0;
	height_t Height = 0;
	word terrainid = 0;
	bool bPath = true;
	bool bNullTerrain = false;

	CRegion *pSrcRegion = ptSrc.GetRegion(REGION_TYPE_AREA|REGION_TYPE_ROOM|REGION_TYPE_MULTI);
	CRegion *pNowRegion = nullptr;

	int lp_x = 0, lp_y = 0;
	short min_z = 0, max_z = 0;

	for (uint i = 0, pathSize = uint(path.size()); i < pathSize; lp_x = ptNow.m_x, lp_y = ptNow.m_y, pItemDef = nullptr, pStatic = nullptr, pMulti = nullptr, pMultiItem = nullptr, min_z = 0, max_z = 0, ++i )
	{
		ptNow = path[i];
		WARNLOS(("---------------------------------------------\n"));
		WARNLOS(("Point %d,%d,%d \n", ptNow.m_x, ptNow.m_y, ptNow.m_z));

		pNowRegion = ptNow.GetRegion(REGION_TYPE_AREA|REGION_TYPE_ROOM|REGION_TYPE_MULTI);

		if ( (flags & LOS_NO_OTHER_REGION) && (pSrcRegion != pNowRegion) )
		{
			WARNLOS(("flags & 0200 and path is leaving my region - BLOCK\n"));
			bPath = false;
			break;
		}

		if ( (flags & LOS_NC_MULTI) && ptNow.GetRegion(REGION_TYPE_MULTI) && (ptNow.GetRegion(REGION_TYPE_MULTI) != ptSrc.GetRegion(REGION_TYPE_MULTI)) )
		{
			WARNLOS(("flags & 0400 and path is crossing another multi - BLOCK\n"));
			bPath = false;
			break;
		}

		if ( (lp_x != ptNow.m_x) || (lp_y != ptNow.m_y) )
		{
			WARNLOS(("\tLoading new map block.\n"));
			pBlock = g_World.GetMapBlock(ptNow);
		}

		if ( !pBlock ) // something is wrong
		{
			WARNLOS(("GetMapBlock Failed\n"));
			bPath = false;
			break;
		}

		if ( !(flags & LOS_NB_TERRAIN) )
		{
			if ( !((flags & LOS_NB_LOCAL_TERRAIN) && (pSrcRegion == pNowRegion)) )
			{
				// ------ MapX.mul Check ----------
				terrainid = pBlock->GetTerrain(UO_BLOCK_OFFSET(ptNow.m_x), UO_BLOCK_OFFSET(ptNow.m_y))->m_wTerrainIndex;
				WARNLOS(("Terrain %d\n", terrainid));

				if ( (flags & LOS_FISHING) && (ptSrc.GetDist(ptNow) >= 2) && (g_World.GetTerrainItemType(terrainid) != IT_WATER) && (g_World.GetTerrainItemType(terrainid) != IT_NORMAL) )
				{
					WARNLOS(("Terrain %d blocked - flags & LOS_FISHING, distance >= 2 and type of pItemDef is not IT_WATER\n", terrainid));
					WARNLOS(("ptSrc: %d,%d,%d; ptNow: %d,%d,%d; terrainid: %d; terrainid type: %d\n", ptSrc.m_x, ptSrc.m_y, ptSrc.m_z, ptNow.m_x, ptNow.m_y, ptNow.m_z, terrainid, g_World.GetTerrainItemType(terrainid)));
					bPath = false;
					break;
				}

				//#define MAPTILEMIN minimum(minimum(minimum(pBlock->GetTerrain(0,0)->m_z, pBlock->GetTerrain(0,1)->m_z), pBlock->GetTerrain(1,0)->m_z), pBlock->GetTerrain(1,1)->m_z)
				//#define MAPTILEMAX maximum(maximum(maximum(pBlock->GetTerrain(0,0)->m_z, pBlock->GetTerrain(0,1)->m_z), pBlock->GetTerrain(1,0)->m_z), pBlock->GetTerrain(1,1)->m_z);
				//#define MAPTILEZ pBlock->GetTerrain(UO_BLOCK_OFFSET(ptNow.m_x), UO_BLOCK_OFFSET(ptNow.m_y))->m_z;

				if ( (terrainid != TERRAIN_HOLE) && (terrainid != 475) )
				{
					if ( terrainid < 430 || terrainid > 437 )
					{
						/*this stuff should do some checking for surrounding items:
						aaa
						aXa
						aaa
						min_z is determined as a minimum of all a/X terrain, where X is ptNow
						*/
						byte pos_x = UO_BLOCK_OFFSET(ptNow.m_x) > 1 ? UO_BLOCK_OFFSET(ptNow.m_x - 1) : 0;
						byte pos_y = UO_BLOCK_OFFSET(ptNow.m_y) > 1 ? UO_BLOCK_OFFSET(ptNow.m_y - 1) : 0;
						const byte defx = UO_BLOCK_OFFSET(ptNow.m_x);
						const byte defy = UO_BLOCK_OFFSET(ptNow.m_y);
						min_z = pBlock->GetTerrain(pos_x, pos_y)->m_z;
						max_z = pBlock->GetTerrain(defx, defy)->m_z;
						for ( byte posy = pos_y; (abs(defx - UO_BLOCK_OFFSET(pos_x)) <= 1 && pos_x <= 7); ++pos_x )
						{
							for ( pos_y = posy; (abs(defy - UO_BLOCK_OFFSET(pos_y)) <= 1 && pos_y <= 7); ++pos_y )
							{
								char terrain_z = pBlock->GetTerrain(pos_x, pos_y)->m_z;
								min_z = minimum(min_z, terrain_z);
							}
						}
						//min_z = MAPTILEZ;
						//max_z = MAPTILEZ;
						WARNLOS(("Terrain %d - m:%d M:%d\n", terrainid, min_z, max_z));
						if ( CUOMapMeter::IsTerrainNull(terrainid) )
							bNullTerrain = true; //what if there are some items on that hole?
						if ( (min_z <= ptNow.m_z && max_z >= ptNow.m_z) && (ptNow.m_x != ptDst.m_x || ptNow.m_y != ptDst.m_y || min_z > ptDst.m_z || max_z < ptDst.m_z) )
						{
							WARNLOS(("Terrain %d - m:%d M:%d - block\n", terrainid, min_z, max_z));
							bPath = false;
							break;
						}
						CUOTerrainInfo land(terrainid);
						if ( (land.m_flags & UFLAG1_WATER) && (flags & LOS_NC_WATER) )
							bNullTerrain = true;
					}
				}
				//#undef MAPTILEMIN
				//#undef MAPTILEMAX
				//#undef MAPTILEZ
			}
		}

		// ------ StaticsX.mul Check --------
		if ( !(flags & LOS_NB_STATIC) )
		{
			if ( !((flags & LOS_NB_LOCAL_STATIC) && (pSrcRegion == pNowRegion)) )
			{
                uint uiStaticMaxQty = pBlock->m_Statics.GetStaticQty();
				for ( uint s = 0; s < uiStaticMaxQty; pStatic = nullptr, pItemDef = nullptr, ++s )
				{
					pStatic = pBlock->m_Statics.GetStatic(s);
					if ( (pStatic->m_x + pBlock->m_x != ptNow.m_x) || (pStatic->m_y + pBlock->m_y != ptNow.m_y) )
						continue;

					//Fix for Stacked items blocking view
					if ( (pStatic->m_x == ptDst.m_x) && (pStatic->m_y == ptDst.m_y) && (pStatic->m_z >= GetTopZ()) && (pStatic->m_z <= ptSrc.m_z) )
						continue;

					pItemDef = CItemBase::FindItemBase(pStatic->GetDispID());
					wTFlags = 0;
					Height = 0;
					bNullTerrain = false;

					if ( !pItemDef )
					{
						WARNLOS(("STATIC - Cannot get pItemDef for item (0%x)\n", pStatic->GetDispID()));
					}
					else
					{
                        if (pItemDef->Can(CAN_I_BLOCKLOS))
                        {
                            WARNLOS(("pStatic blocked by CAN_I_BLOCKLOS"));
                            bPath = false;
                            break;
                        }

						if ( (flags & LOS_FISHING) && (ptSrc.GetDist(ptNow) >= 2) && (pItemDef->GetType() != IT_WATER) &&
							( pItemDef->Can(CAN_I_DOOR | CAN_I_PLATFORM | CAN_I_BLOCK | CAN_I_CLIMB | CAN_I_FIRE | CAN_I_ROOF | CAN_I_BLOCKLOS | CAN_I_BLOCKLOS_HEIGHT)) )
						{
							WARNLOS(("pStatic blocked - flags & 0800, distance >= 2 and type of pItemDef is not IT_WATER\n"));
							bPath = false;
							break;
						}

						wTFlags = pItemDef->GetTFlags();
						Height = pItemDef->GetHeight();

						if ( pItemDef->GetID() != pStatic->GetDispID() ) //not a parent item
						{
							WARNLOS(("Not a parent item (STATIC)\n"));
							pDupeDef = CItemBaseDupe::GetDupeRef((ITEMID_TYPE)(pStatic->GetDispID()));
							if ( !pDupeDef )
							{
								g_Log.EventDebug("AdvancedLoS: Failed to get non-parent reference (static) (DispID 0%x) (X: %d Y: %d Z: %hhd M: %hhu)\n", pStatic->GetDispID(), ptNow.m_x, ptNow.m_y, pStatic->m_z, ptNow.m_map);
							}
							else
							{
								wTFlags = pDupeDef->GetTFlags();
								Height = pDupeDef->GetHeight();
							}
						}
						else
						{
							WARNLOS(("Parent item (STATIC)\n"));
						}

						Height = (wTFlags & UFLAG2_CLIMBABLE) ? Height / 2 : Height;

						if ( ((wTFlags & (UFLAG1_WALL|UFLAG1_BLOCK|UFLAG2_PLATFORM)) || (pItemDef->Can(CAN_I_BLOCKLOS_HEIGHT))) && !((wTFlags & UFLAG2_WINDOW) && (flags & LOS_NB_WINDOWS)) )
						{
							WARNLOS(("pStatic %0x %d,%d,%d - %d\n", pStatic->GetDispID(), pStatic->m_x, pStatic->m_y, pStatic->m_z, Height));
							min_z = pStatic->m_z;
							max_z = minimum(Height + min_z, UO_SIZE_Z);
							WARNLOS(("wTFlags(0%x)\n", wTFlags));

							WARNLOS(("pStatic %0x Z check: %d,%d (Now: %d) (Dest: %d).\n", pStatic->GetDispID(), min_z, max_z, ptNow.m_z, ptDst.m_z));
							if ( (min_z <= ptNow.m_z) && (max_z >= ptNow.m_z) )
							{
								if ( ptNow.m_x != ptDst.m_x || ptNow.m_y != ptDst.m_y || min_z > ptDst.m_z || max_z < ptDst.m_z )
								{
									WARNLOS(("pStatic blocked - m:%d M:%d\n", min_z, max_z));
									bPath = false;
									break;
								}
							}
						}
					}
				}
			}
		}

		if ( !bPath )
			break;

		// --------- In game items ----------
		if ( !(flags & LOS_NB_DYNAMIC) )
		{
			if ( !((flags & LOS_NB_LOCAL_DYNAMIC) && (pSrcRegion == pNowRegion)) )
			{
				CWorldSearch AreaItems(ptNow, 0);
				for (;;)
				{
					pItem = AreaItems.GetItem();
					if ( !pItem )
						break;
					if ( pItem->GetUnkPoint().m_x != ptNow.m_x || pItem->GetUnkPoint().m_y != ptNow.m_y )
						continue;
					if ( !CanSeeItem(pItem) )
						continue;

					//Fix for Stacked items blocking view
					if ( (pItem->GetUnkPoint().m_x == ptDst.m_x) && (pItem->GetUnkPoint().m_y == ptDst.m_y) && (pItem->GetUnkPoint().m_z >= GetTopZ()) && (pItem->GetUnkPoint().m_z <= ptSrc.m_z) )
						continue;

					pItemDef = static_cast<CItemBase*>(pItem->Base_GetDef());
					wTFlags = 0;
					Height = 0;
					bNullTerrain = false;

					if ( !pItemDef )
					{
						WARNLOS(("DYNAMIC - Cannot get pItemDef for item (0%x)\n", pItem->GetDispID()));
					}
					else
					{
                        if (pItem->Can(CAN_I_BLOCKLOS))
                        {
                            WARNLOS(("pItem blocked by CAN_I_BLOCKLOS"));
                            bPath = false;
                            break;
                        }

						if ( (flags & LOS_FISHING) && (ptSrc.GetDist(ptNow) >= 2) && (pItem->GetType() != IT_WATER) &&
							( pItem->Can(CAN_I_DOOR | CAN_I_PLATFORM | CAN_I_BLOCK | CAN_I_CLIMB | CAN_I_FIRE | CAN_I_ROOF | CAN_I_BLOCKLOS | CAN_I_BLOCKLOS_HEIGHT) ) )
						{
							WARNLOS(("pItem blocked - flags & 0800, distance >= 2 and type of pItemDef is not IT_WATER\n"));
							bPath = false;
							break;
							//return CanSeeLOS_New_Failed(pptBlock, ptNow);
						}

						wTFlags = pItemDef->GetTFlags();
						Height = pItemDef->GetHeight();

						if ( pItemDef->GetID() != pItem->GetDispID() )	//not a parent item
						{
							WARNLOS(("Not a parent item (DYNAMIC)\n"));
							pDupeDef = CItemBaseDupe::GetDupeRef((ITEMID_TYPE)(pItem->GetDispID()));
							if ( !pDupeDef )
							{
                                // Not an error: i have changed the DISPID of the item.
                                CItemBase* pParentDef = CItemBase::FindItemBase(pItem->GetDispID());
                                if (pParentDef)
                                {
                                    wTFlags = pParentDef->GetTFlags();
                                    Height = pParentDef->GetHeight();
                                }
                                else
                                    g_Log.EventDebug("AdvancedLoS: Failed to get reference (dynamic): non-dupe, baseless dispid (DispID 0%x) (X: %d Y: %d Z: %hhd M: %hhu)\n", pItem->GetDispID(), ptNow.m_x, ptNow.m_y, pItem->GetUnkZ(), ptNow.m_map);
							}
							else
							{
                                // It's a dupe item
								wTFlags = pDupeDef->GetTFlags();
								Height = pDupeDef->GetHeight();
							}
						}
						else
						{
							WARNLOS(("Parent item (DYNAMIC)\n"));
						}

						Height = (wTFlags & UFLAG2_CLIMBABLE) ? Height / 2 : Height;

						if ( ((wTFlags & (UFLAG1_WALL|UFLAG1_BLOCK|UFLAG2_PLATFORM)) || pItem->Can(CAN_I_BLOCKLOS_HEIGHT)) && !((wTFlags & UFLAG2_WINDOW) && (flags & LOS_NB_WINDOWS)) )
						{
							WARNLOS(("pItem %0x(%0x) %d,%d,%d - %d\n", (dword)pItem->GetUID(), pItem->GetDispID(), pItem->GetUnkPoint().m_x, pItem->GetUnkPoint().m_y, pItem->GetUnkPoint().m_z, Height));
							min_z = pItem->GetUnkPoint().m_z;
							max_z = minimum(Height + min_z, UO_SIZE_Z);
							WARNLOS(("wTFlags(0%x)\n", wTFlags));

							WARNLOS(("pItem %0x(%0x) Z check: %d,%d (Now: %d) (Dest: %d).\n", (dword)pItem->GetUID(), pItem->GetDispID(), min_z, max_z, ptNow.m_z, ptDst.m_z));
							if ( min_z <= ptNow.m_z && max_z >= ptNow.m_z )
							{
								if ( ptNow.m_x != ptDst.m_x || ptNow.m_y != ptDst.m_y || min_z > ptDst.m_z || max_z < ptDst.m_z )
								{
									WARNLOS(("pItem blocked - m:%d M:%d\n", min_z, max_z));
									bPath = false;
									break;
								}
							}
						}
					}
				}
			}
		}

		if ( !bPath )
			break;

		// ----------- Multis ---------------

		if ( !(flags & LOS_NB_MULTI) )
		{
			if ( !((flags & LOS_NB_LOCAL_MULTI) && (pSrcRegion == pNowRegion)) )
			{
				size_t iQtyr = ptNow.GetRegions(REGION_TYPE_MULTI, &rlinks);
				if ( iQtyr > 0 )
				{
					for ( size_t ii = 0; ii < iQtyr; pMulti = nullptr, ++ii, pItem = nullptr, pRegion = nullptr )
					{
						pRegion = rlinks[ii];
						if ( pRegion )
							pItem = pRegion->GetResourceID().ItemFindFromResource();

						if ( !pItem )
							continue;

						pMulti = g_Cfg.GetMultiItemDefs(pItem);
						if ( !pMulti )
							continue;

						uint iQty = pMulti->GetItemCount();
						for ( uint iii = 0; iii < iQty; pItemDef = nullptr, pMultiItem = nullptr, ++iii )
						{
							pMultiItem = pMulti->GetItem(iii);
							if ( !pMultiItem )
								break;
							if ( !pMultiItem->m_visible )
								continue;
							if ( (pMultiItem->m_dx + pItem->GetTopPoint().m_x != ptNow.m_x) || (pMultiItem->m_dy + pItem->GetTopPoint().m_y != ptNow.m_y) )
								continue;

							pItemDef = CItemBase::FindItemBase(pMultiItem->GetDispID());
							wTFlags = 0;
							Height = 0;
							bNullTerrain = false;

							if ( !pItemDef )
							{
								WARNLOS(("MULTI - Cannot get pItemDef for item (0%x)\n", pMultiItem->GetDispID()));
							}
							else
							{
                                if (pItemDef->Can(CAN_I_BLOCKLOS))
                                {
                                    WARNLOS(("pMultiItem blocked by CAN_I_BLOCKLOS"));
                                    bPath = false;
                                    break;
                                }

								if ( (flags & LOS_FISHING) && (ptSrc.GetDist(ptNow) >= 2) && (pItemDef->GetType() != IT_WATER) &&
									( pItemDef->Can(CAN_I_DOOR | CAN_I_PLATFORM | CAN_I_BLOCK | CAN_I_CLIMB | CAN_I_FIRE | CAN_I_ROOF | CAN_I_BLOCKLOS | CAN_I_BLOCKLOS_HEIGHT) ) )
								{
									WARNLOS(("pMultiItem blocked - flags & 0800, distance >= 2 and type of pItemDef is not IT_WATER\n"));
									bPath = false;
									break;
									//return CanSeeLOS_New_Failed(pptBlock, ptNow);
								}

								wTFlags = pItemDef->GetTFlags();
								Height = pItemDef->GetHeight();

								if ( pItemDef->GetID() != pMultiItem->GetDispID() ) //not a parent item
								{
									WARNLOS(("Not a parent item (MULTI)\n"));
									pDupeDef = CItemBaseDupe::GetDupeRef((ITEMID_TYPE)(pMultiItem->GetDispID()));
									if ( !pDupeDef )
									{
										g_Log.EventDebug("AdvancedLoS: Failed to get non-parent reference (multi) (DispID 0%x) (X: %d Y: %d Z: %hhd M: %hhu)\n", pMultiItem->GetDispID(), ptNow.m_x, ptNow.m_y, pMultiItem->m_dz + pItem->GetTopPoint().m_z, ptNow.m_map);
									}
									else
									{
										wTFlags = pDupeDef->GetTFlags();
										Height = pDupeDef->GetHeight();
									}
								}
								else
								{
									WARNLOS(("Parent item (MULTI)\n"));
								}

								Height = (wTFlags & UFLAG2_CLIMBABLE) ? Height / 2 : Height;

								if ( ((wTFlags & (UFLAG1_WALL|UFLAG1_BLOCK|UFLAG2_PLATFORM) || pItemDef->Can(CAN_I_BLOCKLOS_HEIGHT))) && !((wTFlags & UFLAG2_WINDOW) && (flags & LOS_NB_WINDOWS)) )
								{
									WARNLOS(("pMultiItem %0x %d,%d,%d - %d\n", pMultiItem->GetDispID(), pMultiItem->m_dx, pMultiItem->m_dy, pMultiItem->m_dz, Height));
									min_z = (char)(pMultiItem->m_dz) + pItem->GetTopPoint().m_z;
									max_z = minimum(Height + min_z, UO_SIZE_Z);
									WARNLOS(("wTFlags(0%x)\n", wTFlags));

									if ( min_z <= ptNow.m_z && max_z >= ptNow.m_z )
									{
										if ( ptNow.m_x != ptDst.m_x || ptNow.m_y != ptDst.m_y || min_z > ptDst.m_z || max_z < ptDst.m_z )
										{
											WARNLOS(("pMultiItem blocked - m:%d M:%d\n", min_z, max_z));
											bPath = false;
											break;
										}
									}
								}
							}
						}

						if ( !bPath )
							break;
					}
				}
			}
		}

		if ( bNullTerrain )
			bPath = false;

		if ( !bPath )
			break;
	}

	path.clear();

	if ( !bPath )
		return CanSeeLOS_New_Failed(pptBlock, ptNow);

	return true;
}
Exemplo n.º 20
0
void CWndVendorCtrl::OnDraw( C2DRender* p2DRender )
{
	if( m_pMover == NULL )
		return;
	
	CRect rect	= GetClientRect();
	int nWidth	= rect.Width() / 32;
	int nHeight		= rect.Height() / 35;

#if __VER >= 8 //__S8_VENDOR_REVISION
	for( int i = 0; i < MAX_VENDOR_REVISION; i++ )
#else //__S8_VENDOR_REVISION
	for( int i = 0; i < MAX_VENDITEM; i++ )
#endif //__S8_VENDOR_REVISION
	{
		int x	= i % 2;
		int y	= i / 2;
		
		int nX;
		int nY = y * 32 + 8 + y * 4;
		if( x == 0 )
			nX = x * 32 + 15;
		else
			nX = 235;

		CRect rectHittest = CRect( nX, nY, nX + 180, nY + 32 );
		CPoint point	= GetMousePoint();
		if( rectHittest.PtInRect( point ) )
		{
			if( CWndBase::m_GlobalShortcut.m_dwData )
			{
				m_nCurSel = -1;
				{
					CPoint ptx = CPoint(nX, nY);
					m_pTex->Render( p2DRender, ptx );		// 아이템 테두리 그리기
				}
			}
		}			
		CItemBase* pItemBase = GetItem( i );
		if( pItemBase )
		{

			// 툴팁
			float fScal = 1.0f;
			CPoint point	= GetMousePoint();
			if( rectHittest.PtInRect( point ) )
			{
				fScal = 1.15f;
				CPoint point2 = point;
				ClientToScreen( &point2 );
				ClientToScreen( &rectHittest );
				g_WndMng.PutToolTip_Item( pItemBase, point2, &rectHittest, APP_VENDOR );
			}

			// 아이템 아이콘 
			if( ((CItemElem*)pItemBase)->IsFlag( CItemElem::expired ) )
				pItemBase->GetTexture()->Render2( p2DRender, CPoint( nX, nY ), D3DCOLOR_XRGB( 255, 100, 100 ) );					
			else
				pItemBase->GetTexture()->Render2( p2DRender, CPoint( nX, nY ), D3DCOLOR_XRGB( 255, 255, 255 ), fScal, fScal );

			// 아이템 이름, 판매가격
			OnDrawItemInfo( p2DRender, ((CItemElem*)pItemBase), nX, nY );

			if( i == m_nCurSel )
				p2DRender->RenderRect( CRect( nX, nY, nX + 32, nY + 32 ), 0xff00ffff );
			CItemElem* pItemElem	= (CItemElem*)pItemBase;
			if( pItemElem->GetProp()->dwPackMax > 1 )
			{
				short nItemNum	= pItemBase->GetExtra();
				TCHAR szTemp[32];
				_stprintf( szTemp, "%d", nItemNum );
				CSize size	= p2DRender->m_pFont->GetTextExtent( szTemp );
				p2DRender->TextOut( nX - 7 + 32 - size.cx+5, nY - 11 + 32 - size.cy+12, szTemp, 0xff1010ff );
			}
		}
	}
}
Exemplo n.º 21
0
void CWndVendorCtrl::OnDraw( C2DRender* p2DRender )
{
	if( m_pMover == NULL )
		return;

	CRect rect	= GetClientRect();
	int nWidth	= rect.Width() / 32;
	int nHeight		= rect.Height() / 35;

	for( int i = 0; i < MAX_VENDITEM; i++ )
	{
		int x	= i % 6;
		int y	= i / 6;
		//p2DRender->RenderRect( CRect( x * 32 + 7, y * 32 + 11, x * 32 + 32 + 5, y * 32 + 32 + 9 ), 0xff00ffff );
		CRect rectHittest	= CRect( x * 32 + 7, y * 32 + 11, x * 32 + 32 + 5, y * 32 + 32 + 9 );

		CPoint point	= GetMousePoint();

		if( rectHittest.PtInRect( point ) )
		{
			if( CWndBase::m_GlobalShortcut.m_dwData )
			{
				m_nCurSel = -1;
				CPoint ptx = CPoint(x * 32 + 7, y * 32 + 11);
				{
					m_pTex->Render( p2DRender, ptx );
				}
			}
		}			
		CItemBase* pItemBase = GetItem( i );
		if( pItemBase )
		{
			if( ((CItemElem*)pItemBase)->IsFlag( CItemElem::expired ) )
			{
				pItemBase->GetTexture()->Render2( p2DRender, CPoint( x * 32 + 6, y * 32 + 10 ), D3DCOLOR_XRGB( 255, 100, 100 ) );
			}
			else
			{
				pItemBase->GetTexture()->Render( p2DRender, CPoint( x * 32 + 6, y * 32 + 10 ) );
			}

			CPoint point	= GetMousePoint();
			if( rectHittest.PtInRect( point ) )
			{
				CPoint point2 = point;
				ClientToScreen( &point2 );
				ClientToScreen( &rectHittest );
				g_WndMng.PutToolTip_Item( pItemBase, point2, &rectHittest, APP_VENDOR );
			}
			if( i == m_nCurSel )
				p2DRender->RenderRect( CRect( x * 32 + 7, y * 32 + 11, x * 32 + 32 + 5, y * 32 + 32 + 9 ), 0xff00ffff );
			CItemElem* pItemElem	= (CItemElem*)pItemBase;
			if( pItemElem->GetProp()->dwPackMax > 1 )
			{
				short nItemNum	= pItemBase->GetExtra();
				TCHAR szTemp[32];
				_stprintf( szTemp, "%d", nItemNum );
				CSize size	= p2DRender->m_pFont->GetTextExtent( szTemp );
				p2DRender->TextOut( x * 32 + 32 - size.cx+5, y * 32 + 32 - size.cy+12, szTemp, 0xff1010ff );
			}
		}
	}
}
Exemplo n.º 22
0
CPointMap CWorld::FindTypeNear_Top( const CPointMap & pt, IT_TYPE iType, int iDistance )
{
	ADDTOCALLSTACK("CWorld::FindTypeNear_Top");
#define RESOURCE_Z_CHECK 8
	CPointMap ptFound;
	CItemBase * pItemDef = NULL;
	CItem * pItem = NULL;
	CItemBaseDupe * pDupeDef = NULL;
	height_t Height = 0;
	BYTE z = 0;
	CPointMap ptTest;

	unsigned int iRetElem = 4;

	CPointMap ptElem[5];
	memset(ptElem, 0, sizeof(ptElem));
	//for ( iQty = 0; iQty < 4; ++iQty )
	//	ptElem[iQty].m_z = UO_SIZE_MIN_Z;
	ptElem[0].m_z = ptElem[1].m_z  = ptElem[2].m_z  = ptElem[3].m_z = UO_SIZE_MIN_Z;
	ptElem[4] = CPointMap(USHRT_MAX, USHRT_MAX, UO_SIZE_MIN_Z);

	bool fElem[4] = { false, false, false, false };

	// Check dynamics
	CWorldSearch Area( pt, iDistance );
	Area.SetAllShow( true );
	for (;;)
	{
		z = 0;
		Height = 0;
		pItem = Area.GetItem();
		if ( pItem == NULL )
			break;

		if ( pt.GetDist( pItem->GetTopPoint() ) > iDistance )
			continue;

		pItemDef = CItemBase::FindItemBase( pItem->GetDispID() );
		if ( pItemDef == NULL )
			continue;

		Height = pItemDef->GetHeight();
		if ( pItemDef->GetID() != pItem->GetDispID() ) //not a parent item
		{
			pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pItem->GetDispID()));
			if ( ! pDupeDef )
			{
				g_Log.EventDebug("Failed to get non-parent reference (dynamic) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pItem->GetDispID(),ptTest.m_x,ptTest.m_y,ptTest.m_z);
				Height = pItemDef->GetHeight();
			}
			else
				Height = pDupeDef->GetHeight();
		}
		z = minimum( Height + pItem->GetTopPoint().m_z, UO_SIZE_Z ); //height + current position = the top point

		if ( ptElem[0].m_z > z ) //if ( ptElem[0].m_z > pItem->GetTopPoint().m_z )
			continue;

		if ( ((( z - pt.m_z ) > 0) && ( z - pt.m_z ) > RESOURCE_Z_CHECK ) || ((( pt.m_z - z ) < 0) && (( pt.m_z - z ) < - RESOURCE_Z_CHECK ))) //if ( ((( pItem->GetTopPoint().m_z - pt.m_z ) > 0) && ( pItem->GetTopPoint().m_z - pt.m_z ) > RESOURCE_Z_CHECK ) || ((( pt.m_z - pItem->GetTopPoint().m_z ) < 0) && (( pt.m_z - pItem->GetTopPoint().m_z ) < - RESOURCE_Z_CHECK )))
			continue;

		if (( z < ptElem[0].m_z ) || (( z == ptElem[0].m_z ) && ( fElem[0] )))
			continue;
        
		ptElem[0] = pItem->GetTopPoint();
		ptElem[0].m_z = z;
		fElem[0] = false;

		//DEBUG_ERR(("dynamic pItem->IsType( iType %d) %d\n",iType,pItem->IsType( iType )));
		if ( pItem->IsType( iType ) )  //( pItem->Item_GetDef()->IsType(iType) ) )
		{
			fElem[0] = true;
			iRetElem = 0;
		}
	}

	// Parts of multis ?
	const CGrayMulti * pMulti 			= NULL;		// Multi Def (multi check)
	const CUOMultiItemRec2 * pMultiItem = NULL;		// Multi item iterator
	CRegionBase * pRegion				= NULL;
	CRegionLinks rlinks;
	size_t iRegionQty = pt.GetRegions( REGION_TYPE_MULTI, rlinks );
	if ( iRegionQty > 0 )
	{
		for ( size_t iRegion = 0; iRegion < iRegionQty; pMulti = NULL, ++iRegion)
		{
			pRegion = rlinks.GetAt(iRegion);
			pItem = pRegion->GetResourceID().ItemFind();
			if ( !pItem )
				continue;
			pMulti = g_Cfg.GetMultiItemDefs(pItem);
			if ( !pMulti )
				continue;
			size_t iMultiQty = pMulti->GetItemCount();
			for ( size_t iMulti = 0; iMulti < iMultiQty; pItemDef = NULL, pMultiItem = NULL, Height = 0, ++iMulti )
			{
				pMultiItem = pMulti->GetItem(iMulti);
				
				if ( !pMultiItem )
					break;

				//DEBUG_ERR(("abs( pMultiItem->m_dx ) %x, abs( pMultiItem->m_dy ) %x, abs( pMultiItem->m_dz ) %x,\n             iDistance %x IF STATEMENT %x %x\n", abs( pMultiItem->m_dx ), abs( pMultiItem->m_dy ), abs( pMultiItem->m_dz ), iDistance, ( abs( pMultiItem->m_dx ) <= iDistance ), ( abs( pMultiItem->m_dy ) <= iDistance ) ));

				if ( !pMultiItem->m_visible )
					continue;

				ptTest = CPointMap( pMultiItem->m_dx + pt.m_x, pMultiItem->m_dy + pt.m_y, static_cast<signed char>( pMultiItem->m_dz + pt.m_z ), pt.m_map );

				pItemDef = CItemBase::FindItemBase( pMultiItem->GetDispID() );
				if ( pItemDef == NULL )
					continue;

				Height = pItemDef->GetHeight();
				if ( pItemDef->GetID() != pMultiItem->GetDispID() ) //not a parent item
				{
					pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pMultiItem->GetDispID()));
					if ( ! pDupeDef )
					{
						g_Log.EventDebug("Failed to get non-parent reference (multi) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pMultiItem->GetDispID(),ptTest.m_x,ptTest.m_y,ptTest.m_z);
						Height = pItemDef->GetHeight();
					}
					else
						Height = pDupeDef->GetHeight();
				}
				ptTest.m_z = minimum(ptTest.m_z + Height, UO_SIZE_Z); //height + current position = the top point

				if ( pt.GetDist( ptTest ) > iDistance )
					continue;

				if ( ptElem[1].m_z > ptTest.m_z )
					continue;
		
				if ( ((( ptTest.m_z - pt.m_z ) > 0) && ( ptTest.m_z - pt.m_z ) > RESOURCE_Z_CHECK ) || ((( pt.m_z - ptTest.m_z ) < 0) && (( pt.m_z - ptTest.m_z ) < - RESOURCE_Z_CHECK )))
					continue;
	
				if (( ptTest.m_z < ptElem[1].m_z ) || (( ptTest.m_z == ptElem[1].m_z ) && ( fElem[1] )))
					continue;
		        //DEBUG_ERR(("pMultiItem->GetDispID()%x\n",pMultiItem->GetDispID()));
				ptElem[1] = ptTest;
				fElem[1] = false;

				//DEBUG_ERR(("multi pItemDef->IsType( iType %d) %d\n",iType,pItemDef->IsType( iType )));
				if ( pItemDef->IsType( iType ) )
				{
					fElem[1] = true;
					//if ( ptElem[iRetElem].m_z > ptElem[1].m_z )
					if ( ptElem[1].m_z > ptElem[iRetElem].m_z )
						iRetElem = 1;
				}

				//DEBUG_ERR(( "DISPID: %x X %d Y %d Z %d\n", pMultiItem->GetDispID(), (pMultiItem->m_dx), (pMultiItem->m_dy), (pMultiItem->m_dz) ));
			}
		}
	}

	// STATIC - checks one 8x8 block
	const CGrayMapBlock * pMapBlock = GetMapBlock( pt );
	ASSERT( pMapBlock );

	size_t iStaticQty = pMapBlock->m_Statics.GetStaticQty();
	if ( iStaticQty > 0 )  // no static items here.
	{
		const CUOStaticItemRec * pStatic = NULL;

		for ( size_t i = 0; i < iStaticQty; ++i, pStatic = NULL, Height = 0, pItemDef = NULL )
		{
			pStatic = pMapBlock->m_Statics.GetStatic( i );

			ptTest = CPointMap( pStatic->m_x + pMapBlock->m_x, pStatic->m_y + pMapBlock->m_y, pStatic->m_z, pt.m_map );

			pItemDef = CItemBase::FindItemBase( pStatic->GetDispID() );
			if ( pItemDef == NULL )
				continue;

			//DEBUG_ERR(("pStatic->GetDispID() %d; name %s; pStatic->m_z %d\n",pStatic->GetDispID(),pItemDef->GetName(),pStatic->m_z));
			Height = pItemDef->GetHeight();
			if ( pItemDef->GetID() != pStatic->GetDispID() ) //not a parent item
			{
				pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pStatic->GetDispID()));
				if ( ! pDupeDef )
				{
					g_Log.EventDebug("Failed to get non-parent reference (static) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pStatic->GetDispID(),ptTest.m_x,ptTest.m_y,ptTest.m_z);
					Height = pItemDef->GetHeight();
				}
				else
					Height = pDupeDef->GetHeight();
			}
			ptTest.m_z = minimum(ptTest.m_z + Height, UO_SIZE_Z); //height + current position = the top point

			if ( pt.GetDist( ptTest ) > iDistance )
				continue;

			if ( pt.GetDist( ptTest ) > iDistance )
				continue;

			//if ( ptElem[2].m_z > pStatic->m_z )
			if ( ptElem[2].m_z > ptTest.m_z )
				continue;

			if ( ((( pStatic->m_z - pt.m_z ) > 0) && ( pStatic->m_z - pt.m_z ) > RESOURCE_Z_CHECK ) || ((( pt.m_z - pStatic->m_z ) < 0) && (( pt.m_z - pStatic->m_z ) < - RESOURCE_Z_CHECK )))
				continue;

			if (( ptTest.m_z < ptElem[2].m_z ) || (( ptTest.m_z == ptElem[2].m_z ) && ( fElem[2] )))
				continue;

			ptElem[2] = ptTest;
			fElem[2] = false;

			//DEBUG_ERR(("static pItemDef->IsType( iType %d) %d;pItemDef->GetType() %d;pItemDef->GetID() %d;pItemDef->GetDispID() %d\n",iType,pItemDef->IsType( iType ),pItemDef->GetType(),pItemDef->GetID(),pItemDef->GetDispID()));
			if ( pItemDef->IsType( iType ) )
			{
				//DEBUG_ERR(("found %d; ptTest: %d,%d,%d\n",__LINE__,ptTest.m_x,ptTest.m_y,ptTest.m_z));
				fElem[2] = true;
				//DEBUG_ERR(("ptElem[iRetElem].m_z %d, ptElem[2].m_z %d\n",ptElem[iRetElem].m_z,ptElem[2].m_z));
				//if ( ptElem[iRetElem].m_z > ptElem[2].m_z )
				if ( ptElem[2].m_z > ptElem[iRetElem].m_z )
					iRetElem = 2;
			}
		}
	}

	// Check for appropriate terrain type
	CRectMap rect;
	rect.SetRect( pt.m_x - iDistance, pt.m_y - iDistance,
		pt.m_x + iDistance + 1, pt.m_y + iDistance + 1,
		pt.m_map);

	const CUOMapMeter * pMeter = NULL;
	for ( int x = rect.m_left; x < rect.m_right; ++x, pMeter = NULL )
	{
		for ( int y = rect.m_top; y < rect.m_bottom; ++y, pMeter = NULL )
		{
			ptTest = CPointMap(static_cast<WORD>(x), static_cast<WORD>(y), pt.m_z, pt.m_map);
			pMeter = GetMapMeter(ptTest);
			if ( !pMeter )
				continue;
			if ( pt.GetDist( ptTest ) > iDistance )
				continue;
			if ( ptElem[3].m_z > pMeter->m_z )
				continue;

			//DEBUG_ERR(("(( pMeter->m_z (%d) - pt.m_z (%d) ) > 0) && ( pMeter->m_z (%d) - pt.m_z (%d) ) > RESOURCE_Z_CHECK (%d) >> %d\n",pMeter->m_z,pt.m_z,pMeter->m_z,pt.m_z,RESOURCE_Z_CHECK,(( pMeter->m_z - pt.m_z ) > 0) && ( pMeter->m_z - pt.m_z ) > RESOURCE_Z_CHECK));
			//DEBUG_ERR(("(( pt.m_z (%d) - pMeter->m_z (%d) ) < 0) && (( pt.m_z (%d) - pMeter->m_z (%d) ) < - RESOURCE_Z_CHECK (%d) )) >> %d\n",pt.m_z,pMeter->m_z,pt.m_z,pMeter->m_z,- RESOURCE_Z_CHECK,((( pt.m_z - pMeter->m_z ) < 0) && (( pt.m_z - pMeter->m_z ) < - RESOURCE_Z_CHECK ))));
			if ( ((( pMeter->m_z - pt.m_z ) > 0) && ( pMeter->m_z - pt.m_z ) > RESOURCE_Z_CHECK ) || ((( pt.m_z - pMeter->m_z ) < 0) && (( pt.m_z - pMeter->m_z ) < - RESOURCE_Z_CHECK )))
				continue;

			//DEBUG_ERR(("pMeter->m_z (%d) < ptElem[3].m_z (%d) >> %d\n",pMeter->m_z,ptElem[3].m_z,pMeter->m_z < ptElem[3].m_z));
			if (( pMeter->m_z < ptElem[3].m_z ) || (( pMeter->m_z == ptElem[3].m_z ) && ( fElem[3] )))
				continue;

			ptElem[3] = ptTest;
			fElem[3] = false;

			//DEBUG_ERR(("iType %x, TerrainType %x\n",iType,g_World.GetTerrainItemType( pMeter->m_wTerrainIndex )));
			if ( iType == g_World.GetTerrainItemType( pMeter->m_wTerrainIndex ) )
			{
				fElem[3] = true;
				//if ( ptElem[iRetElem].m_z > ptElem[3].m_z )
				//DEBUG_ERR(("ptElem[3].m_z %d; ptElem[iRetElem].m_z %d\n",ptElem[3].m_z, ptElem[iRetElem].m_z));
				if ( ptElem[3].m_z > ptElem[iRetElem].m_z )
						iRetElem = 3;
				//DEBUG_ERR(("fElem3 %d %d\n",ptElem[3].m_z, fElem[3]));
				continue;
			}

			rect.SetRect( pt.m_x - iDistance, pt.m_y - iDistance, pt.m_x + iDistance + 1, pt.m_y + iDistance + 1, pt.m_map);
		}
	}

	/*CPointMap a;
	a.m_z = maximum(
	// priority dynamic->multi->static->terrain
	int iRetElem;
	if (( ptElem[0].m_z >= ptElem[1].m_z ) && ( fElem[0] ))
		iRetElem = 0;
	else if (( ptElem[1].m_z >= ptElem[2].m_z ) && ( fElem[1] ))
		iRetElem = 1;
	else if (( ptElem[2].m_z >= ptElem[3].m_z ) && ( fElem[2] ))
		iRetElem = 2;
	else if ( fElem[3] )
		iRetElem = 3;
	else
		iRetElem = 4;*/

	ASSERT(iRetElem < COUNTOF(ptElem));
	if ( 0 != iRetElem && ptElem[0].m_z > ptElem[iRetElem].m_z )
			 iRetElem = 4;
	else if ( 1 != iRetElem && ptElem[1].m_z > ptElem[iRetElem].m_z )
		     iRetElem = 4;
	else if ( 2 != iRetElem && ptElem[2].m_z > ptElem[iRetElem].m_z )
		     iRetElem = 4;
	else if ( 3 != iRetElem && ptElem[3].m_z > ptElem[iRetElem].m_z )
		     iRetElem = 4;

	//DEBUG_ERR(("iRetElem %d; %d %d %d %d; %d %d %d ISVALID: %d\n",iRetElem,ptElem[1].m_z,ptElem[2].m_z,ptElem[3].m_z,ptElem[4].m_z,pt.m_x,pt.m_y,pt.m_z,ptElem[iRetElem].IsValidPoint()));
	//DEBUG_ERR(("X: %d  Y: %d  Z: %d\n",ptElem[iRetElem].m_x,ptElem[iRetElem].m_y,ptElem[iRetElem].m_z));
	return ( ptElem[iRetElem] );
#undef RESOURCE_Z_CHECK
}
Exemplo n.º 23
0
void CItem::Spawn_GenerateItem( CResourceDef * pDef )
{
	// Count how many items are here already.
	// This could be in a container.

	RESOURCE_ID_BASE rid = pDef->GetResourceID();
	ITEMID_TYPE id = (ITEMID_TYPE) rid.GetResIndex();
	int iDistMax = m_itSpawnItem.m_DistMax;
	int iAmountPile = m_itSpawnItem.m_pile;

	int iCount = 0;
	CItemContainer * pCont = dynamic_cast <CItemContainer *>( GetParent());
	if ( pCont != NULL )
	{
		iCount = pCont->ContentCount( rid );
	}
	else
	{
		// If is equipped this will produce the item where you are standing.
		CPointMap pt = GetTopLevelObj()->GetTopPoint();
		CWorldSearch AreaItems( pt, iDistMax );
		while (true)
		{
			CItem * pItem = AreaItems.GetItem();
			if ( pItem == NULL )
				break;
			if ( pItem->IsType(IT_SPAWN_ITEM))
				continue;
			if ( pItem->IsAttr( ATTR_INVIS ))
				continue;
			if ( pItem->GetID() != id )
				continue;
			// if ( pItem->m_uidLink != GetUID()) continue;
			iCount += pItem->GetAmount();
		}
	}
	if ( iCount >= GetAmount())
		return;

	CItem * pItem = CreateTemplate( id );
	if ( pItem == NULL )
		return;

	pItem->SetAttr( m_Attr & ( ATTR_OWNED | ATTR_MOVE_ALWAYS ));

	if ( iAmountPile > 1 )
	{
		CItemBase * pItemDef = pItem->Item_GetDef();
		ASSERT(pItemDef);
		if ( pItemDef->IsStackableType())
		{
			if ( iAmountPile == 0 || iAmountPile > GetAmount())
				iAmountPile = GetAmount();
			pItem->SetAmount( Calc_GetRandVal(iAmountPile) + 1 );
		}
	}

	// pItem->m_uidLink = GetUID();	// This might be dangerous ?
	pItem->SetDecayTime( g_Cfg.m_iDecay_Item );	// It will decay eventually to be replaced later.
	pItem->MoveNearObj( this, iDistMax );
}
Exemplo n.º 24
0
BOOL CWndRepairItem::OnChildNotify( UINT message, UINT nID, LRESULT* pLResult ) 
{ 
	if( message == WIN_ITEMDROP )
	{
		LPSHORTCUT lpShortcut = (LPSHORTCUT)pLResult;
		CWndBase* pWndFrame = lpShortcut->m_pFromWnd->GetFrameWnd();
		if( nID == 11 ) // item
		{
			if( pWndFrame->GetWndId() == APP_INVENTORY )
			{
				CItemBase* pItemBase	= g_pPlayer->GetItemId( lpShortcut->m_dwId );
				if( pItemBase )
				{
					if( g_pPlayer->m_Inventory.IsEquip( pItemBase->m_dwObjId ) == FALSE )
					{
						// 아이템인가?
						// 방어구 혹은 무기인가?
						// 수리할 필요가 있는가?
						ItemProp* pItemProp	= pItemBase->GetProp();
						if( pItemProp )
						{
							if( pItemProp->dwItemKind2 >= IK2_WEAPON_HAND && pItemProp->dwItemKind2 <= IK2_ARMORETC && ((CItemElem*)pItemBase)->m_nRepair < pItemProp->nMaxRepair )
							{
								CItemElem* pItemElem	= (CItemElem*)pItemBase;
								if( pItemElem->m_nHitPoint < 0 )
									pItemElem->m_nHitPoint = 0;

								if( pItemElem->m_nHitPoint < (int)( pItemProp->dwEndurance ) )
								{
									int nRepair	= 100 - ( ( pItemElem->m_nHitPoint * 100 ) / pItemProp->dwEndurance );
									DWORD dwSumCost = m_dwCost + nRepair * ( pItemProp->dwCost / 1000 + 1 );
									if( g_pPlayer->GetTotalGold() >= (int)( dwSumCost ) )
									{
										m_dwCost = dwSumCost;
										char szCost[MAX_PATH] = {0,};
										sprintf( szCost, "%-d", m_dwCost );
										pWndStaticCost->SetTitle( szCost );
										int iIndex	= lpShortcut->m_dwData - 100;
										m_adwIdRepair[iIndex]	= pItemElem->m_dwObjId;
										pItemElem->m_bRepair	= TRUE;
									}
									else
									{
										// 페냐가 부족하여 수리를 할수 없습니다.
										g_WndMng.PutString( prj.GetText(TID_GAME_REPAIR_NOTENOUGHPENYA), NULL, prj.GetTextColor( TID_GAME_REPAIR_NOTENOUGHPENYA ) );
									}									
								}
								else
								{
									// 수리할 필요가 없는 아이템
									g_WndMng.PutString( prj.GetText(TID_GAME_REPAIR_FULLENDURANCE), NULL, prj.GetTextColor( TID_GAME_REPAIR_FULLENDURANCE ) );
								}
							}
							else
							{
								// 수리할수 없는 아이템
								g_WndMng.PutString( prj.GetText(TID_GAME_REPAIR_DONOT), NULL, prj.GetTextColor( TID_GAME_REPAIR_DONOT ) );
							}
						}
					}
					else
					{
						// 장착되어 있음.
						g_WndMng.PutString( prj.GetText(TID_GAME_REPAIR_EQUIP), NULL, prj.GetTextColor( TID_GAME_REPAIR_EQUIP ) );
					}
				}
//				if( itemElem )
//				{
//					pRepairItem.Add( itemElem->m_dwItemId, itemElem->m_nItemNum, itemElem->m_nAbilityOption, itemElem->m_dwSerialNumber );
//				}

				/*
				CWndItemCtrl* pWndItemCtrl = (CWndItemCtrl*)lpShortcut->m_pFromWnd;
				UINT SelectCount = pWndItemCtrl->GetSelectedCount();
				if( SelectCount != 1)
				{
					//g_WndMng.PutString( "장착 되어 있는것은 넣을수 없습니다", NULL, 0xffffff00 );
					g_WndMng.PutString( prj.GetText(TID_GAME_EQUIPPUT), NULL, prj.GetTextColor( TID_GAME_EQUIPPUT ) );
					
				}
				else
				{
					for( int i = 0; i < SelectCount; i++ )
					{
						int nItem = pWndItemCtrl->GetSelectedItem( i );
						pWndItemCtrl->GetItem( nItem );
					}
					CItemElem* itemElem = (CItemElem*)lpShortcut->m_dwData;
					if( itemElem )
					{
						pRepairItem.Add( itemElem->m_dwItemId, itemElem->m_nItemNum, itemElem->m_nAbilityOption, itemElem->m_dwSerialNumber );
					}
				}
				int aaa = 0;				
				*/
			}
		}
	}
	else
	if( message == WNM_CLICKED )
	{
		if( nID == WIDC_OK )
		{
			g_DPlay.SendRepairItem( m_adwIdRepair );
		}
		else if( nID == WIDC_CANCEL || nID == WTBID_CLOSE )
		{
			OnInit();
			nID = WTBID_CLOSE;
		}
	}
	return CWndNeuz::OnChildNotify( message, nID, pLResult ); 
} 
Exemplo n.º 25
0
void CWorld::GetFixPoint( const CPointMap & pt, CGrayMapBlockState & block)
{
	//Will get the highest CAN_I_PLATFORM|CAN_I_CLIMB and places it into block.Bottom
	ADDTOCALLSTACK("CWorld::GetFixPoint");
	CItemBase * pItemDef = NULL;
	CItemBaseDupe * pDupeDef = NULL;
	CItem * pItem = NULL;
	DWORD wBlockThis = 0;
	signed char z = 0;
	int x2 = 0, y2 = 0;

	// Height of statics at/above given coordinates
	// do gravity here for the z.
	const CGrayMapBlock * pMapBlock = GetMapBlock( pt );
	if (pMapBlock == NULL)
		return;

	size_t iQty = pMapBlock->m_Statics.GetStaticQty();
	if ( iQty > 0 )  // no static items here.
	{
		x2 = pMapBlock->GetOffsetX(pt.m_x);
		y2 = pMapBlock->GetOffsetY(pt.m_y);
		const CUOStaticItemRec * pStatic = NULL;
		for ( size_t i = 0; i < iQty; ++i, z = 0, pStatic = NULL, pDupeDef = NULL )
		{
			if ( ! pMapBlock->m_Statics.IsStaticPoint( i, x2, y2 ))
				continue;

			pStatic = pMapBlock->m_Statics.GetStatic( i );
			if ( pStatic == NULL )
				continue;

			z = pStatic->m_z;

			pItemDef = CItemBase::FindItemBase( pStatic->GetDispID() );
			if ( pItemDef )
			{
				if (pItemDef->GetID() == pStatic->GetDispID()) //parent item
				{
					wBlockThis = (pItemDef->m_Can & CAN_I_MOVEMASK);
					z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight());
				}
				else //non-parent item
				{
					pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pStatic->GetDispID()));
					if ( ! pDupeDef )
					{
						g_Log.EventDebug("Failed to get non-parent reference (static) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pStatic->GetDispID(),pStatic->m_x+pMapBlock->m_x,pStatic->m_y+pMapBlock->m_y,pStatic->m_z);
						wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK );
						z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight());
					}
					else
					{
						wBlockThis = (pDupeDef->m_Can & CAN_I_MOVEMASK);
						z += ((wBlockThis & CAN_I_CLIMB) ? pDupeDef->GetHeight()/2 : pDupeDef->GetHeight());
					}
				}
			}
			else if ( pStatic->GetDispID() )
				CItemBase::GetItemTiledataFlags(wBlockThis,pStatic->GetDispID());

			if (block.m_Bottom.m_z < z)
			{
				if ((z < pt.m_z+PLAYER_HEIGHT) && (wBlockThis & (CAN_I_PLATFORM|CAN_I_CLIMB|CAN_I_WATER)))
				{
					block.m_Bottom.m_dwBlockFlags = wBlockThis;
					block.m_Bottom.m_dwTile = pStatic->GetDispID() + TERRAIN_QTY;
					block.m_Bottom.m_z = z;
				}
				else if (block.m_Top.m_z > z)
				{
					block.m_Top.m_dwBlockFlags = wBlockThis;
					block.m_Top.m_dwTile = pStatic->GetDispID() + TERRAIN_QTY;
					block.m_Top.m_z = z;
				}
			}
		}
	}

	pItemDef = NULL;
	pDupeDef = NULL;
	pItem = NULL;
	wBlockThis = 0;
	z = 0;
	x2 = y2 = 0;
	iQty = 0;

	// Any multi items here ?
	// Check all of them
	CRegionLinks rlinks;
	size_t iRegionQty = pt.GetRegions( REGION_TYPE_MULTI, rlinks );
	if ( iRegionQty > 0 )
	{
		//  ------------ For variables --------------------
		CRegionBase * pRegion = NULL;
		const CGrayMulti * pMulti = NULL;
		const CUOMultiItemRec2 * pMultiItem = NULL;
		x2 = 0;
		y2 = 0;
		//  ------------ For variables --------------------

		for ( size_t iRegion = 0; iRegion < iRegionQty; ++iRegion, pRegion = NULL, pItem = NULL, pMulti = NULL, x2 = 0, y2 = 0 )
		{
			pRegion = rlinks.GetAt(iRegion);
			if ( pRegion != NULL )
				pItem = pRegion->GetResourceID().ItemFind();

			if ( pItem != NULL )
			{
				pMulti = g_Cfg.GetMultiItemDefs(pItem);
				if ( pMulti )
				{
					x2 = pt.m_x - pItem->GetTopPoint().m_x;
					y2 = pt.m_y - pItem->GetTopPoint().m_y;
					iQty = pMulti->GetItemCount();
					for ( size_t ii = 0; ii < iQty; ++ii, pMultiItem = NULL, z = 0 )
					{
						pMultiItem = pMulti->GetItem(ii);

						if ( !pMultiItem )
							break;

						if ( ! pMultiItem->m_visible )
							continue;

						if ( pMultiItem->m_dx != x2 || pMultiItem->m_dy != y2 )
							continue;

						z = static_cast<signed char>(pItem->GetTopZ() + pMultiItem->m_dz);

						pItemDef = CItemBase::FindItemBase( pMultiItem->GetDispID() );
						if ( pItemDef != NULL )
						{
							if ( pItemDef->GetID() == pMultiItem->GetDispID() ) //parent item
							{
								wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK );
								z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight());
							}
							else //non-parent item
							{
								pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pMultiItem->GetDispID()));
								if ( pDupeDef == NULL )
								{
									g_Log.EventDebug("Failed to get non-parent reference (multi) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pMultiItem->GetDispID(),pMultiItem->m_dx+pItem->GetTopPoint().m_x,pMultiItem->m_dy+pItem->GetTopPoint().m_y,pMultiItem->m_dz+pItem->GetTopPoint().m_z);
									wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK );
									z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight());
								}
								else
								{
									wBlockThis = ( pDupeDef->m_Can & CAN_I_MOVEMASK );
									z += ((wBlockThis & CAN_I_CLIMB) ? pDupeDef->GetHeight()/2 : pDupeDef->GetHeight());
								}
							}
						}
						else if ( pMultiItem->GetDispID() )
							CItemBase::GetItemTiledataFlags(wBlockThis,pMultiItem->GetDispID());

						if (block.m_Bottom.m_z < z)
						{
							if ((z < pt.m_z+PLAYER_HEIGHT) && (wBlockThis & (CAN_I_PLATFORM|CAN_I_CLIMB|CAN_I_WATER)))
							{
								block.m_Bottom.m_dwBlockFlags = wBlockThis;
								block.m_Bottom.m_dwTile = pMultiItem->GetDispID() + TERRAIN_QTY;
								block.m_Bottom.m_z = z;
							}
							else if (block.m_Top.m_z > z)
							{
								block.m_Top.m_dwBlockFlags = wBlockThis;
								block.m_Top.m_dwTile = pMultiItem->GetDispID() + TERRAIN_QTY;
								block.m_Top.m_z = z;
							}
						}
					}
				}
			}
		}
	}

	pItemDef = NULL;
	pDupeDef = NULL;
	pItem = NULL;
	wBlockThis = 0;
	x2 = y2 = iQty = 0;
	z = 0;

	// Any dynamic items here ?
	// NOTE: This could just be an item that an NPC could just move ?
	CWorldSearch Area( pt );

	for (;;)
	{
		pItem = Area.GetItem();
		if ( !pItem )
			break;

		z = pItem->GetTopZ();

		// Invis items should not block ???
		pItemDef = CItemBase::FindItemBase( pItem->GetDispID() );

		if ( pItemDef )
		{
			if ( pItemDef->GetDispID() == pItem->GetDispID() )//parent item
			{
				wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK );
				z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight());
			}
			else //non-parent item
			{
				pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pItem->GetDispID()));
				if ( ! pDupeDef )
				{
					g_Log.EventDebug("Failed to get non-parent reference (dynamic) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pItem->GetDispID(),pItem->GetTopPoint().m_x,pItem->GetTopPoint().m_y,pItem->GetTopPoint().m_z);
					wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK );
					z += ((wBlockThis & CAN_I_CLIMB) ? pItemDef->GetHeight()/2 : pItemDef->GetHeight());
				}
				else
				{
					wBlockThis = ( pDupeDef->m_Can & CAN_I_MOVEMASK );
					z += ((wBlockThis & CAN_I_CLIMB) ? pDupeDef->GetHeight()/2 : pDupeDef->GetHeight());
				}
			}

			if ( block.m_Bottom.m_z < z )
			{
				if ( (z < pt.m_z + PLAYER_HEIGHT) && (wBlockThis & (CAN_I_PLATFORM|CAN_I_CLIMB|CAN_I_WATER)) )
				{
					block.m_Bottom.m_dwBlockFlags = wBlockThis;
					block.m_Bottom.m_dwTile = pItemDef->GetDispID() + TERRAIN_QTY;
					block.m_Bottom.m_z = z;
				}
				else if ( block.m_Top.m_z > z )
				{
					block.m_Top.m_dwBlockFlags = wBlockThis;
					block.m_Top.m_dwTile = pItemDef->GetDispID() + TERRAIN_QTY;
					block.m_Top.m_z = z;
				}
			}
		}
		else if (pItem->GetDispID())
			CItemBase::GetItemTiledataFlags(wBlockThis,pItem->GetDispID());
	}

	wBlockThis = 0;
	// Terrain height is screwed. Since it is related to all the terrain around it.
	const CUOMapMeter * pMeter = pMapBlock->GetTerrain( UO_BLOCK_OFFSET(pt.m_x), UO_BLOCK_OFFSET(pt.m_y));
	if ( ! pMeter )
		return;

	if ( pMeter->m_wTerrainIndex == TERRAIN_HOLE )
	{
		wBlockThis = 0;
	}
	else if ( CUOMapMeter::IsTerrainNull( pMeter->m_wTerrainIndex ) )	// inter dungeon type.
	{
		wBlockThis = CAN_I_BLOCK;
	}
	else
	{
		CGrayTerrainInfo land( pMeter->m_wTerrainIndex );
		//DEBUG_ERR(("Terrain flags - land.m_flags 0%x wBlockThis (0%x)\n",land.m_flags,wBlockThis));
		if ( land.m_flags & UFLAG1_WATER )
			wBlockThis |= CAN_I_WATER;
		if ( land.m_flags & UFLAG1_DAMAGE )
			wBlockThis |= CAN_I_FIRE;
		if ( land.m_flags & UFLAG1_BLOCK )
			wBlockThis |= CAN_I_BLOCK;
		if (( ! wBlockThis ) || ( land.m_flags & UFLAG2_PLATFORM )) // Platform items should take precendence over non-platforms.
			wBlockThis = CAN_I_PLATFORM;
	}

	if (block.m_Bottom.m_z < pMeter->m_z)
	{
		if (((pMeter->m_z < pt.m_z+PLAYER_HEIGHT) && (wBlockThis & (CAN_I_PLATFORM|CAN_I_CLIMB|CAN_I_WATER))) || (block.m_Bottom.m_z == UO_SIZE_MIN_Z))
		{
			block.m_Bottom.m_dwBlockFlags = wBlockThis;
			block.m_Bottom.m_dwTile = pMeter->m_wTerrainIndex;
			block.m_Bottom.m_z = pMeter->m_z;
		}
		else if (block.m_Top.m_z > pMeter->m_z)
		{
			block.m_Top.m_dwBlockFlags = wBlockThis;
			block.m_Top.m_dwTile = pMeter->m_wTerrainIndex;
			block.m_Top.m_z = pMeter->m_z;
		}
	}

	if ( block.m_Bottom.m_z == UO_SIZE_MIN_Z )
	{
		//Fail safe...  Reset to 0z with no top block;
		block.m_Bottom.m_dwBlockFlags = 0;
		block.m_Bottom.m_dwTile = 0;
		block.m_Bottom.m_z = 0;

		block.m_Top.m_dwBlockFlags = 0;
		block.m_Top.m_dwTile = 0;
		block.m_Top.m_z = UO_SIZE_Z;
	}
}
Exemplo n.º 26
0
void CWorld::GetHeightPoint( const CPointMap & pt, CGrayMapBlockState & block, bool fHouseCheck )
{
	ADDTOCALLSTACK("CWorld::GetHeightPoint");
	CItemBase * pItemDef = NULL;
	CItemBaseDupe * pDupeDef = NULL;
	CItem * pItem = NULL;
	DWORD wBlockThis = 0;
	signed char z = 0;
	height_t zHeight = 0;
	int x2 = 0, y2 = 0;

	// Height of statics at/above given coordinates
	// do gravity here for the z.
	const CGrayMapBlock * pMapBlock = GetMapBlock( pt );
	if (pMapBlock == NULL)
		return;

	size_t iQty = pMapBlock->m_Statics.GetStaticQty();
	if ( iQty > 0 )  // no static items here.
	{
		x2 = pMapBlock->GetOffsetX(pt.m_x);
		y2 = pMapBlock->GetOffsetY(pt.m_y);
		const CUOStaticItemRec * pStatic = NULL;
		for ( size_t i = 0; i < iQty; ++i, z = 0, zHeight = 0, pStatic = NULL, pDupeDef = NULL )
		{
			if ( ! pMapBlock->m_Statics.IsStaticPoint( i, x2, y2 ))
				continue;

			pStatic = pMapBlock->m_Statics.GetStatic( i );
			if ( pStatic == NULL )
				continue;

			z = pStatic->m_z;

			//DEBUG_ERR(("z (%d)  block.m_zHeight (%d) block.m_Bottom.m_z (%d)\n",z,block.m_zHeight,block.m_Bottom.m_z));
			if ( ! block.IsUsableZ( z, block.m_zHeight ))
				continue;

			// This static is at the coordinates in question.
			// enough room for me to stand here ?

			pItemDef = CItemBase::FindItemBase( pStatic->GetDispID() );
			if ( pItemDef )
			{
				//DEBUG_ERR(("pItemDef->GetID(0%x) pItemDef->GetDispID(0%x) pStatic->GetDispID(0%x)\n",pItemDef->GetID(),pItemDef->GetDispID(),pStatic->GetDispID()));
				if ( pItemDef->GetID() == pStatic->GetDispID() ) //parent item
				{
					zHeight = pItemDef->GetHeight();
					wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove
				}
				else //non-parent item
				{
					pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pStatic->GetDispID()));
					if ( ! pDupeDef )
					{
						g_Log.EventDebug("Failed to get non-parent reference (static) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pStatic->GetDispID(),pStatic->m_x+pMapBlock->m_x,pStatic->m_y+pMapBlock->m_y,pStatic->m_z);
						zHeight = pItemDef->GetHeight();
						wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK );
					}
					else
					{
						zHeight = pDupeDef->GetHeight();
						wBlockThis = ( pDupeDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove - CAN flags cannot be inherited from the parent item due to bad script pack...
					}
				}
			}
			else if ( pStatic->GetDispID() )
				CItemBase::GetItemTiledataFlags(wBlockThis,pStatic->GetDispID());

			block.CheckTile_Item( wBlockThis, z, zHeight, pStatic->GetDispID() + TERRAIN_QTY );
		}
	}

	pItemDef = NULL;
	pDupeDef = NULL;
	pItem = NULL;
	wBlockThis = 0;
	z = 0;
	zHeight = 0;
	x2 = y2 = 0;
	iQty = 0;

	// Any multi items here ?
	// Check all of them
	if ( fHouseCheck )
	{
		CRegionLinks rlinks;
		size_t iRegionQty = pt.GetRegions( REGION_TYPE_MULTI, rlinks );
		if ( iRegionQty > 0 )
		{
			//  ------------ For variables --------------------
			CRegionBase * pRegion = NULL;
			const CGrayMulti * pMulti = NULL;
			const CUOMultiItemRec2 * pMultiItem = NULL;
			x2 = 0;
			y2 = 0;
			//  ------------ For variables --------------------

			for ( size_t iRegion = 0; iRegion < iRegionQty; ++iRegion, pRegion = NULL, pItem = NULL, pMulti = NULL, x2 = 0, y2 = 0 )
			{
				pRegion = rlinks.GetAt(iRegion);
				if ( pRegion != NULL )
					pItem = pRegion->GetResourceID().ItemFind();

				if ( pItem != NULL )
				{
					pMulti = g_Cfg.GetMultiItemDefs(pItem);
					if ( pMulti )
					{
						x2 = pt.m_x - pItem->GetTopPoint().m_x;
						y2 = pt.m_y - pItem->GetTopPoint().m_y;

						iQty = pMulti->GetItemCount();
						for ( size_t ii = 0; ii < iQty; ++ii, pMultiItem = NULL, z = 0, zHeight = 0 )
						{
							pMultiItem = pMulti->GetItem(ii);

							if ( !pMultiItem )
								break;

							if ( ! pMultiItem->m_visible )
								continue;

							if ( pMultiItem->m_dx != x2 || pMultiItem->m_dy != y2 )
								continue;

							z = static_cast<signed char>( pItem->GetTopZ() + pMultiItem->m_dz );
							if ( ! block.IsUsableZ(z,block.m_zHeight))
								continue;

							pItemDef = CItemBase::FindItemBase( pMultiItem->GetDispID() );
							if ( pItemDef != NULL )
							{
								if ( pItemDef->GetID() == pMultiItem->GetDispID() ) //parent item
								{
									zHeight = pItemDef->GetHeight();
									wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove
								}
								else //non-parent item
								{
									pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pMultiItem->GetDispID()));
									if ( pDupeDef == NULL )
									{
										g_Log.EventDebug("Failed to get non-parent reference (multi) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pMultiItem->GetDispID(),pMultiItem->m_dx+pItem->GetTopPoint().m_x,pMultiItem->m_dy+pItem->GetTopPoint().m_y,pMultiItem->m_dz+pItem->GetTopPoint().m_z);
										zHeight = pItemDef->GetHeight();
										wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK );
									}
									else
									{
										zHeight = pDupeDef->GetHeight();
										wBlockThis = ( pDupeDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove - CAN flags cannot be inherited from the parent item due to bad script pack...
									}
								}
							}
							else if ( pMultiItem->GetDispID() )
								CItemBase::GetItemTiledataFlags(wBlockThis,pMultiItem->GetDispID());

							block.CheckTile_Item( wBlockThis, z, zHeight, pMultiItem->GetDispID() + TERRAIN_QTY );
						}
					}
				}
			}
		}
	}

	pItemDef = NULL;
	pDupeDef = NULL;
	pItem = NULL;
	wBlockThis = 0;
	x2 = y2 = iQty = 0;
	zHeight = 0;
	z = 0;

	// Any dynamic items here ?
	// NOTE: This could just be an item that an NPC could just move ?
	CWorldSearch Area( pt );

	for (;;)
	{
		pItem = Area.GetItem();
		if ( !pItem )
			break;

		z = pItem->GetTopZ();
		if ( !block.IsUsableZ( z, block.m_zHeight ) )
			continue;

		// Invis items should not block ???
		pItemDef = CItemBase::FindItemBase( pItem->GetDispID() );

		if ( pItemDef )
		{
			if ( pItemDef->GetDispID() == pItem->GetDispID() )//parent item
			{
				zHeight = pItemDef->GetHeight();
				wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove
			}
			else //non-parent item
			{
				pDupeDef = CItemBaseDupe::GetDupeRef(static_cast<ITEMID_TYPE>(pItem->GetDispID()));
				if ( ! pDupeDef )
				{
					g_Log.EventDebug("Failed to get non-parent reference (dynamic) (DispID 0%x) (X: %d Y: %d Z: %d)\n",pItem->GetDispID(),pItem->GetTopPoint().m_x,pItem->GetTopPoint().m_y,pItem->GetTopPoint().m_z);
					zHeight = pItemDef->GetHeight();
					wBlockThis = ( pItemDef->m_Can & CAN_I_MOVEMASK );
				}
				else
				{
					zHeight = pDupeDef->GetHeight();
					wBlockThis = ( pDupeDef->m_Can & CAN_I_MOVEMASK ); //Use only Block flags, other remove - CAN flags cannot be inherited from the parent item due to bad script pack...
				}
			}
		}
		else if (pItem->GetDispID())
			CItemBase::GetItemTiledataFlags(wBlockThis,pItem->GetDispID());

		block.CheckTile_Item(wBlockThis, z, zHeight, pItem->GetDispID() + TERRAIN_QTY);
	}

	wBlockThis = 0;
	// Terrain height is screwed. Since it is related to all the terrain around it.
	const CUOMapMeter * pMeter = pMapBlock->GetTerrain( UO_BLOCK_OFFSET(pt.m_x), UO_BLOCK_OFFSET(pt.m_y));
	if ( ! pMeter )
		return;

	if ( block.IsUsableZ( pMeter->m_z,block.m_zHeight ) )
	{
		//DEBUG_ERR(("pMeter->m_wTerrainIndex 0%x wBlockThis (0%x)\n",pMeter->m_wTerrainIndex,wBlockThis));
		if ( pMeter->m_wTerrainIndex == TERRAIN_HOLE )
		{
			wBlockThis = 0;
		}
		else if ( CUOMapMeter::IsTerrainNull( pMeter->m_wTerrainIndex ) )	// inter dungeon type.
		{
			wBlockThis = CAN_I_BLOCK;
		}
		else
		{
			CGrayTerrainInfo land( pMeter->m_wTerrainIndex );
			//DEBUG_ERR(("Terrain flags - land.m_flags 0%x wBlockThis (0%x)\n",land.m_flags,wBlockThis));
			if ( land.m_flags & UFLAG1_WATER )
				wBlockThis |= CAN_I_WATER;
			if ( land.m_flags & UFLAG1_DAMAGE )
				wBlockThis |= CAN_I_FIRE;
			if ( land.m_flags & UFLAG1_BLOCK )
				wBlockThis |= CAN_I_BLOCK;
			if (( ! wBlockThis ) || ( land.m_flags & UFLAG2_PLATFORM )) // Platform items should take precendence over non-platforms.
				wBlockThis = CAN_I_PLATFORM;
		}
		//DEBUG_ERR(("TERRAIN wBlockThis (0%x)\n",wBlockThis));
		block.CheckTile_Terrain( wBlockThis, pMeter->m_z, pMeter->m_wTerrainIndex );
	}

	if ( block.m_Bottom.m_z == UO_SIZE_MIN_Z )
	{
		block.m_Bottom = block.m_Lowest;
		if ( block.m_Top.m_z == block.m_Bottom.m_z )
		{
			block.m_Top.m_dwBlockFlags = 0;
			block.m_Top.m_dwTile = 0;
			block.m_Top.m_z = UO_SIZE_Z;
		}
	}
}
Exemplo n.º 27
0
BOOL CWndVendor::OnChildNotify( UINT message, UINT nID, LRESULT* pLResult ) 
{ 
	if( message == 100 && nID == 100 )
	{
		LPSHORTCUT pShortcut	= (LPSHORTCUT)pLResult;
		if( pShortcut )
		{
			CWndBase* pWndFrame		= pShortcut->m_pFromWnd->GetFrameWnd();
			if( pWndFrame->GetWndId() == APP_INVENTORY )
			{
				CItemBase* pItemBase	= m_pVendor->GetItemId( pShortcut->m_dwId );
				if( pItemBase )
				{
					if( pItemBase->IsQuest() )
						return FALSE;

					if( pItemBase->GetProp()->dwItemKind3 == IK3_CLOAK && ( (CItemElem*)pItemBase )->m_idGuild != 0 )
						return FALSE;

//#if __VER >= 11 // __MA_VER11_05	// 케릭터 봉인 거래 기능 world,database,neuz	
//					if( pItemBase->m_dwItemId == II_SYS_SYS_SCR_SEALCHARACTER )
//						return FALSE;	// 개인상점판매허용
//#endif // __MA_VER11_05	// 케릭터 봉인 거래 기능 world,database,neuz

#if __VER >= 9 // __CSC_VER9_1
//					ItemProp* pItemProp = pItemBase->GetProp();
					CItemElem* pItemElem = (CItemElem*)pItemBase;
					if( pItemElem->IsFlag( CItemElem::expired ) )
						return TRUE;
					/*
					if(pItemProp->dwItemKind3 == IK3_EGG && pItemElem->m_pPet) //사망한 펫은 거래 불가
					{
						if(pItemElem->m_pPet->GetLife() <= 0)
							return FALSE;
					}
					*/
#endif //__CSC_VER9_1

					/*
					if( ((CItemElem*)pItemBase)->m_bCharged == 1 )
					{
						g_WndMng.PutString( prj.GetText( TID_GAME_NOTTRADE ), NULL, prj.GetTextColor( TID_GAME_NOTTRADE ) );
						return FALSE;
					}
					*/

					int iIndex	= pShortcut->m_dwData - 100;
					if( 0 <= iIndex && iIndex < MAX_VENDITEM )						
					{
						if( m_pVendor->m_vtInfo.GetItem( iIndex ) != NULL )
							return FALSE;
						
						if( IsUsingItem( pItemBase ) == FALSE && m_pVendor->IsActiveMover() && !m_pVendor->m_vtInfo.IsVendorOpen() )
						{
							SAFE_DELETE( m_pWndRegVend );
							m_pWndRegVend	= new CWndRegVend;
							m_pWndRegVend->Initialize( this );
							m_pWndRegVend->SetItem( iIndex, pItemBase );
						}
					}
				}
			}	// APP_INVENTORY
		}
	}
	else
	{
		if( nID == WIDC_OK )
		{
			if( g_pPlayer->m_pActMover->IsFly() )
				return TRUE;
			if( g_pPlayer->m_vtInfo.VendorIsVendor() == FALSE )
				return TRUE;
			CWndEdit* pWndEdit	= (CWndEdit*)GetDlgItem( WIDC_EDIT1 );
			CString strVendor	= pWndEdit->GetString();
			strVendor.TrimLeft();
			strVendor.TrimRight();

		/*#if __VER >= 11 // __MOD_VENDOR
			// 매물 액수 총합 + 현재 소지금이 2억1천이 넘으면 경고띄우고 리턴시킴.
			int nGold = (int)g_pPlayer->GetTotalGold();

			for( int iv = 0 ; iv < MAX_VENDITEM ; ++iv )
			{
				CItemBase *pItemBase = g_pPlayer->m_vtInfo.GetItem( iv );
				if( pItemBase == NULL )
					continue;

				nGold += ((CItemElem*)pItemBase)->m_nCost * pItemBase->GetExtra();
			}					
			
			if( nGold <= 0 || 2100000000 <= nGold )
			{
				g_WndMng.OpenMessageBox( _T(prj.GetText(TID_GAME_VENDOR_MAX_ALL_GOLD)), MB_OK, this );
				return TRUE;
			}
		#endif*/

			if( prj.IsInvalidName( strVendor )
#ifdef __RULE_0615
				|| prj.IsAllowedLetter( strVendor, TRUE ) == FALSE
#endif	// __RULE_0615
				)
			{
				g_WndMng.OpenMessageBox( _T( prj.GetText(TID_DIAG_0020) ) );
				return TRUE;
			}

			g_WndMng.WordChange( strVendor );
			// name
#ifdef __RULE_0615
			if( strVendor.GetLength() < 6 || strVendor.GetLength() > 32 )
#else	// __RULE_0615
			if( strVendor.GetLength() < 6 || strVendor.GetLength() >= 38 )
#endif	// __RULE_0615
			{
				g_WndMng.OpenMessageBox( _T( prj.GetText(TID_DIAG_0011) ) );
				return TRUE;
			}

			CString strFormat = strVendor;

			if( !strVendor.IsEmpty()  )
			{
				pWndEdit->m_string	= strFormat;
				pWndEdit->m_string.GetTextFormat(strFormat);
			}
			
#if __VER >= 8 // __S8_VENDOR_REVISION
			CWndVendorConfirm* pBox = new CWndVendorConfirm;
			g_WndMng.OpenCustomBox( "", pBox );			
			pBox->SetVendorName( strFormat );
			pBox->SetValue( prj.GetText( TID_GAME_VENDOR_START ) );
#else // __VER >= 8 // __S8_VENDOR_REVISION
			g_DPlay.SendPVendorOpen( (const char*)strFormat );
#endif // __VER >= 8 // __S8_VENDOR_REVISION
			CWndButton* pWndButton	= (CWndButton*)GetDlgItem( WIDC_OK );
			pWndButton->SetVisible( FALSE );
		}
		else if( nID == WIDC_CANCEL || nID == WTBID_CLOSE )
		{
#if __VER >= 8 // __S8_VENDOR_REVISION
			if( g_pPlayer->m_vtInfo.IsVendorOpen() )
			{
				CWndVendorConfirm* pBox = new CWndVendorConfirm;
				g_WndMng.OpenCustomBox( "", pBox );			
				pBox->SetValue( prj.GetText( TID_GAME_VENDOR_STOP ) );
				return FALSE;
			}
#endif // __VER >= 8 // __S8_VENDOR_REVISION
			Destroy( FALSE );
		}
		else if( nID == WIDC_CHAT )
		{
			BOOL bChattingRoom = FALSE;
			if( g_pPlayer->m_vtInfo.IsVendorOpen() )
			{
				g_DPlay.SendOpenChattingRoom();
				bChattingRoom = TRUE;
			}
			else if( g_pPlayer->m_vtInfo.GetOther() && g_Chatting.m_bState )
			{
				bChattingRoom = TRUE;
			}

			if( bChattingRoom )
			{
			#if __VER >= 11 // __MOD_VENDOR
				if(!m_pwndVenderMessage) 
				{
					m_pwndVenderMessage = new CWndVendorMessage;

					if(m_pVendor->IsActiveMover())
						m_pwndVenderMessage->m_nIsOwner = TRUE;
				#ifdef __FIX_WND_1109
					m_pwndVenderMessage->Initialize( this );
				#else	// __FIX_WND_1109
					m_pwndVenderMessage->Initialize( );
				#endif	// __FIX_WND_1109
				}
				else
				{
					if(m_pwndVenderMessage->IsVisible()) m_pwndVenderMessage->SetVisible(FALSE);
					else								 m_pwndVenderMessage->SetVisible(TRUE);
				}
			#else
				SAFE_DELETE( m_pwndVenderMessage );
				m_pwndVenderMessage = new CWndVendorMessage;
			#ifdef __FIX_WND_1109
				m_pwndVenderMessage->Initialize( this );
			#else	// __FIX_WND_1109
				m_pwndVenderMessage->Initialize( );
			#endif	// __FIX_WND_1109
			#endif

			}
		}
#if __VER >= 11 // __MOD_VENDOR
		else if(nID == WIDC_RESET)
		{
			
			CItemBase	apItem_VT[MAX_VENDITEM];		/// vendor and trader share pointer array
			ZeroMemory( apItem_VT, sizeof( apItem_VT ) );

			//if( g_pPlayer->m_vtInfo.IsVendorOpen() )
			//{
				for( int i = 0; i < MAX_VENDITEM; i++ )
				{
					// 리스트를 클리어 한다. 
					CItemBase* pItemBase = g_pPlayer->m_vtInfo.GetItem(i);
					if( pItemBase != NULL )
					{
						if( pItemBase->m_dwObjId != 0 )
							g_DPlay.SendUnregisterPVendorItem( i );
					}
				}

				// 저장버퍼도 클리어
				memset(g_Neuz.m_aSavedInven, 0, sizeof(g_Neuz.m_aSavedInven));
			//}
		}
#endif
	}
	return CWndNeuz::OnChildNotify( message, nID, pLResult ); 
}
Exemplo n.º 28
0
bool CChar::Use_Train_ArcheryButte( CItem * pButte, bool fSetup )
{
	ADDTOCALLSTACK("CChar::Use_Train_ArcheryButte");
	// IT_ARCHERY_BUTTE
	ASSERT(pButte);

	ITEMID_TYPE AmmoID;
	if ( GetDist(pButte) < 2 )		// if we are standing right next to the butte, retrieve the arrows/bolts
	{
		if ( pButte->m_itArcheryButte.m_AmmoCount == 0 )
		{
			SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_EMPTY);
			return true;
		}

		AmmoID = pButte->m_itArcheryButte.m_AmmoType;
		CItemBase *pAmmoDef = CItemBase::FindItemBase(AmmoID);
		if ( pAmmoDef )
		{
			TCHAR *pszMsg = Str_GetTemp();
			sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_REM), pAmmoDef->GetName(), (pButte->m_itArcheryButte.m_AmmoCount == 1) ? "" : g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_REMS));
			Emote(pszMsg);

			CItem *pRemovedAmmo = CItem::CreateBase(AmmoID);
			ASSERT(pRemovedAmmo);
			pRemovedAmmo->SetAmount(pButte->m_itArcheryButte.m_AmmoCount);
			ItemBounce(pRemovedAmmo);
		}

		// Clear the target
		pButte->m_itArcheryButte.m_AmmoType = ITEMID_NOTHING;
		pButte->m_itArcheryButte.m_AmmoCount = 0;
		return true;
	}

	SKILL_TYPE skill = Fight_GetWeaponSkill();
	if ( !g_Cfg.IsSkillFlag(skill, SKF_RANGED) )
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_WS);
		return true;
	}
	if ( Skill_GetBase(skill) > g_Cfg.m_iSkillPracticeMax )
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_SKILL);
		return true;
	}

	// Make sure we have some ammo
	CItem *pWeapon = m_uidWeapon.ItemFind();
	ASSERT(pWeapon);
	const CItemBase *pWeaponDef = pWeapon->Item_GetDef();

	// Determine ammo type
	CVarDefCont *pVarAmmoType = pWeapon->GetDefKey("AMMOTYPE", true);
	RESOURCE_ID_BASE rid;
	LPCTSTR t_Str;

	if ( pVarAmmoType )
	{
		t_Str = pVarAmmoType->GetValStr();
		rid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str));
	}
	else
	{
		rid = pWeaponDef->m_ttWeaponBow.m_idAmmo;
	}
	AmmoID = static_cast<ITEMID_TYPE>(rid.GetResIndex());

	// If there is a different ammo type on the butte currently, tell us to remove the current type first
	if ( (pButte->m_itArcheryButte.m_AmmoType != ITEMID_NOTHING) && (pButte->m_itArcheryButte.m_AmmoType != AmmoID) )
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_X);
		return true;
	}

	// We need to be correctly aligned with the target before we can use it
	// For the south facing butte, we need to have the same X value and a Y > 2
	// For the east facing butte, we need to have the same Y value and an X > 2
	if ( !pButte->IsTopLevel() )
	{
	badalign:
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_P);
		return true;
	}

	int targDistX = GetTopPoint().m_x - pButte->GetTopPoint().m_x;
	int targDistY = GetTopPoint().m_y - pButte->GetTopPoint().m_y;

	if ( (pButte->GetID() == ITEMID_ARCHERYBUTTE_S) || (pButte->GetID() == ITEMID_MONGBATTARGET_S) )
	{
		if ( !(targDistX == 0 && targDistY > 2) )
			goto badalign;
	}
	else
	{
		if ( !(targDistY == 0 && targDistX > 2) )
			goto badalign;
	}

	if ( !CanSeeLOS(pButte, LOS_NB_WINDOWS) )	//we should be able to shoot through a window
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_BLOCK);
		return true;
	}

	if ( fSetup )
	{
		if ( Skill_GetActive() == NPCACT_TRAINING )
			return true;
		UpdateAnimate(ANIM_ATTACK_WEAPON);
		m_Act_TargPrv = m_uidWeapon;
		m_Act_Targ = pButte->GetUID();
		Skill_Start(NPCACT_TRAINING);
		return true;
	}

	CVarDefCont *pCont = pWeapon->GetDefKey("AMMOCONT",true);

	if ( m_pPlayer && AmmoID )
	{
		int iFound = 1;
		if ( pCont )
		{
			//check for UID
			CGrayUID uidCont = static_cast<DWORD>(pCont->GetValNum());
			CItemContainer *pNewCont = dynamic_cast<CItemContainer*>(uidCont.ItemFind());
			if ( !pNewCont )	//if no UID, check for ITEMID_TYPE
			{
				t_Str = pCont->GetValStr();
				RESOURCE_ID_BASE rContid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str));
				ITEMID_TYPE ContID = static_cast<ITEMID_TYPE>(rContid.GetResIndex());
				if ( ContID )
					pNewCont = dynamic_cast<CItemContainer*>(ContentFind(rContid));
			}

			if ( pNewCont )
				iFound = pNewCont->ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID));
			else
				iFound = ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID));
		}
		else
			iFound = ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID));
		if ( iFound )
		{
			SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_NOAMMO);
			return(true);
		}
	}

	// OK...go ahead and fire at the target
	// Check the skill
	bool fSuccess = Skill_UseQuick(skill, Calc_GetRandLLVal(40));

	// determine animation parameters
	CVarDefCont *pVarAnim = pWeapon->GetDefKey("AMMOANIM", true);
	CVarDefCont *pVarAnimColor = pWeapon->GetDefKey("AMMOANIMHUE", true);
	CVarDefCont *pVarAnimRender = pWeapon->GetDefKey("AMMOANIMRENDER", true);
	ITEMID_TYPE AmmoAnim;
	DWORD AmmoHue;
	DWORD AmmoRender;

	if ( pVarAnim )
	{
		t_Str = pVarAnim->GetValStr();
		rid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str));
		AmmoAnim = static_cast<ITEMID_TYPE>(rid.GetResIndex());
	}
	else
		AmmoAnim = static_cast<ITEMID_TYPE>(pWeaponDef->m_ttWeaponBow.m_idAmmoX.GetResIndex());

	AmmoHue = pVarAnimColor ? static_cast<DWORD>(pVarAnimColor->GetValNum()) : 0;
	AmmoRender = pVarAnimRender ? static_cast<DWORD>(pVarAnimRender->GetValNum()) : 0;
	
	pButte->Effect(EFFECT_BOLT, AmmoAnim, this, 16, 0, false, AmmoHue, AmmoRender);
	pButte->Sound(0x224);

	// Did we destroy the ammo?
	const CItemBase *pAmmoDef = NULL;
	if ( AmmoID )
		pAmmoDef = CItemBase::FindItemBase(AmmoID);

	if ( !fSuccess )
	{
		// Small chance of destroying the ammo
		if ( pAmmoDef && !Calc_GetRandVal(10) )
		{
			TCHAR *pszMsg = Str_GetTemp();
			sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_DEST), pAmmoDef->GetName());
			Emote(pszMsg, NULL, true);
			return true;
		}

		static LPCTSTR const sm_Txt_ArcheryButte_Failure[] =
		{
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_1),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_2),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_3),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_4)
		};
		Emote(sm_Txt_ArcheryButte_Failure[Calc_GetRandVal(COUNTOF(sm_Txt_ArcheryButte_Failure))]);
	}
	else
	{
		// Very small chance of destroying another arrow
		if ( pAmmoDef && !Calc_GetRandVal(50) && pButte->m_itArcheryButte.m_AmmoCount )
		{
			TCHAR *pszMsg = Str_GetTemp();
			sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_SPLIT), pAmmoDef->GetName());
			Emote(pszMsg, NULL, true);
			return true;
		}

		static LPCTSTR const sm_Txt_ArcheryButte_Success[] =
		{
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_1),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_2),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_3),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_4)
		};
		Emote(sm_Txt_ArcheryButte_Success[Calc_GetRandVal(COUNTOF(sm_Txt_ArcheryButte_Success))]);
	}

	// Update the target
	if ( AmmoID )
	{
		pButte->m_itArcheryButte.m_AmmoType = AmmoID;
		pButte->m_itArcheryButte.m_AmmoCount++;
	}
	return true;
}
Exemplo n.º 29
0
bool CClient::Cmd_Use_Item( CItem *pItem, bool fTestTouch, bool fScript )
{
	ADDTOCALLSTACK("CClient::Cmd_Use_Item");
	// Assume we can see the target.
	// called from Event_DoubleClick

	if ( !pItem )
		return false;

	if ( pItem->m_Can & CAN_I_FORCEDC )
		fTestTouch = false;

	if ( fTestTouch )
	{
		if ( !fScript )
		{
			CItemContainer *pContainer = dynamic_cast<CItemContainer *>(pItem->GetParent());
			if ( pContainer )
			{
				// protect from ,snoop - disallow picking from not opened containers
				bool isInOpenedContainer = false;
				if ( pContainer->GetType() == IT_EQ_TRADE_WINDOW )
					isInOpenedContainer = true;
				else
				{
					CClient::OpenedContainerMap_t::iterator itContainerFound = m_openedContainers.find(pContainer->GetUID().GetPrivateUID());
					if ( itContainerFound != m_openedContainers.end() )
					{
						DWORD dwTopContainerUID = (((*itContainerFound).second).first).first;
						DWORD dwTopMostContainerUID = (((*itContainerFound).second).first).second;
						CPointMap ptOpenedContainerPosition = ((*itContainerFound).second).second;
						const CObjBaseTemplate *pObjTop = pItem->GetTopLevelObj();
						const CObjBase *pObjParent = pContainer->GetParentObj();

						DWORD dwTopContainerUID_ToCheck = 0;
						if ( pObjParent )
							dwTopContainerUID_ToCheck = pObjParent->GetUID().GetPrivateUID();
						else
							dwTopContainerUID_ToCheck = pObjTop->GetUID().GetPrivateUID();

						if ( (dwTopMostContainerUID == pObjTop->GetUID().GetPrivateUID()) && (dwTopContainerUID == dwTopContainerUID_ToCheck) )
						{
							if ( pObjTop->IsChar() )
							{
								// probably a pickup check from pack if pCharTop != this?
								isInOpenedContainer = true;
							}
							else
							{
								const CItem *pItemTop = static_cast<const CItem *>(pObjTop);
								if ( pItemTop && (pItemTop->IsType(IT_SHIP_HOLD) || pItemTop->IsType(IT_SHIP_HOLD_LOCK)) && (pItemTop->GetTopPoint().GetRegion(REGION_TYPE_MULTI) == m_pChar->GetTopPoint().GetRegion(REGION_TYPE_MULTI)) )
									isInOpenedContainer = true;
								else if ( ptOpenedContainerPosition.GetDist(pObjTop->GetTopPoint()) <= 3 )
									isInOpenedContainer = true;
							}
						}
					}
				}

				if ( !isInOpenedContainer )
				{
					SysMessageDefault(DEFMSG_REACH_UNABLE);
					return false;
				}
			}
		}

		// CanTouch handles priv level compares for chars
		if ( !m_pChar->CanUse(pItem, false) )
		{
			if ( !m_pChar->CanTouch(pItem) )
				SysMessage((m_pChar->IsStatFlag(STATF_DEAD)) ? g_Cfg.GetDefaultMsg(DEFMSG_REACH_GHOST) : g_Cfg.GetDefaultMsg(DEFMSG_REACH_FAIL));
			else
				SysMessageDefault(DEFMSG_REACH_UNABLE);

			return false;
		}
	}

	if ( IsTrigUsed(TRIGGER_DCLICK) || IsTrigUsed(TRIGGER_ITEMDCLICK) )
	{
		if ( pItem->OnTrigger(ITRIG_DCLICK, m_pChar) == TRIGRET_RET_TRUE )
			return true;
	}

	CItemBase *pItemDef = pItem->Item_GetDef();
	bool bIsEquipped = pItem->IsItemEquipped();
	if ( pItemDef->IsTypeEquippable() && !bIsEquipped && pItemDef->GetEquipLayer() )
	{
		bool bMustEquip = true;
		if ( pItem->IsTypeSpellbook() )
			bMustEquip = false;
		else if ( (pItem->IsType(IT_LIGHT_OUT) || pItem->IsType(IT_LIGHT_LIT)) && !pItem->IsItemInContainer() )
			bMustEquip = false;

		if ( bMustEquip )
		{
			if ( !m_pChar->CanMove(pItem) )
				return false;

			if ( !m_pChar->CanCarry(pItem) )
			{
				SysMessageDefault(DEFMSG_MSG_HEAVY);
				return false;
			}

			if ( !m_pChar->ItemEquip(pItem, NULL, true) )
				return false;
		}
	}

	CItemSpawn *pSpawn = static_cast<CItemSpawn *>(pItem->m_uidSpawnItem.ItemFind());	// remove this item from its spawn when players DClick it from ground, no other way to take it out.
	if ( pSpawn )
		pSpawn->DelObj(pItem->GetUID());

	SetTargMode();
	m_Targ_PrvUID = m_Targ_UID;
	m_Targ_UID = pItem->GetUID();
	m_tmUseItem.m_pParent = pItem->GetParent();		// store item location to check later if it was not moved

	// Use types of items (specific to client)
	switch ( pItem->GetType() )
	{
		case IT_TRACKER:
		{
			if ( !m_pChar->Skill_Tracking(pItem->m_uidLink) )
			{
				if ( pItem->m_uidLink.IsValidUID() )
					SysMessageDefault(DEFMSG_TRACKING_UNABLE);
				addTarget(CLIMODE_TARG_LINK, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_TRACKER_ATTUNE));
			}
			return true;
		}

		case IT_SHAFT:
		case IT_FEATHER:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_bolts");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_bolts"));
		}

		case IT_FISH_POLE:	// Just be near water ?
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_FISHING_PROMT), true);
			return true;

		case IT_DEED:
			addTargetDeed(pItem);
			return true;

		case IT_EQ_BANK_BOX:
		case IT_EQ_VENDOR_BOX:
			if ( !fScript )
				g_Log.Event(LOGL_WARN|LOGM_CHEAT, "%lx:Cheater '%s' is using 3rd party tools to open bank box\n", GetSocketID(), m_pAccount->GetName());
			return false;

		case IT_CONTAINER_LOCKED:
		case IT_SHIP_HOLD_LOCK:
			if ( !m_pChar->GetContainerCreate(LAYER_PACK)->ContentFindKeyFor(pItem) )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_LOCKED);
				if ( !IsPriv(PRIV_GM) )
					return false;
			}

		case IT_CORPSE:
		case IT_SHIP_HOLD:
		case IT_CONTAINER:
		case IT_TRASH_CAN:
		{
			CItemContainer *pPack = static_cast<CItemContainer *>(pItem);
			if ( !pPack )
				return false;

			if ( !m_pChar->Skill_Snoop_Check(pPack) )
			{
				if ( !addContainerSetup(pPack) )
					return false;
			}

			const CItemCorpse *pCorpseItem = static_cast<const CItemCorpse *>(pPack);
			if ( m_pChar->CheckCorpseCrime(pCorpseItem, true, true) )
				SysMessageDefault(DEFMSG_LOOT_CRIMINAL_ACT);
			return true;
		}

		case IT_GAME_BOARD:
		{
			if ( !pItem->IsTopLevel() )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_GAMEBOARD_FAIL);
				return false;
			}
			CItemContainer *pBoard = static_cast<CItemContainer *>(pItem);
			ASSERT(pBoard);
			pBoard->Game_Create();
			addContainerSetup(pBoard);
			return true;
		}

		case IT_BBOARD:
			addBulletinBoard(static_cast<CItemContainer *>(pItem));
			return true;

		case IT_SIGN_GUMP:
		{
			GUMP_TYPE gumpid = pItemDef->m_ttContainer.m_gumpid;
			if ( !gumpid )
				return false;
			addGumpTextDisp(pItem, gumpid, pItem->GetName(), pItem->IsIndividualName() ? pItem->GetName() : NULL);
			return true;
		}

		case IT_BOOK:
		case IT_MESSAGE:
		{
			if ( !addBookOpen(pItem) )
				SysMessageDefault(DEFMSG_ITEMUSE_BOOK_FAIL);
			return true;
		}

		case IT_STONE_GUILD:
		case IT_STONE_TOWN:
			return true;

		case IT_POTION:
		{
			if ( !m_pChar->CanMove(pItem) )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_POTION_FAIL);
				return false;
			}
			if ( RES_GET_INDEX(pItem->m_itPotion.m_Type) == SPELL_Poison )
			{
				// If we click directly on poison potion, we will drink poison and get ill.
				// To use it on Poisoning skill, the skill will request to target the potion.
				m_pChar->OnSpellEffect(SPELL_Poison, m_pChar, pItem->m_itSpell.m_spelllevel, NULL);
				return true;
			}
			if ( RES_GET_INDEX(pItem->m_itPotion.m_Type) == SPELL_Explosion )
			{
				// Throw explosion potion
				if ( !m_pChar->ItemPickup(pItem, 1) )	// put the potion in our hand
					return false;

				pItem->m_itPotion.m_tick = 4;		// countdown to explode
				pItem->m_itPotion.m_ignited = 1;	// ignite it
				pItem->m_uidLink = m_pChar->GetUID();
				pItem->SetTimeout(TICK_PER_SEC);
				m_tmUseItem.m_pParent = pItem->GetParent();
				addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_SELECT_POTION_TARGET), true, true, pItem->m_itPotion.m_tick * TICK_PER_SEC);
				return true;
			}
			m_pChar->Use_Drink(pItem);
			return true;
		}

		case IT_ANIM_ACTIVE:
			SysMessage(g_Cfg.GetDefaultMsg(DEFMSG_ITEM_IN_USE));
			return false;

		case IT_CLOCK:
			addObjMessage(m_pChar->GetTopSector()->GetLocalGameTime(), pItem);
			return true;

		case IT_SPAWN_ITEM:
		case IT_SPAWN_CHAR:
		{
			pSpawn = static_cast<CItemSpawn *>(pItem);
			if ( !pSpawn )
				return false;

			if ( pSpawn->m_currentSpawned )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_SPAWN_NEG);
				pSpawn->KillChildren();		// Removing existing objects spawned from it ( RESET ).
			}
			else
			{
				SysMessageDefault(DEFMSG_ITEMUSE_SPAWN_RESET);
				pSpawn->OnTick(true);		// Forcing the spawn to work and create some objects ( START ).
			}
			return true;
		}

		case IT_SHRINE:
		{
			if ( m_pChar->OnSpellEffect(SPELL_Resurrection, m_pChar, 1000, pItem) )
				return true;
			SysMessageDefault(DEFMSG_ITEMUSE_SHRINE);
			return true;
		}

		case IT_SHIP_TILLER:
			pItem->Speak(g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_TILLERMAN), HUE_TEXT_DEF, TALKMODE_SAY, FONT_NORMAL);
			return true;

		case IT_WAND:
		case IT_SCROLL:
		{
			SPELL_TYPE spell = static_cast<SPELL_TYPE>(RES_GET_INDEX(pItem->m_itWeapon.m_spell));
			CSpellDef *pSpellDef = g_Cfg.GetSpellDef(spell);
			if ( !pSpellDef )
				return false;

			if ( IsSetMagicFlags(MAGICF_PRECAST) && !pSpellDef->IsSpellType(SPELLFLAG_NOPRECAST) )
			{
				int skill;
				if ( !pSpellDef->GetPrimarySkill(&skill, NULL) )
					return false;

				m_tmSkillMagery.m_Spell = spell;	// m_atMagery.m_Spell
				m_pChar->m_atMagery.m_Spell = spell;
				m_pChar->Skill_Start(static_cast<SKILL_TYPE>(skill));
				return true;
			}
			return Cmd_Skill_Magery(spell, pItem);
		}

		case IT_RUNE:
		{
			if ( !m_pChar->CanMove(pItem, true) )
				return false;
			addPromptConsole(CLIMODE_PROMPT_NAME_RUNE, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_RUNE_NAME), pItem->GetUID());
			return true;
		}

		case IT_CARPENTRY:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_carpentry");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_carpentry"));
		}

		case IT_FORGE:
			// Solve for the combination of this item with another.
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_FORGE));
			return true;

		case IT_ORE:
			return m_pChar->Skill_Mining_Smelt(pItem, NULL);

		case IT_INGOT:
			return Cmd_Skill_Smith(pItem);

		case IT_KEY:
		case IT_KEYRING:
		{
			if ( pItem->GetTopLevelObj() != m_pChar && !m_pChar->IsPriv(PRIV_GM) )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_KEY_FAIL);
				return false;
			}
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_KEY_PROMT), false, true);
			return true;
		}

		case IT_BANDAGE:		// SKILL_HEALING, or SKILL_VETERINARY
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_BANDAGE_PROMT), false, false);
			return true;

		case IT_BANDAGE_BLOOD:	// Clean the bandages.
		case IT_COTTON:			// use on a spinning wheel.
		case IT_WOOL:			// use on a spinning wheel.
		case IT_YARN:			// Use this on a loom.
		case IT_THREAD: 		// Use this on a loom.
		case IT_COMM_CRYSTAL:
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_TARGET_PROMT), false, false);
			return true;

		case IT_CARPENTRY_CHOP:
		case IT_LOCKPICK:		// Use on a locked thing.
		case IT_SCISSORS:
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_TARGET_PROMT), false, true);
			return true;

		case IT_WEAPON_MACE_PICK:
			if ( bIsEquipped || !IsSetOF(OF_NoDClickTarget) )
			{
				// Mine at the location
				TCHAR *pszTemp = Str_GetTemp();
				sprintf(pszTemp, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_MACEPICK_TARG), pItem->GetName());
				addTarget(CLIMODE_TARG_USE_ITEM, pszTemp, true, true);
				return true;
			}

		case IT_WEAPON_SWORD:
		case IT_WEAPON_FENCE:
		case IT_WEAPON_AXE:
		case IT_WEAPON_MACE_SHARP:
		case IT_WEAPON_MACE_STAFF:
		case IT_WEAPON_MACE_SMITH:
		{
			if ( bIsEquipped || !IsSetOF(OF_NoDClickTarget) )
				addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_WEAPON_PROMT), false, true);
			return true;
		}

		case IT_WEAPON_MACE_CROOK:
			if ( bIsEquipped || !IsSetOF(OF_NoDClickTarget) )
				addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_CROOK_PROMT), false, true);
			return true;

		case IT_FISH:
			SysMessageDefault(DEFMSG_ITEMUSE_FISH_FAIL);
			return true;

		case IT_TELESCOPE:
			SysMessageDefault(DEFMSG_ITEMUSE_TELESCOPE);
			return true;

		case IT_MAP:
			addDrawMap(static_cast<CItemMap *>(pItem));
			return true;

		case IT_CANNON_BALL:
		{
			TCHAR *pszTemp = Str_GetTemp();
			sprintf(pszTemp, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_CBALL_PROMT), pItem->GetName());
			addTarget(CLIMODE_TARG_USE_ITEM, pszTemp);
			return true;
		}

		case IT_CANNON_MUZZLE:
		{
			if ( !m_pChar->CanUse(pItem, false) )
				return false;

			// Make sure the cannon is loaded.
			if ( !(pItem->m_itCannon.m_Load & 1) )
			{
				addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_CANNON_POWDER));
				return true;
			}
			if ( !(pItem->m_itCannon.m_Load & 2) )
			{
				addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_CANNON_SHOT));
				return true;
			}
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_CANNON_TARG), false, true);
			return true;
		}

		case IT_CRYSTAL_BALL:
			// Gaze into the crystal ball.
			return true;

		case IT_SEED:
		case IT_PITCHER_EMPTY:
		{
			TCHAR *pszTemp = Str_GetTemp();
			sprintf(pszTemp, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_PITCHER_TARG), pItem->GetName());
			addTarget(CLIMODE_TARG_USE_ITEM, pszTemp, true);
			return true;
		}

		case IT_SPELLBOOK:
			addSpellbookOpen(pItem);
			return true;

		case IT_SPELLBOOK_NECRO:
			addSpellbookOpen(pItem, 101);
			return true;

		case IT_SPELLBOOK_PALA:
			addSpellbookOpen(pItem, 201);
			return true;

		case IT_SPELLBOOK_BUSHIDO:
			addSpellbookOpen(pItem, 401);
			return true;

		case IT_SPELLBOOK_NINJITSU:
			addSpellbookOpen(pItem, 501);
			return true;

		case IT_SPELLBOOK_ARCANIST:
			addSpellbookOpen(pItem, 601);
			return true;

		case IT_SPELLBOOK_MYSTIC:
			addSpellbookOpen(pItem, 678);
			return true;

		case IT_SPELLBOOK_BARD:
			addSpellbookOpen(pItem, 701);
			return true;

		case IT_HAIR_DYE:
		{
			if ( !m_pChar->LayerFind(LAYER_BEARD) && !m_pChar->LayerFind(LAYER_HAIR) )
			{
				SysMessageDefault(DEFMSG_ITEMUSE_DYE_NOHAIR);
				return true;
			}
			Dialog_Setup(CLIMODE_DIALOG, g_Cfg.ResourceGetIDType(RES_DIALOG, "d_hair_dye"), 0, pItem);
			return true;
		}

		case IT_DYE:
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_DYE_VAT));
			return true;

		case IT_DYE_VAT:
			addTarget(CLIMODE_TARG_USE_ITEM, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_DYE_TARG), false, true);
			return true;

		case IT_MORTAR:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_alchemy");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_alchemy"));
		}

		case IT_CARTOGRAPHY:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_cartography");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_cartography"));
		}

		case IT_COOKING:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_cooking");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_cooking"));
		}

		case IT_TINKER_TOOLS:
		{
			if ( IsTrigUsed(TRIGGER_SKILLMENU) )
			{
				CScriptTriggerArgs args("sm_tinker");
				if ( m_pChar->OnTrigger("@SkillMenu", m_pChar, &args) == TRIGRET_RET_TRUE )
					return true;
			}
			return Cmd_Skill_Menu(g_Cfg.ResourceGetIDType(RES_SKILLMENU, "sm_tinker"));
		}

		case IT_SEWING_KIT:
		{
			TCHAR *pszTemp = Str_GetTemp();
			sprintf(pszTemp, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SEWKIT_PROMT), pItem->GetName());
			addTarget(CLIMODE_TARG_USE_ITEM, pszTemp);
			return true;
		}

		case IT_SCROLL_BLANK:
			Cmd_Skill_Inscription();
			return true;

		default:
		{
			// An NPC could use it this way.
			if ( m_pChar->Use_Item(pItem) )
				return true;
			break;
		}
	}

	SysMessageDefault(DEFMSG_ITEMUSE_CANTTHINK);
	return false;
}
Exemplo n.º 30
0
bool CMenuItem::ParseLine( TCHAR * pszArgs, CScriptObj * pObjBase, CTextConsole * pSrc )
{
	ADDTOCALLSTACK("CMenuItem::ParseLine");

	if ( *pszArgs == '@' )
	{
		// This allows for triggers in menus
		return false;
	}

	TCHAR * pszArgStart = pszArgs;
	while ( _ISCSYM( *pszArgs ))
		pszArgs++;

	if ( *pszArgs )
	{
		*pszArgs = '\0';
		pszArgs++;
		GETNONWHITESPACE( pszArgs );
	}

	// The item id (if we want to have an item type menu) or 0
	if ( strcmp( pszArgStart, "0" ) != 0 )
	{
		CItemBase * pItemBase = CItemBase::FindItemBase(static_cast<ITEMID_TYPE>(g_Cfg.ResourceGetIndexType( RES_ITEMDEF, pszArgStart )));
		if ( pItemBase != NULL )
		{
			m_id = static_cast<WORD>(pItemBase->GetDispID());
			pObjBase = pItemBase;
		}
		else
		{
			DEBUG_ERR(( "Bad MENU item id '%s'\n", pszArgStart ));
			return( false );	// skip this.
		}
	}
	else
	{
		m_id = 0;
	}

	if ( pObjBase != NULL )
	{
		pObjBase->ParseText( pszArgs, pSrc );
	}
	else
	{
		g_Serv.ParseText( pszArgs, pSrc );
	}

	// Parsing @color
	if ( *pszArgs == '@' )
	{
		pszArgs++;
		HUE_TYPE wHue = static_cast<HUE_TYPE>(Exp_GetVal( pszArgs ));
		if ( wHue != 0 )
			wHue = (wHue == 1? 0x7FF: wHue-1);

		m_color = wHue;
		SKIP_ARGSEP( pszArgs );
	}
	else
		m_color = 0;

	m_sText = pszArgs;

	if ( m_sText.IsEmpty())
	{
		if ( pObjBase )	// use the objects name by default.
		{
			m_sText = pObjBase->GetName();	
			if ( ! m_sText.IsEmpty())
				return( true );
		}
		DEBUG_ERR(( "Bad MENU item text '%s'\n", pszArgStart ));
	}

	return( !m_sText.IsEmpty() );
}