// WorldObject.cpp : Implementation of cWorldObject
#include "stdafx.h"
#include "DecalFilters.h"
#include "World.h"
#include "WorldObject.h"
#include ".\worldobject.h"

/////////////////////////////////////////////////////////////////////////////
// cWorldObject

cWorldObject::~cWorldObject()
{
}


HRESULT cWorldObject::GetLong(long val, long *ret)
{
	if (!ret) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*ret = val ;
	return S_OK ;
}


STDMETHODIMP cWorldObject::get_GUID(long *pVal)
{   
	return GetLong(m_p->m_dwGUID, pVal) ;
}

STDMETHODIMP cWorldObject::get_Model(long *pVal)
{
	return GetLong(m_p->m_dwModel, pVal) ;
}

STDMETHODIMP cWorldObject::get_RealModel(LONG* pVal)
{
	return GetLong(m_p->m_dwRealModel, pVal) ;
}

STDMETHODIMP cWorldObject::get_Icon(long *pVal)
{
	return GetLong(m_p->m_dwIcon, pVal) ;
}

STDMETHODIMP cWorldObject::get_Name(BSTR *pVal)
{
	USES_CONVERSION;

	if(!pVal)
	{
		_ASSERT(FALSE);
		return E_POINTER;
	}

	*pVal = T2BSTR(m_p->m_strName.c_str());

	return S_OK;
}

STDMETHODIMP cWorldObject::get_SecondaryName(BSTR *pVal)
{
	USES_CONVERSION;

	if(!pVal)
	{
		_ASSERT(FALSE);
		return E_POINTER;
	}

	*pVal = T2BSTR(m_p->m_strSecondaryName.c_str());

	return S_OK;
}

STDMETHODIMP cWorldObject::get_Value(long *pVal)
{
	return GetLong(m_p->m_dwValue, pVal) ;
}

STDMETHODIMP cWorldObject::get_Container(long *pVal)
{
	return GetLong(m_p->m_dwContainer, pVal) ;
}

STDMETHODIMP cWorldObject::get_Landblock(long *pVal)
{
	HRESULT hr = GetLong(m_p->m_dwLandblock, pVal) ;
	hr = (hr==S_OK && (m_p->m_flags & FLAG_LOCATION)) ? S_OK : S_FALSE ;
	return hr ;
}

STDMETHODIMP cWorldObject::get_Offset(float *x, float *y, float *z, short *pVal)
{
	if(!pVal || !x || !y || !z)
	{
		_ASSERT(FALSE);
		return E_POINTER;
	}

	HRESULT hr = S_OK ;
	if (m_p->m_flags & FLAG_LOCATION) {
		*pVal = true;
		*x = m_p->m_fxOffset;
		*y = m_p->m_fyOffset;
		*z = m_p->m_fzOffset;
	} else {
		*pVal = false;
		*x = 0;
		*y = 0;
		*z = 0;
		hr = S_FALSE;
	}
	return hr ;
}


STDMETHODIMP cWorldObject::get_Heading(float *x, float *y, float *z, float *w, short *pVal)
{
	if(!pVal || !x || !y || !z || !w)
	{
		_ASSERT(FALSE);
		return E_POINTER;
	}
	HRESULT hr = S_OK ;
	if (m_p->m_flags & FLAG_LOCATION) {
		*pVal = true;
		// Gouru: modified so that x, y, and z are current position information, there is 
		//	no such thing as x,y,z heading information from the server.
		*x = m_p->m_fxOffset;
		*y = m_p->m_fyOffset;
		*z = m_p->m_fzOffset;
		*w = m_p->m_fwHeading;
	} else {
		*pVal = false;
		*x = 0;
		*y = 0;
		*z = 0;
		*w = 0;
		hr = S_FALSE;
	}
	return hr ;
}

STDMETHODIMP cWorldObject::get_Type(eObjectType *pVal)
{
	if(!pVal)
	{
		_ASSERT(FALSE);
		return E_POINTER;
	}

	*pVal = m_p->m_eType;
	return S_OK;
}

