bool CChar::NPC_StablePetRetrieve( CChar * pCharPlayer ) { ADDTOCALLSTACK("CChar::NPC_StablePetRetrieve"); // Get pets for this person from my inventory. // May want to put up a menu ??? if ( !m_pNPC || m_pNPC->m_Brain != NPCBRAIN_STABLE ) return false; int iCount = 0; CItem *pItemNext = NULL; for ( CItem *pItem = GetBank()->GetContentHead(); pItem != NULL; pItem = pItemNext ) { pItemNext = pItem->GetNext(); if ( pItem->IsType(IT_FIGURINE) && pItem->m_uidLink == pCharPlayer->GetUID() ) { if ( !pCharPlayer->Use_Figurine(pItem) ) { tchar *pszTemp = Str_GetTemp(); sprintf(pszTemp, g_Cfg.GetDefaultMsg(DEFMSG_NPC_STABLEMASTER_CLAIM_FOLLOWER), pItem->GetName()); Speak(pszTemp); return true; } pItem->Delete(); iCount++; } } Speak(g_Cfg.GetDefaultMsg((iCount > 0) ? DEFMSG_NPC_STABLEMASTER_CLAIM : DEFMSG_NPC_STABLEMASTER_CLAIM_NOPETS)); return true; }
CItemMulti::~CItemMulti() { MultiUnRealizeRegion(); // unrealize before removed from ground. DeletePrepare(); // Must remove early because virtuals will fail in child destructor. // NOTE: ??? This is dangerous to iterators. The "next" item may no longer be valid ! // Attempt to remove all the accessory junk. // NOTE: assume we have already been removed from Top Level if ( ! m_pRegion ) return; CWorldSearch Area( m_pRegion->m_pt, Multi_GetMaxDist() ); // largest area. while (true) { CItem * pItem = Area.GetItem(); if ( pItem == NULL ) break; if ( pItem == this ) // this gets deleted seperately. continue; if ( ! Multi_IsPartOf( pItem )) continue; pItem->Delete(); // delete the key id for the door/key/sign. } delete m_pRegion; }
bool clearTradesFunctor( CBaseObject *a, UI32 &b, void *extraData ) { bool retVal = true; if( ValidateObject( a ) && a->CanBeObjType( OT_ITEM ) ) { // Body of the functor goes here CItem *i = static_cast< CItem * >(a); if( ValidateObject( i ) ) { if( i->GetType() == IT_TRADEWINDOW ) { CChar *k = FindItemOwner( i ); if( ValidateObject( k ) ) { CItem *p = k->GetPackItem(); if( ValidateObject( p ) ) { CDataList< CItem * > *iCont = i->GetContainsList(); for( CItem *j = iCont->First(); !iCont->Finished(); j = iCont->Next() ) { if( ValidateObject( j ) ) j->SetCont( p ); } } } i->Delete(); ++b; // let's track how many we cleared } } } return retVal; }
//o--------------------------------------------------------------------------o //| Function - Cleanup( void ) //| Date - 26th September, 2001 //| Programmer - Abaddon //| Modified - //o--------------------------------------------------------------------------o //| Purpose - Makes sure that any items and chars inside the multi //| are removed //o--------------------------------------------------------------------------o void CMultiObj::Cleanup( void ) { for( CItem *iRemove = itemInMulti.First(); !itemInMulti.Finished(); iRemove = itemInMulti.Next() ) { if( ValidateObject( iRemove ) ) { ItemTypes iType = iRemove->GetType(); if( iType == IT_DOOR || iType == IT_LOCKEDDOOR || iType == IT_HOUSESIGN ) iRemove->Delete(); else { if( iRemove->IsLockedDown() ) iRemove->SetMovable( 1 ); iRemove->SetMulti( INVALIDSERIAL ); iRemove->SetZ( GetZ() ); } } } for( CChar *cRemove = charInMulti.First(); !charInMulti.Finished(); cRemove = charInMulti.Next() ) { if( ValidateObject( cRemove ) ) { cRemove->SetMulti( INVALIDSERIAL ); cRemove->SetZ( GetZ() ); } } CItem::Cleanup(); }
//o---------------------------------------------------------------------------o //| Function : CItem *startTrade( CSocket *mSock, CChar *nChar ) //| Date : February 2, 2006 //| Programmer : giwo //o---------------------------------------------------------------------------o //| Purpose : Handles everything necesarry to start a secure trade //o---------------------------------------------------------------------------o CItem *startTrade( CSocket *mSock, CChar *nChar ) { if( mSock == NULL || !ValidateObject( nChar ) ) return NULL; CChar *mChar = mSock->CurrcharObj(); CSocket *nSock = nChar->GetSocket(); if( !ValidateObject( mChar ) || nSock == NULL ) return NULL; CItem *tradeWindowOne = CreateTradeWindow( mSock, nSock, mChar ); if( !ValidateObject( tradeWindowOne ) ) return NULL; CItem *tradeWindowTwo = CreateTradeWindow( nSock, mSock, nChar ); if( !ValidateObject( tradeWindowTwo ) ) { tradeWindowOne->Delete(); return NULL; } const SERIAL tw1Serial = tradeWindowOne->GetSerial(); const SERIAL tw2Serial = tradeWindowTwo->GetSerial(); tradeWindowOne->SetTempVar( CITV_MOREX, tw2Serial ); tradeWindowTwo->SetTempVar( CITV_MOREX, tw1Serial ); CPSecureTrading cpstOne( (*nChar), tw1Serial, tw2Serial ); cpstOne.Name( nChar->GetName() ); mSock->Send( &cpstOne ); CPSecureTrading cpstTwo( (*mChar), tw2Serial, tw1Serial ); cpstTwo.Name( mChar->GetName() ); nSock->Send( &cpstTwo ); CPWornItem toWear = (*tradeWindowOne); mSock->Send( &toWear ); nSock->Send( &toWear ); CPWornItem toWear2 = (*tradeWindowTwo); mSock->Send( &toWear2 ); nSock->Send( &toWear2 ); return tradeWindowOne; }
void CSector::OnTick(int iPulseCount) { ADDTOCALLSTACK_INTENSIVE("CSector::OnTick"); // CWorld gives OnTick() to all CSectors. EXC_TRY("Tick"); EXC_SET("light change"); // do not tick sectors on maps not supported by server if ( !g_MapList.m_maps[m_map] ) return; // Check for light change before putting the sector to sleep, since in other case the // world light levels will be shitty bool fEnvironChange = false; bool fLightChange = false; bool fSleeping = false; if ( ! ( iPulseCount & 0x7f )) // 30 seconds or so. { // check for local light level change ? BYTE blightprv = m_Env.m_Light; m_Env.m_Light = GetLightCalc( false ); if ( m_Env.m_Light != blightprv ) { fEnvironChange = true; fLightChange = true; } } EXC_SET("sector sleeping?"); size_t clients = m_Chars_Active.HasClients(); if ( clients <= 0 ) // having no clients inside { // Put the sector to sleep if no clients been here in a while. fSleeping = IsSectorSleeping(); if ( fSleeping ) { if ( !g_Cfg.m_iSectorSleepMask ) return; if (( iPulseCount & g_Cfg.m_iSectorSleepMask ) != ( GetIndex() & g_Cfg.m_iSectorSleepMask )) return; } } EXC_SET("sound effects"); // random weather noises and effects. SOUND_TYPE sound = 0; bool fWeatherChange = false; int iRegionPeriodic = 0; if ( ! ( iPulseCount & 0x7f )) // 30 seconds or so. { // Only do this every x minutes or so (TICK_PER_SEC) // check for local weather change ? WEATHER_TYPE weatherprv = m_Env.m_Weather; if ( ! Calc_GetRandVal( 30 )) // change less often { m_Env.m_Weather = GetWeatherCalc(); if ( weatherprv != m_Env.m_Weather ) { fWeatherChange = true; fEnvironChange = true; } } // Random area noises. Only do if clients about. if ( clients > 0 ) { iRegionPeriodic = 2; static const SOUND_TYPE sm_SfxRain[] = { 0x10, 0x11 }; static const SOUND_TYPE sm_SfxWind[] = { 0x14, 0x15, 0x16 }; static const SOUND_TYPE sm_SfxThunder[] = { 0x28, 0x29 , 0x206 }; // Lightning ? // wind, rain, switch ( GetWeather() ) { case WEATHER_CLOUDY: break; case WEATHER_SNOW: if ( ! Calc_GetRandVal(5) ) sound = sm_SfxWind[ Calc_GetRandVal( COUNTOF( sm_SfxWind )) ]; break; case WEATHER_RAIN: { int iVal = Calc_GetRandVal(30); if ( iVal < 5 ) { // Mess up the light levels for a sec.. LightFlash(); sound = sm_SfxThunder[ Calc_GetRandVal( COUNTOF( sm_SfxThunder )) ]; } else if ( iVal < 10 ) sound = sm_SfxRain[ Calc_GetRandVal( COUNTOF( sm_SfxRain )) ]; else if ( iVal < 15 ) sound = sm_SfxWind[ Calc_GetRandVal( COUNTOF( sm_SfxWind )) ]; } break; default: break; } } } // regen all creatures and do AI ProfileTask charactersTask(PROFILE_CHARS); //pChar = STATIC_CAST <CChar*>( m_Chars_Active.GetHead()); CChar * pCharNext = NULL; CChar * pChar = dynamic_cast <CChar*>( m_Chars_Active.GetHead()); for ( ; pChar != NULL; pChar = pCharNext ) { EXC_TRYSUB("TickChar"); pCharNext = pChar->GetNext(); if (( fEnvironChange ) && ( IsTrigUsed(TRIGGER_ENVIRONCHANGE) )) pChar->OnTrigger(CTRIG_EnvironChange, pChar); if ( pChar->IsClient()) { CClient * pClient = pChar->GetClient(); ASSERT( pClient ); if ( sound ) pClient->addSound(sound, pChar); if ( fLightChange && ! pChar->IsStatFlag( STATF_DEAD | STATF_NightSight )) pClient->addLight(); if ( fWeatherChange ) pClient->addWeather(GetWeather()); if ( iRegionPeriodic && pChar->m_pArea ) { if (( iRegionPeriodic == 2 )&&( IsTrigUsed(TRIGGER_REGPERIODIC) )) { pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_REGPERIODIC ); iRegionPeriodic--; } if ( IsTrigUsed(TRIGGER_CLIPERIODIC) ) pChar->m_pArea->OnRegionTrigger( pChar, RTRIG_CLIPERIODIC ); } } // Can only die on your own tick. if ( !pChar->OnTick() ) pChar->Delete(); EXC_CATCHSUB("Sector"); EXC_DEBUGSUB_START; CPointMap pt = GetBasePoint(); g_Log.EventDebug("char 0%lx '%s'\n", static_cast<DWORD>(pChar->GetUID()), pChar->GetName()); g_Log.EventDebug("sector #%d [%d,%d,%d,%d]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUGSUB_END; } // decay items on ground = time out spells / gates etc.. etc.. // No need to check these so often ! ProfileTask itemsTask(PROFILE_ITEMS); CItem * pItemNext = NULL; CItem * pItem = dynamic_cast <CItem*>( m_Items_Timer.GetHead()); for ( ; pItem != NULL; pItem = pItemNext ) { EXC_TRYSUB("TickItem"); pItemNext = pItem->GetNext(); EXC_SETSUB("TimerExpired"); if ( pItem->IsTimerExpired() ) { EXC_SETSUB("ItemTick"); if ( !pItem->OnTick() ) { EXC_SETSUB("ItemDelete"); pItem->Delete(); } else { EXC_SETSUB("TimerExpired2"); if ( pItem->IsTimerExpired() ) // forgot to clear the timer.? strange. { EXC_SETSUB("SetTimeout"); pItem->SetTimeout(-1); } } } EXC_SETSUB("UpdateFlags"); pItem->OnTickStatusUpdate(); #ifdef _WIN32 EXC_CATCHSUB("Sector"); EXC_DEBUGSUB_START; CPointMap pt = GetBasePoint(); g_Log.EventError("item 0%lx '%s' [timer=%lld, type=%lld]\n", static_cast<DWORD>(pItem->GetUID()), pItem->GetName(), pItem->GetTimerAdjusted(), static_cast<int>(pItem->GetType())); g_Log.EventError("sector #%d [%d,%d,%d,%d]\n", GetIndex(), pt.m_x, pt.m_y, pt.m_z, pt.m_map); EXC_DEBUGSUB_END; #else } #ifndef _DEBUG catch ( const CGrayError& e )
bool CChar::Use_Item_Web( CItem * pItemWeb ) { ADDTOCALLSTACK("CChar::Use_Item_Web"); // IT_WEB // IT_EQ_STUCK // Try to break out of the web. // Or just try to damage it. // // RETURN: true = held in place. // false = walk thru it. if ( GetDispID() == CREID_GIANT_SPIDER || !pItemWeb || !pItemWeb->IsTopLevel() || IsStatFlag(STATF_DEAD|STATF_Insubstantial) || IsPriv(PRIV_GM) ) return false; // just walk through it // Try to break it. int iStr = pItemWeb->m_itWeb.m_Hits_Cur; if ( iStr == 0 ) iStr = pItemWeb->m_itWeb.m_Hits_Cur = 60 + Calc_GetRandVal(250); // Since broken webs become spider silk, we should get out of here now if we aren't in a web. CItem *pFlag = LayerFind(LAYER_FLAG_Stuck); if ( CanMove(pItemWeb, false) ) { if ( pFlag ) pFlag->Delete(); return false; } if ( pFlag ) { if ( pFlag->IsTimerSet() ) // don't allow me to try to damage it too often return true; } int iDmg = pItemWeb->OnTakeDamage(Stat_GetAdjusted(STAT_STR), this); switch ( iDmg ) { case 0: // damage blocked case 1: // web survived default: // unknown if ( GetTopPoint() == pItemWeb->GetTopPoint() ) // is character still stuck on the web? break; case 2: // web turned into silk case INT_MAX: // web destroyed if ( pFlag ) pFlag->Delete(); return false; } // Stuck in it still. if ( !pFlag ) { if ( iDmg < 0 ) return false; // First time message. pFlag = CItem::CreateBase(ITEMID_WEB1_1); ASSERT(pFlag); pFlag->SetAttr(ATTR_DECAY); pFlag->SetType(IT_EQ_STUCK); pFlag->m_uidLink = pItemWeb->GetUID(); pFlag->SetTimeout(pItemWeb->GetTimerDAdjusted()); LayerAdd(pFlag, LAYER_FLAG_Stuck); } else { if ( iDmg < 0 ) { pFlag->Delete(); return false; } SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_SWEB_STUCK), pItemWeb->GetName()); } return true; }
bool CChar::Use_Seed( CItem * pSeed, CPointMap * pPoint ) { ADDTOCALLSTACK("CChar::Use_Seed"); // Use the seed at the current point on the ground or some new point that i can touch. // IT_SEED from IT_FRUIT ASSERT(pSeed); CPointMap pt; if ( pPoint ) pt = *pPoint; else if ( pSeed->IsTopLevel() ) pt = pSeed->GetTopPoint(); else pt = GetTopPoint(); if ( !CanTouch(pt) ) { SysMessageDefault(DEFMSG_MSG_SEED_REACH); return false; } // is there soil here ? IT_DIRT if ( !IsPriv(PRIV_GM) && !g_World.IsItemTypeNear(pt, IT_DIRT, 0, false) ) { SysMessageDefault(DEFMSG_MSG_SEED_TARGSOIL); return(false); } const CItemBase *pItemDef = pSeed->Item_GetDef(); ITEMID_TYPE idReset = static_cast<ITEMID_TYPE>(RES_GET_INDEX(pItemDef->m_ttFruit.m_idReset)); if ( idReset == 0 ) { SysMessageDefault(DEFMSG_MSG_SEED_NOGOOD); return false; } // Already a plant here ? CWorldSearch AreaItems(pt); for (;;) { CItem *pItem = AreaItems.GetItem(); if ( !pItem ) break; if ( pItem->IsType(IT_TREE) || pItem->IsType(IT_FOLIAGE) ) // there's already a tree here { SysMessageDefault(DEFMSG_MSG_SEED_ATREE); return false; } if ( pItem->IsType(IT_CROPS) ) // there's already a plant here pItem->Delete(); } // plant it and consume the seed. CItem *pPlant = CItem::CreateScript(idReset, this); ASSERT(pPlant); pPlant->MoveToUpdate(pt); if ( pPlant->IsType(IT_CROPS) || pPlant->IsType(IT_FOLIAGE) ) { pPlant->m_itCrop.m_ReapFruitID = pSeed->GetID(); pPlant->Plant_CropReset(); } else { pPlant->SetDecayTime(10 * g_Cfg.m_iDecay_Item); } pSeed->ConsumeAmount(); return true; }
//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; }