Exemplo n.º 1
0
// 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);
    }
}
Exemplo n.º 2
0
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()
    );
}
Exemplo n.º 3
0
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);
    }
}
Exemplo n.º 4
0
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;
	}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
//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();
}
Exemplo n.º 7
0
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);
    }
}
Exemplo n.º 8
0
void CPlayerGameStats::OnItemFired (const CItem &Item)

//	OnItemFired
//
//	Player fired the item (weapon or missile)

	{
	SItemTypeStats *pStats = GetItemStats(Item.GetType()->GetUNID());
	pStats->iCountFired++;
	}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
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);
}
Exemplo n.º 11
0
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());
    }
}
Exemplo n.º 12
0
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;
	}
Exemplo n.º 13
0
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;
	}
Exemplo n.º 14
0
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);
		}
	}
Exemplo n.º 15
0
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);
	}
Exemplo n.º 16
0
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 );
}
Exemplo n.º 17
0
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());
	}
Exemplo n.º 18
0
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++;
	}
Exemplo n.º 19
0
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);
		}
	}
Exemplo n.º 20
0
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;
}
Exemplo n.º 21
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;
}
Exemplo n.º 22
0
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 ;
}
Exemplo n.º 23
0
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 )
Exemplo n.º 24
0
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;
	}
Exemplo n.º 25
0
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;
	}
Exemplo n.º 26
0
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;
	}

}
Exemplo n.º 27
0
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;
	}
Exemplo n.º 28
0
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
}
Exemplo n.º 29
0
bool CChar::CanSeeLOS_New( const CPointMap &ptDst, CPointMap *pptBlock, int iMaxDist, word flags, bool bCombatCheck ) const
{
	ADDTOCALLSTACK("CChar::CanSeeLOS_New");
	// WARNING: CanSeeLOS is an expensive function (lot of calculations but	most importantly it has to read the UO files, and file I/O is slow).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		if ( !bPath )
			break;

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

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

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

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

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

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

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

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

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

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

		if ( !bPath )
			break;

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

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

						if ( !pItem )
							continue;

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

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

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

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

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

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

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

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

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

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

						if ( !bPath )
							break;
					}
				}
			}
		}

		if ( bNullTerrain )
			bPath = false;

		if ( !bPath )
			break;
	}

	path.clear();

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

	return true;
}
Exemplo n.º 30
0
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);
			}
		}
	}