STDMETHODIMP cWorldObject::get_ItemSlots(long *pVal)
{
	return GetLong(m_p->m_nItemSlots, pVal) ;
}

STDMETHODIMP cWorldObject::get_PackSlots(long *pVal)
{
	return GetLong(m_p->m_nPackSlots, pVal) ;
}

STDMETHODIMP cWorldObject::get_Lockable(VARIANT_BOOL *pVal)
{
	if(!pVal) {
		_ASSERT(FALSE);
		return E_POINTER;
	}

	*pVal = (m_p->m_flags & FLAG_LOCKABLE) ? VARIANT_TRUE : VARIANT_FALSE;

	return S_OK;
}

STDMETHODIMP cWorldObject::get_Inscribable(VARIANT_BOOL *pVal)
{
	if(!pVal) {
		_ASSERT(FALSE);
		return E_POINTER;
	}

	*pVal = (m_p->m_flags & FLAG_INSCRIBABLE) ? VARIANT_TRUE : VARIANT_FALSE ;
	return S_OK;
}


STDMETHODIMP cWorldObject::get_UsesLeft(long *pVal)
{
	return GetLong(m_p->m_nUsesLeft, pVal) ;
}

STDMETHODIMP cWorldObject::get_TotalUses(long *pVal)
{	
	return GetLong(m_p->m_nTotalUses, pVal) ;
}

STDMETHODIMP cWorldObject::get_StackCount(long *pVal)
{
	return GetLong(m_p->m_nStackCount, pVal) ;
}

STDMETHODIMP cWorldObject::get_StackMax(long *pVal)
{
	return GetLong(m_p->m_nStackMax, pVal) ;
}

STDMETHODIMP cWorldObject::get_TradeNoteVendor(long *pVal)
{
	return GetLong(m_p->m_dwTradeNoteVendor, pVal) ;
}

STDMETHODIMP cWorldObject::get_AssociatedSpell(long *pVal)
{
	return GetLong(m_p->m_dwAssociatedSpell, pVal) ;
}

STDMETHODIMP cWorldObject::get_Slot(long *pVal)
{
	return GetLong(m_p->m_Slot.slot, pVal) ;
}

// Gouru: call maintained for backwards compatability. Owner will always be the same
//	as the container. If you want the player that owns this item,  
STDMETHODIMP cWorldObject::get_Owner(long *pVal)
{
	return GetLong(m_p->m_dwContainer, pVal) ;
}

STDMETHODIMP cWorldObject::get_Wielder(long *pVal)
{
	return GetLong(m_p->m_dwWielder, pVal) ;
}

STDMETHODIMP cWorldObject::get_WieldingSlot(long *pVal)
{
	return GetLong(m_p->m_dwWieldingSlot, pVal) ;
}


// Gouru: this method should NEVER be implemented. It requires knowledge of the location of
//	 other objects. And since it is easily computed from the coordinates returned by
//	get_Coordinates, this seems like a major waste. Method however is still here to avoid
//	breaking the interface.
STDMETHODIMP cWorldObject::get_Distance(float *NorthSouth, float *EastWest, VARIANT_BOOL *pVal)
{
	return E_NOTIMPL ;
}


STDMETHODIMP cWorldObject::get_Coordinates(float *NorthSouth, float *EastWest, VARIANT_BOOL *pVal)
{
	// code based on algorithm from GKusnick
	if (NorthSouth==NULL || EastWest==NULL ) {
		_ASSERT(FALSE);
		if (pVal) *pVal = VARIANT_FALSE ;
		return E_POINTER ;
	}

	*NorthSouth = cWorld::NorthSouth(m_p->m_dwLandblock, m_p->m_fyOffset) ;
	*EastWest	= cWorld::EastWest(m_p->m_dwLandblock, m_p->m_fxOffset) ;

	if (pVal) *pVal = VARIANT_TRUE ;

	return S_OK ;
}

