// Gets all items of type IT_DRIVE. // void CDirstatDoc::GetDriveItems(CArray<CItem *, CItem *>& drives) { drives.RemoveAll(); CItem *root = GetRootItem(); if(NULL == root) { return; } if(IT_MYCOMPUTER == root->GetType()) { for(int i = 0; i < root->GetChildrenCount(); i++) { CItem *drive = root->GetChild(i); ASSERT(IT_DRIVE == drive->GetType()); drives.Add(drive); } } else if(IT_DRIVE == root->GetType()) { drives.Add(root); } }
void CDirstatDoc::OnUpdateCleanupDelete(CCmdUI *pCmdUI) { // FIXME: Multi-select CItem *item = GetSelection(0); pCmdUI->Enable( DirectoryListHasFocus() && item != NULL && (IT_DIRECTORY == item->GetType() || IT_FILE == item->GetType()) && !item->IsRootItem() ); }
void CDirstatDoc::OnCleanupDeletetotrashbin() { // FIXME: Multi-select CItem *item = GetSelection(0); if(NULL == item || item->GetType() != IT_DIRECTORY && item->GetType() != IT_FILE || item->IsRootItem()) { return; } if(DeletePhysicalItem(item, true)) { RefreshRecyclers(); UpdateAllViews(NULL); } }
bool CGroupOfDeviceGenerators::FindDefaultDesc (const CItem &Item, SDeviceDesc *retDesc) // FindDefaultDesc // // Looks for a slot descriptor that matches the given item and returns it. { // See if the item fits into one of the slots that we've defined. If so, // then we take the descriptor from the slot. SSlotDesc *pSlotDesc = FindSlotDesc(Item); if (pSlotDesc) { *retDesc = pSlotDesc->DefaultDesc; return true; } // Otherwise we go with default (we assume that retDesc is already // initialized to default values). // // For backwards compatibility, however, we place all weapons 20 pixels // forward. ItemCategories iCategory = Item.GetType()->GetCategory(); if (iCategory == itemcatWeapon || iCategory == itemcatLauncher) retDesc->iPosRadius = 20; // Done return true; }
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(); }
void CDirstatDoc::OnCleanupDelete() { // FIXME: Multi-select CItem *item = GetSelection(0); if(NULL == item || item->GetType() != IT_DIRECTORY && item->GetType() != IT_FILE || item->IsRootItem()) { return; } if(DeletePhysicalItem(item, false)) { SetWorkingItem(GetRootItem()); UpdateAllViews(NULL); } }
void CPlayerGameStats::OnItemFired (const CItem &Item) // OnItemFired // // Player fired the item (weapon or missile) { SItemTypeStats *pStats = GetItemStats(Item.GetType()->GetUNID()); pStats->iCountFired++; }
bool CChar::NPC_CheckWalkHere( const CPointBase & pt, const CRegionBase * pArea, WORD wBlockFlags ) const { ADDTOCALLSTACK("CChar::NPC_CheckWalkHere"); UNREFERENCED_PARAMETER(wBlockFlags); // Does the NPC want to walk here ? step on this item ? if ( !m_pNPC ) return false; if ( !pt.IsValidXY() ) return true; if ( m_pArea != NULL ) { if ( m_pNPC->m_Brain == NPCBRAIN_GUARD && !IsStatFlag(STATF_War) ) // guards will want to stay in guard range { if ( m_pArea->IsGuarded() && !pArea->IsGuarded() ) return false; } if ( Noto_IsCriminal() ) { if ( !m_pArea->IsGuarded() && pArea->IsGuarded() ) return false; } } // Is there a nasty object here that will hurt us ? CWorldSearch AreaItems(pt); for (;;) { CItem * pItem = AreaItems.GetItem(); if ( pItem == NULL ) break; if ( abs(pItem->GetTopZ() - pt.m_z) > 5 ) continue; switch ( pItem->GetType() ) { case IT_WEB: return (GetDispID() == CREID_GIANT_SPIDER) ? true : false; case IT_FIRE: return Can(CAN_C_FIRE_IMMUNE); case IT_TRAP: case IT_TRAP_ACTIVE: case IT_MOONGATE: case IT_TELEPAD: return false; default: break; } } return true; }
bool iCHARACTER::UseItemEx(LPITEM item, int iDestCell) { switch (item->GetVnum()) { case 71051: case 71052: CItem* useon = this->GetItem(iDestCell); if (useon && useon->GetType()==ITEM_COSTUME){ this->ChatPacket(CHAT_TYPE_INFO,locale_find("¼Ó¼ºÀ» º¯°æÇÒ ¼ö ¾ø´Â ¾ÆÀÌÅÛÀÔ´Ï´Ù.")); return true; } } return globals::instance()->UseItemEx->GetOriginalFunction()(this, item, iDestCell); }
void CTypeView::SetSelection() { // FIXME: Multi-select CItem *item = GetDocument()->GetSelection(0); if(item == NULL || item->GetType() != IT_FILE) { m_extensionListControl.EnsureVisible(0, false); } else { m_extensionListControl.SelectExtension(item->GetExtension()); } }
void CPlayerGameStats::OnItemSold (const CItem &Item, CurrencyValue iTotalPrice) // OnItemSold // // Player sold an item { if (iTotalPrice <= 0) return; SItemTypeStats *pStats = GetItemStats(Item.GetType()->GetUNID()); pStats->iCountSold += Item.GetCount(); pStats->iValueSold += iTotalPrice; }
void CPlayerGameStats::OnItemBought (const CItem &Item, CurrencyValue iTotalPrice) // OnItemBought // // Player bought an item { if (iTotalPrice <= 0) return; SItemTypeStats *pStats = GetItemStats(Item.GetType()->GetUNID()); pStats->iCountBought += Item.GetCount(); pStats->iValueBought += iTotalPrice; }
bool CReactorClass::IsFuelCompatible (const ReactorDesc &Desc, const CItem &FuelItem) // IsFuelCompatible // // Returns TRUE if compatible with the given fuel. { if (Desc.pFuelCriteria) return FuelItem.MatchesCriteria(*Desc.pFuelCriteria); else { // Must be fuel if (!FuelItem.GetType()->IsFuel()) return false; // Make sure we're the correct level int iLevel = FuelItem.GetType()->GetLevel(); return (iLevel >= Desc.iMinFuelLevel && iLevel <= Desc.iMaxFuelLevel); } }
CInstalledArmor *GetArmorSectionArg (CCodeChain &CC, ICCItem *pArg, CSpaceObject *pObj) // GetArmorSectionArg // // Returns an armor section from a section number or an item struct // Returns NULL if invalid. { // Get the ship CShip *pShip = pObj->AsShip(); if (pShip == NULL) return NULL; // Set the armor segment int iArmorSeg; if (pArg->IsList()) { CItem Item = CreateItemFromList(CC, pArg); if (Item.GetType() && Item.GetType()->GetArmorClass() && Item.IsInstalled()) iArmorSeg = Item.GetInstalled(); else return NULL; } else iArmorSeg = pArg->GetIntegerValue(); // Some error checking if (iArmorSeg < 0 || iArmorSeg >= pShip->GetArmorSectionCount()) return NULL; // Done return pShip->GetArmorSection(iArmorSeg); }
bool CItemMulti::Multi_CreateComponent( ITEMID_TYPE id, int dx, int dy, int dz, DWORD dwKeyCode ) { CItem * pItem = CreateTemplate( id ); ASSERT(pItem); CPointMap pt = GetTopPoint(); pt.m_x += dx; pt.m_y += dy; pt.m_z += dz; bool fNeedKey = false; switch ( pItem->GetType() ) { case IT_KEY: // it will get locked down with the house ? case IT_SIGN_GUMP: case IT_SHIP_TILLER: pItem->m_itKey.m_lockUID.SetPrivateUID( dwKeyCode ); // Set the key id for the key/sign. fNeedKey = true; break; case IT_DOOR: pItem->SetType(IT_DOOR_LOCKED); fNeedKey = true; break; case IT_CONTAINER: pItem->SetType(IT_CONTAINER_LOCKED); fNeedKey = true; break; case IT_SHIP_SIDE: pItem->SetType(IT_SHIP_SIDE_LOCKED); break; case IT_SHIP_HOLD: pItem->SetType(IT_SHIP_HOLD_LOCK); break; } pItem->SetAttr( ATTR_MOVE_NEVER | (m_Attr&(ATTR_MAGIC|ATTR_INVIS))); pItem->SetHue( GetHue()); pItem->m_uidLink = GetUID(); // lock it down with the structure. if ( pItem->IsTypeLockable() || pItem->IsTypeLocked()) { pItem->m_itContainer.m_lockUID.SetPrivateUID( dwKeyCode ); // Set the key id for the door/key/sign. pItem->m_itContainer.m_lock_complexity = 10000; // never pickable. } pItem->MoveTo( pt ); return( fNeedKey ); }
void CCodeChainCtx::DefineItem (const CString &sVar, const CItem &Item) // DefineItem // // Defines a CItem variable { if (Item.GetType()) { ICCItem *pItem = CreateListFromItem(m_CC, Item); m_CC.DefineGlobal(sVar, pItem); pItem->Discard(&m_CC); } else m_CC.DefineGlobal(sVar, m_CC.CreateNil()); }
void CPlayerGameStats::OnItemInstalled (const CItem &Item) // OnItemInstalled // // Player installed an item { SItemTypeStats *pStats = GetItemStats(Item.GetType()->GetUNID()); if (pStats->iCountInstalled == 0) { pStats->dwLastInstalled = g_pUniverse->GetTicks(); if (pStats->dwFirstInstalled == INVALID_TIME) pStats->dwFirstInstalled = pStats->dwLastInstalled; pStats->dwLastUninstalled = INVALID_TIME; } pStats->iCountInstalled++; }
void CPlayerGameStats::OnItemUninstalled (const CItem &Item) // OnItemUninstalled // // Player uninstalled an item { SItemTypeStats *pStats = GetItemStats(Item.GetType()->GetUNID()); ASSERT(pStats->iCountInstalled > 0); if (pStats->iCountInstalled <= 0) return; pStats->iCountInstalled--; if (pStats->iCountInstalled == 0) { ASSERT(pStats->dwLastInstalled != INVALID_TIME); pStats->dwLastUninstalled = g_pUniverse->GetTicks(); pStats->dwTotalInstalledTime += (pStats->dwLastUninstalled - pStats->dwLastInstalled); } }
bool killTradesFunctor( 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 = (CChar *)i->GetCont(); if( ValidateObject( k ) ) { CChar *mChar = (CChar *)extraData; if( k == mChar ) cancelTrade( i ); } ++b; // let's track how many we cleared } } } return retVal; }
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; }
bool CTooltipText::x_Parse(LPCTSTR& pText) { CItemData itemData ; // 如果第一个字符不是'<',则是格式错误,返回false if ( '<' != *pText) return false ; CItem item; // 把根节点传给Item,往下parse一个节点 if(!item.SetItem(pText) ) return false ; if ( item.IsItemEnd() ) return false ; itemData.SetType(item.GetType()) ; switch(itemData.GetType()) { case TIT_TEXT: itemData.SetColor(item.GetAttribColor(_T("color"))) ; break; case TIT_LINK: itemData.SetColor(item.GetAttribColor(_T("color"))) ; itemData.SetColorActive(item.GetAttribColor(_T("active"))); itemData.SetColorHover(item.GetAttribColor(_T("hover"))) ; itemData.SetId(item.GetAttribInt(_T("id"))) ; itemData.SetBold(item.GetAttribInt(_T("bold"))) ; break; } do { wstring wsText ; LPCTSTR pstr = _tcschr(pText , '<') ; if ( NULL == pstr ) return false ; wsText.insert(wsText.begin() , pText , pstr) ; pText = pstr ; if ( !wsText.empty() || itemData.GetType()==TIT_RETURN ) { itemData.SetText(wsText) ; m_ItemList.push_back(itemData) ; } LPCTSTR pTemp = pText ; if(!item.SetItem(pTemp)) return false ; if ( !item.IsItemEnd() ) { if(!x_Parse(pText) ) return false ; } else { pText = pTemp ; break; } } while (true); return true ; }
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 )
int CUIHelper::CalcItemEntryHeight (CSpaceObject *pSource, const CItem &Item, const RECT &rcRect, DWORD dwOptions) const // CalcItemEntryHeight // // Computes the height necessary to paint the item entry. { const CVisualPalette &VI = m_HI.GetVisuals(); const CG16bitFont &LargeBold = VI.GetFont(fontLargeBold); const CG16bitFont &Medium = VI.GetFont(fontMedium); bool bNoIcon = ((dwOptions & OPTION_NO_ICON) == OPTION_NO_ICON); bool bTitle = ((dwOptions & OPTION_TITLE) == OPTION_TITLE); // Get the item CItemCtx Ctx(&Item, pSource); CItemType *pType = Item.GetType(); if (pType == NULL) return ITEM_DEFAULT_HEIGHT; // Compute the rect where the reference text will paint RECT rcDrawRect = rcRect; rcDrawRect.left += ITEM_TEXT_MARGIN_X; rcDrawRect.right -= ITEM_TEXT_MARGIN_X; if (!bNoIcon) rcDrawRect.left += ICON_WIDTH; int iLevel = pType->GetApparentLevel(); // Compute the height of the row int cyHeight = 0; // Account for margin cyHeight += ITEM_TEXT_MARGIN_Y; // Item title cyHeight += LargeBold.GetHeight(); if (bTitle) cyHeight += ITEM_TITLE_EXTRA_MARGIN; // Attributes TArray<SDisplayAttribute> Attribs; if (Item.GetDisplayAttributes(Ctx, &Attribs)) { int cyAttribs; FormatDisplayAttributes(Attribs, rcDrawRect, &cyAttribs); cyHeight += cyAttribs + ATTRIB_SPACING_Y; } // Reference CString sReference = pType->GetReference(Ctx); // If this is a weapon, then add room for the weapon damage if (Item.GetReferenceDamageType(pSource, -1, 0, NULL, NULL)) cyHeight += Medium.GetHeight(); // If this is armor or a shield, then add room for damage resistance else if (Item.GetReferenceDamageAdj(pSource, 0, NULL, NULL)) cyHeight += Medium.GetHeight(); // Measure the reference text int iLines; if (!sReference.IsBlank()) { iLines = Medium.BreakText(sReference, RectWidth(rcDrawRect), NULL, 0); cyHeight += iLines * Medium.GetHeight(); } // Measure the description CString sDesc = Item.GetDesc(); iLines = Medium.BreakText(sDesc, RectWidth(rcDrawRect), NULL, 0); cyHeight += iLines * Medium.GetHeight(); // Margin cyHeight += ITEM_TEXT_MARGIN_BOTTOM; // Done cyHeight = Max(ITEM_DEFAULT_HEIGHT, cyHeight); return cyHeight; }
void CUIHelper::PaintItemEntry (CG16bitImage &Dest, CSpaceObject *pSource, const CItem &Item, const RECT &rcRect, DWORD dwOptions) const // PaintItemEntry // // Paints an item entry suitable for an item list. { const CVisualPalette &VI = m_HI.GetVisuals(); const CG16bitFont &LargeBold = VI.GetFont(fontLargeBold); const CG16bitFont &Medium = VI.GetFont(fontMedium); WORD wColorTitle = VI.GetColor(colorTextHighlight); WORD wColorRef = VI.GetColor(colorTextHighlight); WORD wColorDescSel = CG16bitImage::RGBValue(200,200,200); WORD wColorDesc = CG16bitImage::RGBValue(128,128,128); bool bSelected = ((dwOptions & OPTION_SELECTED) == OPTION_SELECTED); bool bNoIcon = ((dwOptions & OPTION_NO_ICON) == OPTION_NO_ICON); bool bTitle = ((dwOptions & OPTION_TITLE) == OPTION_TITLE); // Item context CItemCtx Ctx(&Item, pSource); CItemType *pItemType = Item.GetType(); // Calc the rect where we will draw RECT rcDrawRect = rcRect; rcDrawRect.left += ITEM_TEXT_MARGIN_X; rcDrawRect.right -= ITEM_TEXT_MARGIN_X; rcDrawRect.top += ITEM_TEXT_MARGIN_Y; // Paint the image if (!bNoIcon) { DrawItemTypeIcon(Dest, rcRect.left, rcRect.top, pItemType); rcDrawRect.left += ICON_WIDTH; } // Paint the item name DWORD dwNounPhraseFlags = nounNoModifiers; if (bTitle) dwNounPhraseFlags |= nounTitleCapitalize | nounShort; else dwNounPhraseFlags |= nounCount; int cyHeight; RECT rcTitle = rcDrawRect; LargeBold.DrawText(Dest, rcTitle, wColorTitle, Item.GetNounPhrase(dwNounPhraseFlags), 0, CG16bitFont::SmartQuotes | CG16bitFont::TruncateLine, &cyHeight); rcDrawRect.top += cyHeight; if (bTitle) rcDrawRect.top += ITEM_TITLE_EXTRA_MARGIN; // Paint the display attributes TArray<SDisplayAttribute> Attribs; if (Item.GetDisplayAttributes(Ctx, &Attribs)) { FormatDisplayAttributes(Attribs, rcDrawRect, &cyHeight); PaintDisplayAttributes(Dest, Attribs); rcDrawRect.top += cyHeight + ATTRIB_SPACING_Y; } // Stats CString sStat; int iLevel = pItemType->GetApparentLevel(); CString sReference = pItemType->GetReference(Ctx); DamageTypes iDamageType; CString sDamageRef; int iDamageAdj[damageCount]; int iHP; if (Item.GetReferenceDamageType(pSource, -1, 0, &iDamageType, &sDamageRef)) { // Paint the damage type reference PaintReferenceDamageType(Dest, rcDrawRect.left + DAMAGE_ADJ_SPACING_X, rcDrawRect.top, iDamageType, sDamageRef); rcDrawRect.top += Medium.GetHeight(); // Paint additional reference in the line below if (!sReference.IsBlank()) { Medium.DrawText(Dest, rcDrawRect, wColorRef, sReference, 0, 0, &cyHeight); rcDrawRect.top += cyHeight; } } else if (Item.GetReferenceDamageAdj(pSource, 0, &iHP, iDamageAdj)) { // Paint the initial text sStat = strPatternSubst("hp: %d ", iHP); int cxWidth = Medium.MeasureText(sStat, &cyHeight); Medium.DrawText(Dest, rcDrawRect, wColorRef, sStat, 0, 0, &cyHeight); // Paint the damage type array PaintReferenceDamageAdj(Dest, rcDrawRect.left + cxWidth + DAMAGE_ADJ_SPACING_X, rcDrawRect.top, iLevel, iHP, iDamageAdj); rcDrawRect.top += cyHeight; // Paint additional reference in the line below if (!sReference.IsBlank()) { Medium.DrawText(Dest, rcDrawRect, wColorRef, sReference, 0, 0, &cyHeight); rcDrawRect.top += cyHeight; } } else { Medium.DrawText(Dest, rcDrawRect, wColorRef, sReference, 0, 0, &cyHeight); rcDrawRect.top += cyHeight; } // Description CString sDesc = Item.GetDesc(); Medium.DrawText(Dest, rcDrawRect, (bSelected ? wColorDescSel : wColorDesc), sDesc, 0, CG16bitFont::SmartQuotes, &cyHeight); rcDrawRect.top += cyHeight; }
void CSeparateDlg::Update( CObservable* pObservable, CTObject* pObj ) { assert( pObservable ); assert( pObj && strcmp( pObj->toString() ,"Separate" ) == 0 ); if( pObj == NULL || strcmp( pObj->toString() ,"Separate" ) ) return; CTEventSeparate* pEvent = (CTEventSeparate*)pObj; switch( pEvent->GetID() ) { case CTEventSeparate::EID_REMOVE_MATERIAL_ITEM: ClientLog (LOG_NORMAL, "CSeperateDlg::Update. Event 2: EID_REMOVE_MATERIAL_ITEM"); m_MaterialItemSlot.DetachIcon(); break; case CTEventSeparate::EID_SET_MATERIAL_ITEM: { CItem* pItem = pEvent->GetItem(); ClientLog (LOG_NORMAL, "CSeperateDlg::Update. Event 1: EID_SET_MATERIAL_ITEM Item Type %i Item ID %i", pItem->GetType(), pItem->GetItemNo()); assert( pItem ); if( pItem ) m_MaterialItemSlot.AttachIcon( pItem->CreateItemIcon() ); break; } case CTEventSeparate::EID_REMOVE_OUTPUT_ITEM: { ClientLog (LOG_NORMAL, "CSeperateDlg::Update. Event 4: EID_REMOVE_OUTPUT_ITEM"); int iIndex = pEvent->GetIndex(); //assert( iIndex >= 0 && iIndex < (int)m_OutputItemSlots.size() ); if( iIndex >= 0 && iIndex < (int)m_OutputItemSlots.size() ) m_OutputItemSlots[iIndex].DetachIcon(); break; } case CTEventSeparate::EID_SET_OUTPUT_ITEM: { ClientLog (LOG_NORMAL, "CSeperateDlg::Update. Event 3: EID_SET_OUTPUT_ITEM"); int e = m_OutputItemSlots.size(); int iIndex = pEvent->GetIndex(); //assert( iIndex >= 0 && iIndex < (int)m_OutputItemSlots.size() ); if( iIndex >= 0 && iIndex < (int)m_OutputItemSlots.size() ) { CItem* pItem = pEvent->GetItem(); ClientLog (LOG_NORMAL, "CSeperateDlg::Update. Event 3: EID_SET_OUTPUT_ITEM Item Type %i Item ID %i", pItem->GetType(), pItem->GetItemNo()); //assert( pItem && m_OutputItemSlots[iIndex].GetIcon() == NULL ); if( pItem && m_OutputItemSlots[iIndex].GetIcon() == NULL ) { m_OutputItemSlots[iIndex].AttachIcon( pItem->CreateItemIcon() ); } else if( pItem && m_OutputItemSlots[iIndex].GetIcon() != NULL) { m_OutputItemSlots[iIndex].DetachIcon(); m_OutputItemSlots[iIndex].AttachIcon( pItem->CreateItemIcon() ); } else { assert(" pItem && m_OutputItemSlots[iIndex].GetIcon() == NULL ?? "); //PY: Logically speaking, this can never happen unless it is simultaineously neither NULL or Not NULL. Duhh!! } } break; } case CTEventSeparate::EID_RECEIVE_RESULT: { ClientLog (LOG_NORMAL, "CSeperateDlg::Update. Event 5: EID_RECEIVE_RESULT"); ChangeState( STATE_RESULT ); break; } default: { ClientLog (LOG_NORMAL, "CSeperateDlg::Update. Invalid Seperate Event"); assert( 0 && "Invalid Separate Event Type" ); } break; } }
void CGItemListArea::PaintItem (CG16bitImage &Dest, const CItem &Item, const RECT &rcRect, bool bSelected) // PaintItem // // Paints the item { // Item context CItemCtx Ctx(&Item, m_pListData->GetSource()); CItemType *pItemType = Item.GetType(); // Paint the image DrawItemTypeIcon(Dest, rcRect.left, rcRect.top, pItemType); RECT rcDrawRect = rcRect; rcDrawRect.left += ICON_WIDTH + ITEM_TEXT_MARGIN_X; rcDrawRect.right -= ITEM_TEXT_MARGIN_X; rcDrawRect.top += ITEM_TEXT_MARGIN_Y; // Paint the attribute blocks RECT rcAttrib; rcAttrib = rcDrawRect; rcAttrib.bottom = rcAttrib.top + m_pFonts->MediumHeavyBold.GetHeight(); if (Item.IsDamaged()) PaintItemModifier(Dest, CONSTLIT("Damaged"), RGB_ILLEGAL_BACKGROUND, &rcAttrib); else if (Item.IsDisrupted()) PaintItemModifier(Dest, CONSTLIT("Ionized"), RGB_ILLEGAL_BACKGROUND, &rcAttrib); if (pItemType->IsKnown() && pItemType->HasAttribute(CONSTLIT("Military"))) PaintItemModifier(Dest, CONSTLIT("Military"), RGB_MILITARY_BACKGROUND, &rcAttrib); if (pItemType->IsKnown() && pItemType->HasAttribute(CONSTLIT("Illegal"))) PaintItemModifier(Dest, CONSTLIT("Illegal"), RGB_ILLEGAL_BACKGROUND, &rcAttrib); CString sEnhanced = Item.GetEnhancedDesc(m_pListData->GetSource()); if (!sEnhanced.IsBlank()) { bool bDisadvantage = (*(sEnhanced.GetASCIIZPointer()) == '-'); PaintItemModifier(Dest, sEnhanced, (bDisadvantage ? RGB_ILLEGAL_BACKGROUND : RGB_MILITARY_BACKGROUND), &rcAttrib); } // Paint the item name int cyHeight; RECT rcTitle = rcDrawRect; rcTitle.right = rcAttrib.right; m_pFonts->LargeBold.DrawText(Dest, rcTitle, m_pFonts->wItemTitle, Item.GetNounPhrase(nounCount | nounNoModifiers), 0, CG16bitFont::SmartQuotes | CG16bitFont::TruncateLine, &cyHeight); rcDrawRect.top += cyHeight; // Stats CString sStat; int iLevel = pItemType->GetApparentLevel(); CString sReference = pItemType->GetReference(Ctx); DamageTypes iDamageType; CString sDamageRef; int iDamageAdj[damageCount]; int iHP; if (Item.GetReferenceDamageType(m_pListData->GetSource(), -1, 0, &iDamageType, &sDamageRef)) { // Paint the initial text sStat = strPatternSubst("Level %s —", strLevel(iLevel)); int cxWidth = m_pFonts->Medium.MeasureText(sStat, &cyHeight); m_pFonts->Medium.DrawText(Dest, rcDrawRect, m_pFonts->wItemRef, sStat, 0, 0, &cyHeight); // Paint the damage type reference m_pUIRes->DrawReferenceDamageType(Dest, rcDrawRect.left + cxWidth + DAMAGE_ADJ_SPACING_X, rcDrawRect.top, iDamageType, sDamageRef); rcDrawRect.top += cyHeight; // Paint additional reference in the line below if (!sReference.IsBlank()) { m_pFonts->Medium.DrawText(Dest, rcDrawRect, m_pFonts->wItemRef, sReference, 0, 0, &cyHeight); rcDrawRect.top += cyHeight; } } else if (Item.GetReferenceDamageAdj(m_pListData->GetSource(), 0, &iHP, iDamageAdj)) { // Paint the initial text sStat = strPatternSubst("Level %s — hp: %d ", strLevel(iLevel), iHP); int cxWidth = m_pFonts->Medium.MeasureText(sStat, &cyHeight); m_pFonts->Medium.DrawText(Dest, rcDrawRect, m_pFonts->wItemRef, sStat, 0, 0, &cyHeight); // Paint the damage type array m_pUIRes->DrawReferenceDamageAdj(Dest, rcDrawRect.left + cxWidth + DAMAGE_ADJ_SPACING_X, rcDrawRect.top, iLevel, iHP, iDamageAdj); rcDrawRect.top += cyHeight; // Paint additional reference in the line below if (!sReference.IsBlank()) { m_pFonts->Medium.DrawText(Dest, rcDrawRect, m_pFonts->wItemRef, sReference, 0, 0, &cyHeight); rcDrawRect.top += cyHeight; } } else { if (sReference.IsBlank()) sStat = strPatternSubst("Level %s", strLevel(iLevel)); else sStat = strPatternSubst("Level %s — %s", strLevel(iLevel), sReference); m_pFonts->Medium.DrawText(Dest, rcDrawRect, m_pFonts->wItemRef, sStat, 0, 0, &cyHeight); rcDrawRect.top += cyHeight; } // Description CString sDesc = Item.GetDesc(); m_pFonts->Medium.DrawText(Dest, rcDrawRect, (bSelected ? m_pFonts->wItemDescSelected : m_pFonts->wItemDesc), sDesc, 0, CG16bitFont::SmartQuotes, &cyHeight); rcDrawRect.top += cyHeight; }
void CChar::Use_CarveCorpse( CItemCorpse * pCorpse ) { ADDTOCALLSTACK("CChar::Use_CarveCorpse"); CREID_TYPE CorpseID = pCorpse->m_itCorpse.m_BaseID; CCharBase *pCorpseDef = CCharBase::FindCharBase(CorpseID); if ( !pCorpseDef || pCorpse->m_itCorpse.m_carved ) { SysMessageDefault(DEFMSG_CARVE_CORPSE_NOTHING); return; } CChar *pChar = pCorpse->m_uidLink.CharFind(); CPointMap pnt = pCorpse->GetTopLevelObj()->GetTopPoint(); UpdateAnimate(ANIM_BOW); if ( pCorpse->m_TagDefs.GetKeyNum("BLOOD", true) ) { CItem *pBlood = CItem::CreateBase(ITEMID_BLOOD4); ASSERT(pBlood); pBlood->SetHue(pCorpseDef->m_wBloodHue); pBlood->MoveToDecay(pnt, 5 * TICK_PER_SEC); } size_t iItems = 0; for ( size_t i = 0; i < pCorpseDef->m_BaseResources.GetCount(); i++ ) { long long iQty = pCorpseDef->m_BaseResources[i].GetResQty(); RESOURCE_ID rid = pCorpseDef->m_BaseResources[i].GetResourceID(); if ( rid.GetResType() != RES_ITEMDEF ) continue; ITEMID_TYPE id = static_cast<ITEMID_TYPE>(rid.GetResIndex()); if ( id == ITEMID_NOTHING ) break; iItems++; CItem *pPart = CItem::CreateTemplate(id, NULL, this); ASSERT(pPart); switch ( pPart->GetType() ) { case IT_FOOD: case IT_FOOD_RAW: case IT_MEAT_RAW: SysMessageDefault(DEFMSG_CARVE_CORPSE_MEAT); //pPart->m_itFood.m_MeatType = CorpseID; break; case IT_HIDE: SysMessageDefault(DEFMSG_CARVE_CORPSE_HIDES); //pPart->m_itSkin.m_creid = CorpseID; if ( (g_Cfg.m_iRacialFlags & RACIALF_HUMAN_WORKHORSE) && IsHuman() ) // humans always find 10% bonus when gathering hides, ores and logs (Workhorse racial trait) iQty = iQty * 110 / 100; break; case IT_FEATHER: SysMessageDefault(DEFMSG_CARVE_CORPSE_FEATHERS); //pPart->m_itSkin.m_creid = CorpseID; break; case IT_WOOL: SysMessageDefault(DEFMSG_CARVE_CORPSE_WOOL); //pPart->m_itSkin.m_creid = CorpseID; break; /*case IT_DRAGON_SCALE: // TO-DO (typedef IT_DRAGON_SCALE doesn't exist yet) SysMessageDefault(DEFMSG_CARVE_CORPSE_SCALES); //pPart->m_itSkin.m_creid = CorpseID; break;*/ default: break; } if ( iQty > 1 ) pPart->SetAmount(static_cast<unsigned int>(iQty)); if ( pChar && pChar->m_pPlayer ) { TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_CORPSE_NAME), pPart->GetName(), pChar->GetName()); pPart->SetName(pszMsg); pPart->m_uidLink = pChar->GetUID(); pPart->MoveToDecay(pnt, pPart->GetDecayTime()); continue; } pCorpse->ContentAdd(pPart); } if ( iItems < 1 ) SysMessageDefault(DEFMSG_CARVE_CORPSE_NOTHING); CheckCorpseCrime(pCorpse, false, false); pCorpse->m_itCorpse.m_carved = 1; // mark as been carved pCorpse->m_itCorpse.m_uidKiller = GetUID(); // by you if ( pChar && pChar->m_pPlayer ) pCorpse->SetTimeout(0); // reset corpse timer to make it turn bones }
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; }
void GenerateShieldStats (CUniverse &Universe, CXMLElement *pCmdLine) { int i; CString sUNID = pCmdLine->GetAttribute(CONSTLIT("unid")); DWORD dwUNID = strToInt(sUNID, 0, NULL); CItemType *pItem = Universe.FindItemType(dwUNID); if (pItem == NULL) { CItemCriteria Crit; CItem::InitCriteriaAll(&Crit); CItem Item = CItem::CreateItemByName(sUNID, Crit); pItem = Item.GetType(); if (pItem == NULL) { printf("ERROR: Unknown item '%s'\n", sUNID.GetASCIIZPointer()); return; } } if (pItem->GetCategory() != itemcatShields) { printf("ERROR: Item '%s' is not a shield generator\n", pItem->GetNounPhrase().GetASCIIZPointer()); return; } bool bVerbose = pCmdLine->GetAttributeBool(CONSTLIT("verbose")); bool bEval = pCmdLine->GetAttributeBool(CONSTLIT("eval")); // Get the stats for the shield Metric rHP = (Metric)pItem->GetDataFieldInteger(FIELD_HP); Metric rHPRegenPerTick = pItem->GetDataFieldInteger(FIELD_REGEN) / 1000.0; int iDamageAdj[damageCount]; CString sDamageAdj = pItem->GetDataField(CONSTLIT("damageAdj")); char *pPos = sDamageAdj.GetASCIIZPointer(); int iCount = 0; while (iCount < damageCount) { iDamageAdj[iCount] = strParseInt(pPos, 0, &pPos, NULL); if (*pPos != '\0') pPos++; iCount++; } // Print header printf("%s\n\n", pItem->GetNounPhrase().GetASCIIZPointer()); // Loop over all weapons and sort them by level and then name CSymbolTable List(FALSE, TRUE); for (i = 0; i < Universe.GetItemTypeCount(); i++) { CItemType *pWeapon = Universe.GetItemType(i); if (pWeapon->GetCategory() != itemcatWeapon) continue; CString sLevel = (pWeapon->GetLevel() < 10 ? strPatternSubst(CONSTLIT("0%d"), pWeapon->GetLevel()) : strFromInt(pWeapon->GetLevel(), FALSE)); CString sSortName = strPatternSubst(CONSTLIT("%s%s"), sLevel, pWeapon->GetNounPhrase()); List.AddEntry(sSortName, (CObject *)pWeapon); } // Loop over sorted list and output data for (i = 0; i < List.GetCount(); i++) { CItemType *pWeapon = (CItemType *)List.GetValue(i); // Get the data for the weapon int iFireDelay = pWeapon->GetDataFieldInteger(CONSTLIT("fireDelay")); Metric rAverageDamage = pWeapon->GetDataFieldInteger(CONSTLIT("averageDamage")) / 1000.0; int iDamageType = pWeapon->GetDataFieldInteger(CONSTLIT("damageType")); if (iDamageType < 0 || iDamageType >= damageCount) iDamageType = 0; // Adjust damage for type rAverageDamage = rAverageDamage * (iDamageAdj[iDamageType] / 100.0); if (rAverageDamage < 1.0) rAverageDamage = 0.0; // Calculate how many shots it would take to pierce through the shields char szBuffer[256]; Metric rShotsToDeplete; Metric rRegenPerShot = rHPRegenPerTick * (Metric)iFireDelay; if (rRegenPerShot >= rAverageDamage) { rShotsToDeplete = 1000000.0; lstrcpy(szBuffer, "ineffective"); } else { Metric rDrainPerShot = rAverageDamage - rRegenPerShot; rShotsToDeplete = rHP / rDrainPerShot; sprintf(szBuffer, "%.2f", rShotsToDeplete); } // See if this weapon is overpowered or underpowered char szEval[256]; if (bEval) { lstrcpy(szEval, "\t"); if (pWeapon->GetLevel() < pItem->GetLevel()) { if (rShotsToDeplete <= 10.0) lstrcpy(szEval, "\tOVERpowered"); } else { if (rShotsToDeplete > 20.0) lstrcpy(szEval, "\tUNDERpowered"); } } else lstrcpy(szEval, ""); // Print table if (bVerbose) { printf("%s\t%s\t%s\t(%d ticks; %.2f damage; %.2f regen/shot)%s\n", RomanNumeral(pWeapon->GetLevel()), pWeapon->GetNounPhrase().GetASCIIZPointer(), szBuffer, iFireDelay, rAverageDamage, rRegenPerShot, szEval); } else { printf("%s\t%s\t%s%s\n", RomanNumeral(pWeapon->GetLevel()), pWeapon->GetNounPhrase().GetASCIIZPointer(), szBuffer, szEval); } } }