Beispiel #1
0
//o--------------------------------------------------------------------------o
//|	Function		-	SI32 CWeight::calcCharWeight( CChar *mChar )
//|	Date			-	2/23/2003
//|	Developers		-	Zane
//|	Organization	-	UOX3 DevTeam
//o--------------------------------------------------------------------------o
//|	Description		-	Calculate the total weight of a character based upon all items he owns,
//|							This function should never need to be called but is available for
//|							bruteforce weight updating
//o--------------------------------------------------------------------------o
SI32 CWeight::calcCharWeight( CChar *mChar )
{
    SI32 totalWeight = 0;
    SI32 contWeight = 0;

    for( CItem *i = mChar->FirstItem(); !mChar->FinishedItems(); i = mChar->NextItem() )
    {
        if( !ValidateObject( i ) )
            continue;

        if( IsWeightedContainer( i ) )
        {
            if( i->GetLayer() == IL_PACKITEM )
            {
                CTile& tile = Map->SeekTile( i->GetID() );
                contWeight = static_cast<SI32>( tile.Weight() * 100);	// Add the weight of the container
                contWeight += calcWeight( i );	// Find and add the weight of the items in the container
                i->SetWeight( contWeight, false );		// Also update the weight property of the container
                totalWeight += contWeight;
            }
            else
                totalWeight += i->GetWeight();	// Normal item, just add its weight
        }
        if( totalWeight >= MAX_WEIGHT )
            return MAX_WEIGHT;
    }
    return totalWeight;
}
Beispiel #2
0
//o--------------------------------------------------------------------------o
//|	Function		-	SI32 CWeight::calcWeight( CItem *pack )
//|	Date			-	2/23/2003
//|	Developers		-	Zane
//|	Organization	-	UOX3 DevTeam
//o--------------------------------------------------------------------------o
//|	Description		-	Calculate the total weight of a pack based upon all items inside,
//|							their amounts, etc. This function should never need to be called
//|							but is available for bruteforce weight updating
//o--------------------------------------------------------------------------o
SI32 CWeight::calcWeight( CItem *pack )
{
    SI32 totalWeight = 0;
    SI32 contWeight = 0;

    CDataList< CItem * > *pCont = pack->GetContainsList();
    for( CItem *i = pCont->First(); !pCont->Finished(); i = pCont->Next() )
    {
        if( !ValidateObject( i ) )
            continue;

        if( i->IsContType() )	// Item is a container
        {
            CTile& tile = Map->SeekTile( i->GetID() );
            contWeight = static_cast<SI32>( tile.Weight() * 100);	// Add the weight of the container
            contWeight += calcWeight( i );	// Find and add the weight of the items in the container
            i->SetWeight( contWeight, false );		// Also update the weight property of the container
            totalWeight += contWeight;
            if( totalWeight >= MAX_WEIGHT )
                return MAX_WEIGHT;
        }
        else
        {
            if( !calcAddWeight( i, totalWeight ) )
                return MAX_WEIGHT;
        }
    }
    return totalWeight;
}
Beispiel #3
0
CItem * CWorld::CheckNaturalResource( const CPointMap & pt, IT_TYPE Type, bool fTest, CChar * pCharSrc )
{
	ADDTOCALLSTACK("CWorld::CheckNaturalResource");
	// RETURN: 
	//  The resource tracking item.
	//  NULL = nothing here.

	if ( !pt.IsValidPoint() )
		return NULL;

	EXC_TRY("CheckNaturalResource");

	// Check/Decrement natural resources at this location.
	// We create an invis object to time out and produce more.
	// RETURN: Quantity they wanted. 0 = none here.

	if ( fTest )	// Is the resource avail at all here ?
	{
		EXC_SET("is item near type");
		if ((Type != IT_TREE) && (Type != IT_ROCK) )
		{
			if ( !g_World.IsTypeNear_Top(pt, Type, 0) )
				return NULL;
		}
		else
		{
			if ( !g_World.IsItemTypeNear(pt, Type, 0, false) ) //cannot be used, because it does no Z check... what if there is a static tile 70 tiles under me?
				return NULL;
		}
	}

	// Find the resource object.
	EXC_SET("find existant bit");
	CItem * pResBit;
	CWorldSearch Area(pt);
	for (;;)
	{
		pResBit = Area.GetItem();
		if ( !pResBit )
			break;
		// NOTE: ??? Not all resource objects are world gems. should they be ?
		// I wanted to make tree stumps etc be the resource block some day.

		if ( pResBit->IsType(Type) && pResBit->GetID() == ITEMID_WorldGem )
			break;
	}

	// If none then create one.
	if ( pResBit )
		return pResBit;

	// What type of ore is here ?
	// NOTE: This is unrelated to the fact that we might not be skilled enough to find it.
	// Odds of a vein of ore being present are unrelated to my skill level.
	// Odds of my finding it are.
	// RES_REGIONRESOURCE from RES_REGIONTYPE linked to RES_AREA

	EXC_SET("get region");
	CRegionWorld* pRegion = dynamic_cast<CRegionWorld*>( pt.GetRegion( REGION_TYPE_AREA ));
	if ( !pRegion )
		return NULL;

	CWorldSearch AreaItems( pt );
	AreaItems.SetAllShow(1);
	for (;;)
	{
		CItem *pItem = AreaItems.GetItem();
		if ( !pItem )
			break;
		if ( pItem->GetType() != Type )
			return NULL;
	}

	// just use the background (default) region for this
	if ( pRegion->m_Events.GetCount() <= 0 )
	{
		CPointMap ptZero(0,0,0,pt.m_map);
		pRegion = dynamic_cast<CRegionWorld*>(ptZero.GetRegion(REGION_TYPE_AREA));
	}

	// Find RES_REGIONTYPE
	EXC_SET("resource group");
	const CRandGroupDef * pResGroup = pRegion->FindNaturalResource(Type);
	if ( !pResGroup )
		return NULL;

	// Find RES_REGIONRESOURCE
	EXC_SET("get random group element");
	size_t id = pResGroup->GetRandMemberIndex(pCharSrc);
	CRegionResourceDef * pOreDef;
	if ( id == pResGroup->BadMemberIndex() )
	{
		pOreDef	= dynamic_cast <CRegionResourceDef *> (g_Cfg.ResourceGetDefByName(RES_REGIONRESOURCE, "mr_nothing"));
	}
	else
	{
		RESOURCE_ID rid	= pResGroup->GetMemberID( id );
		pOreDef = dynamic_cast <CRegionResourceDef *>( g_Cfg.ResourceGetDef( rid ));
	}

	if ( !pOreDef )
		return NULL;

	EXC_SET("create bit");
	pResBit = CItem::CreateScript(ITEMID_WorldGem, pCharSrc);
	if ( !pResBit )
		return NULL;
	
	pResBit->SetType(Type);
	pResBit->SetAttr(ATTR_INVIS|ATTR_MOVE_NEVER);
	pResBit->m_itResource.m_rid_res = pOreDef->GetResourceID();

	// Total amount of ore here.
	int amount = pOreDef->m_Amount.GetRandom();
	if ( Type == IT_ROCK && g_Cfg.m_iFeatureML & FEATURE_ML_RACIAL_BONUS && pCharSrc->IsHuman() && pCharSrc->GetTopMap() == 0 )
		amount += 1;	// Workhorse racial bonus, giving +1 ore to humans in Felucca.
	if ( Type == IT_TREE && g_Cfg.m_iFeatureML & FEATURE_ML_RACIAL_BONUS && pCharSrc->IsHuman() && pCharSrc->GetTopMap() == 1 )
		amount += 2;	// Workhorse racial bonus, giving +2 logs to humans in Trammel.
	pResBit->SetAmount( amount );
	pResBit->MoveToDecay(pt, pOreDef->m_iRegenerateTime.GetRandom() * TICK_PER_SEC);	// Delete myself in this amount of time.

	EXC_SET("resourcefound");

	if ( pCharSrc != NULL)
	{
		CScriptTriggerArgs	Args(0, 0, pResBit);
		TRIGRET_TYPE tRet = TRIGRET_RET_DEFAULT;
		if ( IsTrigUsed(TRIGGER_REGIONRESOURCEFOUND) )
			tRet = pCharSrc->OnTrigger(CTRIG_RegionResourceFound, pCharSrc, &Args);
		if ( IsTrigUsed(TRIGGER_RESOURCEFOUND) )
			tRet = pOreDef->OnTrigger("@ResourceFound", pCharSrc, &Args);

		if (tRet == TRIGRET_RET_TRUE)
		{
			if ( pResBit->IsDisconnected() )
				return NULL;
			pResBit->SetAmount(0);
		}
	}
	return pResBit;

	EXC_CATCH;

	EXC_DEBUG_START;
	g_Log.EventDebug("point '%d,%d,%d,%d' type '%d' [0%lx]\n", pt.m_x, pt.m_y, pt.m_z, pt.m_map, static_cast<int>(Type), 
		pCharSrc ? static_cast<DWORD>(pCharSrc->GetUID()) : 0);
	EXC_DEBUG_END;
	return NULL;
}
Beispiel #4
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 );
}
Beispiel #5
0
//o---------------------------------------------------------------------------o
//|   Function   : void sellItem(CSocket *mSock)
//|   Date       : Unknown
//|   Programmer : UOX3 DevTeam
//o---------------------------------------------------------------------------o
//|   Purpose    : Player sells an item to the vendor
//o---------------------------------------------------------------------------o
bool CPISellItem::Handle(void)
{
    if (tSock->GetByte(8) != 0)
    {
        CChar *mChar = tSock->CurrcharObj();
        CChar *n = calcCharObjFromSer(tSock->GetDWord(3));
        if (!ValidateObject(n) || !ValidateObject(mChar))
            return true;

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

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

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

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

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

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

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

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

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

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

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

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

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

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