// Exposes the raw coordinate data as sent by the server, for those who prefer to do their own calcs.
STDMETHODIMP cWorldObject::get_RawCoordinates(float *pX, float *pY, float *pZ, VARIANT_BOOL *pVal)
{
	if (pX==NULL || pY==NULL ) {
		_ASSERT(FALSE);
		if (pVal) *pVal = VARIANT_FALSE ;
		return E_POINTER ;
	}

	*pX = m_p->m_fxOffset;
	*pY = m_p->m_fyOffset;

	if (pZ)
	{
		*pZ = m_p->m_fzOffset;
	}

	if (pVal)
	{
		*pVal = VARIANT_TRUE ;
	}

	return S_OK ;
}


STDMETHODIMP cWorldObject::get_Scale(float* pVal)
{
	*pVal = m_p->m_fScale;
	return S_OK;
}

STDMETHODIMP cWorldObject::get_Flags(long *pVal)
{
	return GetLong(m_p->m_flags, pVal) ;
}

STDMETHODIMP cWorldObject::get_CreateFlags1(long *pVal)
{
	return GetLong(m_p->m_dwFlags1, pVal) ;
}

STDMETHODIMP cWorldObject::get_CreateFlags2(long *pVal)
{
	return GetLong(m_p->m_dwFlags2, pVal) ;
}

STDMETHODIMP cWorldObject::get_ObjectFlags1(long *pVal)
{
	return GetLong(m_p->m_dwObjectFlags1, pVal) ;
}

STDMETHODIMP cWorldObject::get_ObjectFlags2(long *pVal)
{
	return GetLong(m_p->m_dwObjectFlags2, pVal) ;
}

STDMETHODIMP cWorldObject::get_Monarch(long *pVal) {
	return GetLong(m_p->m_dwMonarch, pVal) ;
}

STDMETHODIMP cWorldObject::get_Material(long *pVal) {
	return GetLong(m_p->m_dwMaterial, pVal) ;
}

STDMETHODIMP cWorldObject::get_Coverage(long *pVal) {
	return GetLong(m_p->m_dwCoverage, pVal) ;
}


STDMETHODIMP cWorldObject::get_Coverage2(long *pVal) {
	return GetLong(m_p->m_dwCoverage2, pVal) ;
}

STDMETHODIMP cWorldObject::get_Coverage3(long *pVal) {
	return GetLong(m_p->m_dwCoverage3, pVal) ;
}

STDMETHODIMP cWorldObject::get_EquipType(long *pVal) {
	return GetLong(m_p->m_dwEquipType, pVal) ;
}

STDMETHODIMP cWorldObject::get_Burden(long *pVal) {
	return GetLong(m_p->m_Burden, pVal) ;
}

STDMETHODIMP cWorldObject::get_IconOutline(long *pVal) {
	return GetLong(m_p->m_IconOutline, pVal) ;
}

STDMETHODIMP cWorldObject::get_MissileType(long *pVal) {
	return GetLong(m_p->m_MissileType, pVal) ;
}

STDMETHODIMP cWorldObject::get_TotalValue(long *pVal) {
	return GetLong(m_p->m_TotalValue, pVal) ;
}

STDMETHODIMP cWorldObject::get_UsageMask(long *pVal) {
	return GetLong(m_p->m_UsageMask, pVal) ;
}

STDMETHODIMP cWorldObject::get_HouseOwner(long *pVal) {
	return GetLong(m_p->m_HouseOwner, pVal) ;
}

STDMETHODIMP cWorldObject::get_HookMask(long *pVal) {
	return GetLong(m_p->m_HookMask, pVal) ;
}

STDMETHODIMP cWorldObject::get_HookType(long *pVal) {
	return GetLong(m_p->m_HookType, pVal) ;
}

