//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; }
//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; }
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; }
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 ); }
//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; }