コード例 #1
0
ファイル: CContain.cpp プロジェクト: greeduomacro/Source
int CContainer::ContentConsume( RESOURCE_ID_BASE rid, int amount, bool fTest, DWORD dwArg )
{
	ADDTOCALLSTACK("CContainer::ContentConsume");
	// ARGS:
	//  dwArg = a hack for ores.
	// RETURN:
	//  0 = all consumed ok.
	//  # = number left to be consumed. (still required)

	if ( rid.GetResIndex() == 0 )
		return( amount );	// from skills menus.

	CItem * pItemNext;
	for ( CItem* pItem=GetContentHead(); pItem!=NULL; pItem=pItemNext)
	{
		pItemNext = pItem->GetNext();

		if ( pItem->IsResourceMatch( rid, dwArg ))
		{
			amount -= pItem->ConsumeAmount( amount, fTest );
			if ( amount <= 0 )
				break;
		}

		CItemContainer * pCont = dynamic_cast <CItemContainer*> (pItem);
		if ( pCont != NULL )	// this is a sub-container.
		{
			if ( rid == RESOURCE_ID(RES_TYPEDEF,IT_GOLD))
			{
				if ( pCont->IsType(IT_CONTAINER_LOCKED))
					continue;
			}
			else
			{
				if ( ! pCont->IsSearchable())
					continue;
			}
			amount = pCont->ContentConsume( rid, amount, fTest, dwArg );
			if ( amount <= 0 )
				break;
		}
	}
	return( amount );
}
コード例 #2
0
ファイル: CCharUse.cpp プロジェクト: DarkLotus/Source
bool CChar::Use_Train_ArcheryButte( CItem * pButte, bool fSetup )
{
	ADDTOCALLSTACK("CChar::Use_Train_ArcheryButte");
	// IT_ARCHERY_BUTTE
	ASSERT(pButte);

	ITEMID_TYPE AmmoID;
	if ( GetDist(pButte) < 2 )		// if we are standing right next to the butte, retrieve the arrows/bolts
	{
		if ( pButte->m_itArcheryButte.m_AmmoCount == 0 )
		{
			SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_EMPTY);
			return true;
		}

		AmmoID = pButte->m_itArcheryButte.m_AmmoType;
		CItemBase *pAmmoDef = CItemBase::FindItemBase(AmmoID);
		if ( pAmmoDef )
		{
			TCHAR *pszMsg = Str_GetTemp();
			sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_REM), pAmmoDef->GetName(), (pButte->m_itArcheryButte.m_AmmoCount == 1) ? "" : g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_REMS));
			Emote(pszMsg);

			CItem *pRemovedAmmo = CItem::CreateBase(AmmoID);
			ASSERT(pRemovedAmmo);
			pRemovedAmmo->SetAmount(pButte->m_itArcheryButte.m_AmmoCount);
			ItemBounce(pRemovedAmmo);
		}

		// Clear the target
		pButte->m_itArcheryButte.m_AmmoType = ITEMID_NOTHING;
		pButte->m_itArcheryButte.m_AmmoCount = 0;
		return true;
	}

	SKILL_TYPE skill = Fight_GetWeaponSkill();
	if ( !g_Cfg.IsSkillFlag(skill, SKF_RANGED) )
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_WS);
		return true;
	}
	if ( Skill_GetBase(skill) > g_Cfg.m_iSkillPracticeMax )
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_SKILL);
		return true;
	}

	// Make sure we have some ammo
	CItem *pWeapon = m_uidWeapon.ItemFind();
	ASSERT(pWeapon);
	const CItemBase *pWeaponDef = pWeapon->Item_GetDef();

	// Determine ammo type
	CVarDefCont *pVarAmmoType = pWeapon->GetDefKey("AMMOTYPE", true);
	RESOURCE_ID_BASE rid;
	LPCTSTR t_Str;

	if ( pVarAmmoType )
	{
		t_Str = pVarAmmoType->GetValStr();
		rid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str));
	}
	else
	{
		rid = pWeaponDef->m_ttWeaponBow.m_idAmmo;
	}
	AmmoID = static_cast<ITEMID_TYPE>(rid.GetResIndex());

	// If there is a different ammo type on the butte currently, tell us to remove the current type first
	if ( (pButte->m_itArcheryButte.m_AmmoType != ITEMID_NOTHING) && (pButte->m_itArcheryButte.m_AmmoType != AmmoID) )
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_X);
		return true;
	}

	// We need to be correctly aligned with the target before we can use it
	// For the south facing butte, we need to have the same X value and a Y > 2
	// For the east facing butte, we need to have the same Y value and an X > 2
	if ( !pButte->IsTopLevel() )
	{
	badalign:
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_P);
		return true;
	}

	int targDistX = GetTopPoint().m_x - pButte->GetTopPoint().m_x;
	int targDistY = GetTopPoint().m_y - pButte->GetTopPoint().m_y;

	if ( (pButte->GetID() == ITEMID_ARCHERYBUTTE_S) || (pButte->GetID() == ITEMID_MONGBATTARGET_S) )
	{
		if ( !(targDistX == 0 && targDistY > 2) )
			goto badalign;
	}
	else
	{
		if ( !(targDistY == 0 && targDistX > 2) )
			goto badalign;
	}

	if ( !CanSeeLOS(pButte, LOS_NB_WINDOWS) )	//we should be able to shoot through a window
	{
		SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_BLOCK);
		return true;
	}

	if ( fSetup )
	{
		if ( Skill_GetActive() == NPCACT_TRAINING )
			return true;
		UpdateAnimate(ANIM_ATTACK_WEAPON);
		m_Act_TargPrv = m_uidWeapon;
		m_Act_Targ = pButte->GetUID();
		Skill_Start(NPCACT_TRAINING);
		return true;
	}

	CVarDefCont *pCont = pWeapon->GetDefKey("AMMOCONT",true);

	if ( m_pPlayer && AmmoID )
	{
		int iFound = 1;
		if ( pCont )
		{
			//check for UID
			CGrayUID uidCont = static_cast<DWORD>(pCont->GetValNum());
			CItemContainer *pNewCont = dynamic_cast<CItemContainer*>(uidCont.ItemFind());
			if ( !pNewCont )	//if no UID, check for ITEMID_TYPE
			{
				t_Str = pCont->GetValStr();
				RESOURCE_ID_BASE rContid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str));
				ITEMID_TYPE ContID = static_cast<ITEMID_TYPE>(rContid.GetResIndex());
				if ( ContID )
					pNewCont = dynamic_cast<CItemContainer*>(ContentFind(rContid));
			}

			if ( pNewCont )
				iFound = pNewCont->ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID));
			else
				iFound = ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID));
		}
		else
			iFound = ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID));
		if ( iFound )
		{
			SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_NOAMMO);
			return(true);
		}
	}

	// OK...go ahead and fire at the target
	// Check the skill
	bool fSuccess = Skill_UseQuick(skill, Calc_GetRandLLVal(40));

	// determine animation parameters
	CVarDefCont *pVarAnim = pWeapon->GetDefKey("AMMOANIM", true);
	CVarDefCont *pVarAnimColor = pWeapon->GetDefKey("AMMOANIMHUE", true);
	CVarDefCont *pVarAnimRender = pWeapon->GetDefKey("AMMOANIMRENDER", true);
	ITEMID_TYPE AmmoAnim;
	DWORD AmmoHue;
	DWORD AmmoRender;

	if ( pVarAnim )
	{
		t_Str = pVarAnim->GetValStr();
		rid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str));
		AmmoAnim = static_cast<ITEMID_TYPE>(rid.GetResIndex());
	}
	else
		AmmoAnim = static_cast<ITEMID_TYPE>(pWeaponDef->m_ttWeaponBow.m_idAmmoX.GetResIndex());

	AmmoHue = pVarAnimColor ? static_cast<DWORD>(pVarAnimColor->GetValNum()) : 0;
	AmmoRender = pVarAnimRender ? static_cast<DWORD>(pVarAnimRender->GetValNum()) : 0;
	
	pButte->Effect(EFFECT_BOLT, AmmoAnim, this, 16, 0, false, AmmoHue, AmmoRender);
	pButte->Sound(0x224);

	// Did we destroy the ammo?
	const CItemBase *pAmmoDef = NULL;
	if ( AmmoID )
		pAmmoDef = CItemBase::FindItemBase(AmmoID);

	if ( !fSuccess )
	{
		// Small chance of destroying the ammo
		if ( pAmmoDef && !Calc_GetRandVal(10) )
		{
			TCHAR *pszMsg = Str_GetTemp();
			sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_DEST), pAmmoDef->GetName());
			Emote(pszMsg, NULL, true);
			return true;
		}

		static LPCTSTR const sm_Txt_ArcheryButte_Failure[] =
		{
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_1),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_2),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_3),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_4)
		};
		Emote(sm_Txt_ArcheryButte_Failure[Calc_GetRandVal(COUNTOF(sm_Txt_ArcheryButte_Failure))]);
	}
	else
	{
		// Very small chance of destroying another arrow
		if ( pAmmoDef && !Calc_GetRandVal(50) && pButte->m_itArcheryButte.m_AmmoCount )
		{
			TCHAR *pszMsg = Str_GetTemp();
			sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_SPLIT), pAmmoDef->GetName());
			Emote(pszMsg, NULL, true);
			return true;
		}

		static LPCTSTR const sm_Txt_ArcheryButte_Success[] =
		{
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_1),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_2),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_3),
			g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_4)
		};
		Emote(sm_Txt_ArcheryButte_Success[Calc_GetRandVal(COUNTOF(sm_Txt_ArcheryButte_Success))]);
	}

	// Update the target
	if ( AmmoID )
	{
		pButte->m_itArcheryButte.m_AmmoType = AmmoID;
		pButte->m_itArcheryButte.m_AmmoCount++;
	}
	return true;
}