STDMETHODIMP cWorldObject::get_ApproachDistance(float *pVal) {
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_fApproachDistance ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_Workmanship(float *pVal) {
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_Workmanship ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_HasIdData(VARIANT_BOOL *pVal)
{
	if(!pVal) {
		_ASSERT(FALSE);
		return E_POINTER;
	}

	*pVal = m_p->m_HasIdData ;
	return S_OK;
}

STDMETHODIMP cWorldObject::get_ArmorLevel(long *pVal)
{
	return GetLong(m_p->m_ArmorLevel, pVal) ;
}

STDMETHODIMP cWorldObject::get_MagicDef(long *pVal)
{
	return GetLong(m_p->m_MagicDef, pVal) ;
}

STDMETHODIMP cWorldObject::get_Spellcraft(long *pVal)
{
	return GetLong(m_p->m_Spellcraft, pVal) ;
}

STDMETHODIMP cWorldObject::get_MaximumMana(long *pVal)
{
	return GetLong(m_p->m_MaximumMana, pVal) ;
}

STDMETHODIMP cWorldObject::get_LoreReq(long *pVal)
{
	return GetLong(m_p->m_LoreReq, pVal) ;
}

STDMETHODIMP cWorldObject::get_RankReq(long *pVal)
{
	return GetLong(m_p->m_RankReq, pVal) ;
}

STDMETHODIMP cWorldObject::get_SkillReq(long *pVal)
{
	return GetLong(m_p->m_SkillReq, pVal) ;
}

STDMETHODIMP cWorldObject::get_WieldReqType(long *pVal)
{
	return GetLong(m_p->m_WieldReqType, pVal) ;
}

STDMETHODIMP cWorldObject::get_WieldReqId(long *pVal)
{
	return GetLong(m_p->m_WieldReqId, pVal) ;
}

STDMETHODIMP cWorldObject::get_WieldReq(long *pVal)
{
	return GetLong(m_p->m_WieldReq, pVal) ;
}

STDMETHODIMP cWorldObject::get_TinkerCount(long *pVal)
{
	return GetLong(m_p->m_TinkerCount, pVal) ;
}

STDMETHODIMP cWorldObject::get_SkillReqId(long *pVal)
{
	return GetLong(m_p->m_SkillReqId, pVal) ;
}

STDMETHODIMP cWorldObject::get_SpecialProps(long *pVal)
{
	return GetLong(m_p->m_SpecialProps, pVal) ;
}

STDMETHODIMP cWorldObject::get_ManaCMod(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_ManaCMod ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_SpellCount(long *pVal)
{
	return GetLong(m_p->m_SpellCount, pVal) ;
}

STDMETHODIMP cWorldObject::get_Spell(long ix, long *pVal)
{
	return GetLong(m_p->m_Spell[ix], pVal) ;
}

STDMETHODIMP cWorldObject::get_Inscription(BSTR *pVal)
{
	USES_CONVERSION;

	if(!pVal)
	{
		_ASSERT(FALSE);
		return E_POINTER;
	}

	*pVal = T2BSTR(m_p->m_Inscription.c_str());

	return S_OK;
}

STDMETHODIMP cWorldObject::get_RaceReq(BSTR *pVal)
{
	USES_CONVERSION;

	if(!pVal)
	{
		_ASSERT(FALSE);
		return E_POINTER;
	}

	*pVal = T2BSTR(m_p->m_RaceReq.c_str());

	return S_OK;
}

STDMETHODIMP cWorldObject::get_WeapSpeed(long *pVal)
{
	return GetLong(m_p->m_WeapSpeed, pVal) ;
}

STDMETHODIMP cWorldObject::get_EquipSkill(long *pVal)
{
	return GetLong(m_p->m_EquipSkill, pVal) ;
}

STDMETHODIMP cWorldObject::get_DamageType(long *pVal)
{
	return GetLong(m_p->m_DamageType, pVal) ;
}

STDMETHODIMP cWorldObject::get_MaxDamage(long *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_MaxDamage ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_Variance(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_Variance ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_DefenseBonus(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_DefenseBonus ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_AttackBonus(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_AttackBonus ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_Range(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_Range ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_SlashProt(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_SlashProt ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_PierceProt(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_PierceProt ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_BludProt(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_BludProt ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_ColdProt(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_ColdProt ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_FireProt(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_FireProt ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_ElectProt(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_ElectProt ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_AcidProt(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_AcidProt ;
	return S_OK ;
}

STDMETHODIMP cWorldObject::get_DamageBonus(float *pVal)
{
	if (!pVal) {
		_ASSERT(FALSE) ;
		return E_POINTER ;
	}
	*pVal = m_p->m_DamageBonus ;
	return S_OK ;
}

