void WBCompEldAnchor::Unanchor()
{
	ASSERT( m_IsAnchored );

	m_IsAnchored = false;

	WB_MAKE_EVENT( OnUnanchored, GetEntity() );
	WB_DISPATCH_EVENT( GetEventManager(), OnUnanchored, GetEntity() );
}
/*virtual*/ void WBActionUIPushScreen::Execute()
{
	// We can't push directly to the UI stack because we don't know anything about Framework3D
	// or whoever else might own a UI manager and stack. Instead, use Workbench events.

	WB_MAKE_EVENT( PushUIScreen, NULL );
	WB_SET_AUTO( PushUIScreen, Hash, Screen, m_ScreenName );
	WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), PushUIScreen, NULL );
}
示例#3
0
void WBCompEldSleeper::Wake() {
  if (m_IsAwake) {
    return;
  }

  m_IsAwake = true;

  WB_MAKE_EVENT(OnWoken, GetEntity());
  WB_DISPATCH_EVENT(GetEventManager(), OnWoken, GetEntity());
}
void WBCompEldPickup::SellItemTo( WBEntity* const pEntity )
{
	DEVASSERT( pEntity );

	sm_PurchasePickup	= this;
	sm_Purchaser		= pEntity;

	WBCompEldWallet* const pWallet = GET_WBCOMP( pEntity, EldWallet );
	ASSERT( pWallet );

	const bool CanAfford = ( pWallet->GetMoney() >= m_Price );

	STATICHASH( Purchase );

	STATICHASH( NameTag );
	ConfigManager::SetString( sNameTag, m_FriendlyName.CStr(), sPurchase );

	STATICHASH( ItemDesc );
	ConfigManager::SetString( sItemDesc, m_FriendlyDesc.CStr(), sPurchase );

	STATICHASH( PriceTag );
	ConfigManager::SetInt( sPriceTag, m_Price, sPurchase );

	STATIC_HASHED_STRING( PurchaseScreen );
	STATIC_HASHED_STRING( PurchaseBuyButton );

	// Disable the buy button if the price is too high
	{
		WB_MAKE_EVENT( SetWidgetDisabled, GetEntity() );
		WB_SET_AUTO( SetWidgetDisabled, Hash, Screen, sPurchaseScreen );
		WB_SET_AUTO( SetWidgetDisabled, Hash, Widget, sPurchaseBuyButton );
		WB_SET_AUTO( SetWidgetDisabled, Bool, Disabled, !CanAfford );
		WB_DISPATCH_EVENT( GetEventManager(), SetWidgetDisabled, NULL );
	}

	// Show the purchase screen
	{
		WB_MAKE_EVENT( PushUIScreen, GetEntity() );
		WB_SET_AUTO( PushUIScreen, Hash, Screen, sPurchaseScreen );
		WB_DISPATCH_EVENT( GetEventManager(), PushUIScreen, NULL );
	}
}
示例#5
0
void EldritchGame::SetUIReturnToHubDisabled( const bool Disabled )
{
    STATIC_HASHED_STRING( PauseScreen );
    STATIC_HASHED_STRING( PausedReturnButton );

    WB_MAKE_EVENT( SetWidgetDisabled, NULL );
    WB_SET_AUTO( SetWidgetDisabled, Hash, Screen, sPauseScreen );
    WB_SET_AUTO( SetWidgetDisabled, Hash, Widget, sPausedReturnButton );
    WB_SET_AUTO( SetWidgetDisabled, Bool, Disabled, Disabled );
    WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), SetWidgetDisabled, NULL );
}
示例#6
0
void WBCompEldHands::SetHandMeshes(
	const SimpleString& LeftHandMesh,
	const SimpleString& LeftHandTexture,
	const SimpleString& RightHandMesh,
	const SimpleString& RightHandTexture ) const
{
	{
		WB_MAKE_EVENT( SetMesh, GetEntity() );
		WB_SET_AUTO( SetMesh, Hash, Mesh, LeftHandMesh );
		WB_SET_AUTO( SetMesh, Hash, Texture, LeftHandTexture );
		WB_DISPATCH_EVENT( GetEventManager(), SetMesh, GetLeftHand() );
	}

	{
		WB_MAKE_EVENT( SetMesh, GetEntity() );
		WB_SET_AUTO( SetMesh, Hash, Mesh, RightHandMesh );
		WB_SET_AUTO( SetMesh, Hash, Texture, RightHandTexture );
		WB_DISPATCH_EVENT( GetEventManager(), SetMesh, GetRightHand() );
	}
}
示例#7
0
void WBCompEldHands::HideWeaponAltHUD() const
{
	STATIC_HASHED_STRING( HUD );
	STATIC_HASHED_STRING( WeaponAltIcon );

	WB_MAKE_EVENT( SetWidgetHidden, NULL );
	WB_SET_AUTO( SetWidgetHidden, Hash, Screen, sHUD );
	WB_SET_AUTO( SetWidgetHidden, Hash, Widget, sWeaponAltIcon );
	WB_SET_AUTO( SetWidgetHidden, Bool, Hidden, true );
	WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), SetWidgetHidden, NULL );
}
示例#8
0
void WBCompEldLock::Unlock()
{
	m_Locked = false;

	EldritchPersistence* const pPersistence = GetGame()->GetPersistence();
	ASSERT( pPersistence );
	pPersistence->AddOpenLock( m_Key );

	WB_MAKE_EVENT( OnUnlocked, GetEntity() );
	WB_LOG_EVENT( OnUnlocked );
	WB_DISPATCH_EVENT( GetEventManager(), OnUnlocked, GetEntity() );
}
示例#9
0
void WBCompEldHands::PlayAnimation( WBEntity* const pAnimatingEntity, const HashedString& AnimationName, const EHand Hand ) const
{
	if( !pAnimatingEntity )
	{
		return;
	}

	WB_MAKE_EVENT( PlayAnim, GetEntity() );
	WB_SET_AUTO( PlayAnim, Hash, AnimationName, AnimationName );
	WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), PlayAnim, pAnimatingEntity );
	WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), PlayAnim, GetHand( Hand ) );
}
// Borrowed from WBCompEldItem spawn drop code. Maybe unify?
/*virtual*/ void WBActionEldSpawnEntity::Execute()
{
	WBAction::Execute();

	WBEntity* const				pEntity				= GetOwner();

	WBParamEvaluator::SPEContext PEContext;
	PEContext.m_Entity = pEntity;
	m_EntityDefPE.Evaluate( PEContext );
	const SimpleString			EntityDef			= ( m_EntityDefPE.GetType() == WBParamEvaluator::EPT_String ) ? m_EntityDefPE.GetString() : m_EntityDef;

	WBEntity* const				pSpawnedEntity		= WBWorld::GetInstance()->CreateEntity( EntityDef );

	WBCompEldTransform* const	pSpawnedTransform	= pSpawnedEntity->GetTransformComponent<WBCompEldTransform>();
	ASSERT( pSpawnedTransform );

	WBCompOwner* const			pSpawnedOwner		= GET_WBCOMP( pSpawnedEntity, Owner );

	if( pSpawnedOwner )
	{
		pSpawnedOwner->SetOwner( pEntity );
	}

	Vector SpawnLocation;
	Vector SpawnImpulse;
	Angles SpawnOrientation;
	GetSpawnTransform( pSpawnedEntity, SpawnLocation, SpawnImpulse, SpawnOrientation );

	pSpawnedTransform->SetLocation(		SpawnLocation );
	pSpawnedTransform->SetOrientation(	SpawnOrientation );
	pSpawnedTransform->ApplyImpulse(	SpawnImpulse );

	WB_MAKE_EVENT( OnInitialOrientationSet, pSpawnedEntity );
	WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), OnInitialOrientationSet, pSpawnedEntity );

	// Notify instigator that we spawned this thing
	WB_MAKE_EVENT( OnSpawnedEntityAction, GetEntity() );
	WB_SET_AUTO( OnSpawnedEntityAction, Entity, SpawnedEntity, pSpawnedEntity );
	WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), OnSpawnedEntityAction, GetEntity() );
}
/*virtual*/ void WBActionEldSetLight::Execute()
{
	WBAction::Execute();

	STATIC_HASHED_STRING( EventOwner );
	WBEntity* const pEntity = WBActionStack::Top().GetEntity( sEventOwner );

	if( pEntity )
	{
		if( m_AddLight )
		{
			// Queue because if we do this during spawning, the world won't accept a light yet.
			WB_MAKE_EVENT( AddLight, pEntity );
			WB_QUEUE_EVENT( WBWorld::GetInstance()->GetEventManager(), AddLight, pEntity );
		}
		else
		{
			WB_MAKE_EVENT( RemoveLight, pEntity );
			WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), RemoveLight, pEntity );
		}
	}
}
示例#12
0
/*virtual*/ void WBActionEldTweetRIP::Execute() {
  WBAction::Execute();

  EldritchGame* const pGame = EldritchFramework::GetInstance()->GetGame();
  ASSERT(pGame);

  WBEventManager* const pEventManager =
      WBWorld::GetInstance()->GetEventManager();
  ASSERT(pEventManager);

  WB_MAKE_EVENT(TweetRIP, NULL);
  WB_LOG_EVENT(TweetRIP);
  WB_DISPATCH_EVENT(pEventManager, TweetRIP, pGame);
}
/*virtual*/ void WBActionUISetWidgetImage::Execute()
{
	WBParamEvaluator::SPEContext PEContext;
	PEContext.m_Entity = GetEntity();

	m_ImagePE.Evaluate( PEContext );
	const HashedString Image = ( m_ImagePE.GetType() == WBParamEvaluator::EPT_String ) ? m_ImagePE.GetString() : m_Image;

	WB_MAKE_EVENT( SetWidgetImage, NULL );
	WB_SET_AUTO( SetWidgetImage, Hash, Screen, m_ScreenName );
	WB_SET_AUTO( SetWidgetImage, Hash, Widget, m_WidgetName );
	WB_SET_AUTO( SetWidgetImage, Hash, Image, Image );
	WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), SetWidgetImage, NULL );
}
示例#14
0
void WBCompEldMesh::OnAnimationFinished(class Mesh* pMesh,
                                        class Animation* pAnimation,
                                        bool Interrupted) {
  Unused(pMesh);

  ASSERT(pAnimation);
  ASSERT(pMesh == m_Mesh);

  WB_MAKE_EVENT(OnAnimationFinished, GetEntity());
  WB_SET_AUTO(OnAnimationFinished, Hash, AnimationName,
              pAnimation->m_HashedName);
  WB_SET_AUTO(OnAnimationFinished, Bool, Interrupted, Interrupted);
  WB_DISPATCH_EVENT(GetEventManager(), OnAnimationFinished, GetEntity());
}
/*virtual*/ void WBActionEldSetPersistentVar::Execute()
{
	WBAction::Execute();

	WBParamEvaluator::SPEContext PEContext;
	PEContext.m_Entity = GetEntity();

	m_ValuePE.Evaluate( PEContext );

	WB_MAKE_EVENT( SetPersistentVar, NULL );
	WB_SET_AUTO( SetPersistentVar, Hash, Name, m_Key );
	WB_SET_AUTO_PE( SetPersistentVar, Value, m_ValuePE );
	WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), SetPersistentVar, NULL );
}
示例#16
0
RodinBTNode::ETickStatus RodinBTNodeEldLookAt::Tick(float DeltaTime) {
  Unused(DeltaTime);

  WBEntity* const pEntity = GetEntity();

  WBCompRodinBlackboard* const pAIBlackboard =
      GET_WBCOMP(pEntity, RodinBlackboard);
  ASSERT(pAIBlackboard);

  const WBEvent::EType TargetType =
      pAIBlackboard->GetType(m_LookTargetBlackboardKey);

  if (TargetType == WBEvent::EWBEPT_Vector) {
    const Vector LookTarget =
        pAIBlackboard->GetVector(m_LookTargetBlackboardKey);

    WB_MAKE_EVENT(LookAt, pEntity);
    WB_SET_AUTO(LookAt, Vector, LookAtLocation, LookTarget);
    WB_DISPATCH_EVENT(GetEventManager(), LookAt, pEntity);

    return ETS_Success;
  } else if (TargetType == WBEvent::EWBEPT_Entity) {
    WBEntity* const pLookTargetEntity =
        pAIBlackboard->GetEntity(m_LookTargetBlackboardKey);
    if (!pLookTargetEntity) {
      return ETS_Fail;
    }

    WB_MAKE_EVENT(LookAt, pEntity);
    WB_SET_AUTO(LookAt, Entity, LookAtEntity, pLookTargetEntity);
    WB_DISPATCH_EVENT(GetEventManager(), LookAt, pEntity);

    return ETS_Success;
  }

  return ETS_Fail;
}
void WBCompEldEndgameCounter::SetHUDHidden(const bool Hidden) const {
  UIManager* const pUIManager = GetFramework()->GetUIManager();
  ASSERT(pUIManager);

  STATIC_HASHED_STRING(HUD);
  STATIC_HASHED_STRING(EndgameImg);
  STATIC_HASHED_STRING(EndgameCounter);

  {
    WB_MAKE_EVENT(SetWidgetHidden, GetEntity());
    WB_SET_AUTO(SetWidgetHidden, Hash, Screen, sHUD);
    WB_SET_AUTO(SetWidgetHidden, Hash, Widget, sEndgameImg);
    WB_SET_AUTO(SetWidgetHidden, Bool, Hidden, Hidden);
    WB_DISPATCH_EVENT(GetEventManager(), SetWidgetHidden, pUIManager);
  }

  {
    WB_MAKE_EVENT(SetWidgetHidden, GetEntity());
    WB_SET_AUTO(SetWidgetHidden, Hash, Screen, sHUD);
    WB_SET_AUTO(SetWidgetHidden, Hash, Widget, sEndgameCounter);
    WB_SET_AUTO(SetWidgetHidden, Bool, Hidden, Hidden);
    WB_DISPATCH_EVENT(GetEventManager(), SetWidgetHidden, pUIManager);
  }
}
示例#18
0
void WBCompEldWatson::TickUnactivated()
{
	WBEntity* const pPlayer = EldritchGame::GetPlayer();
	ASSERT( pPlayer );

	WBCompEldSensorVision* const pVision = GET_WBCOMP( GetEntity(), EldSensorVision );
	ASSERT( pVision );

	if( pVision->IsVisible( pPlayer ) )
	{
		m_Activated = true;

		WB_MAKE_EVENT( OnWatsonActivated, GetEntity() );
		WB_DISPATCH_EVENT( GetEventManager(), OnWatsonActivated, GetEntity() );
	}
}
示例#19
0
void WBCompEldFrobber::TryFrob(const int InputEdge) {
  WBEntity* const pTargetFrobbable = m_FrobTarget.Get();
  DEBUGASSERT(pTargetFrobbable == FindTargetFrobbable());

  if (pTargetFrobbable) {
    WB_MAKE_EVENT(MarshalFrob, pTargetFrobbable);
    WB_SET_AUTO(MarshalFrob, Entity, Frobber, GetEntity());
    WB_SET_AUTO(MarshalFrob, Int, InputEdge, InputEdge);
    WB_DISPATCH_EVENT(GetEventManager(), MarshalFrob, pTargetFrobbable);

    // Untarget the frob target so we'll refresh the frob overlay on the next
    // tick.
    OnUnsetFrobTarget(pTargetFrobbable);
    m_FrobTarget = NULL;
  }
}
示例#20
0
void WBCompEldFrobbable::SetIsFrobTarget(const bool IsFrobTarget,
                                         WBEntity* const pFrobber) {
  m_IsProbableFrobbable = IsFrobTarget;

  WB_MAKE_EVENT(OnBecameFrobTarget, GetEntity());
  WB_SET_AUTO(OnBecameFrobTarget, Bool, IsFrobTarget, m_IsProbableFrobbable);
  WB_SET_AUTO(OnBecameFrobTarget, Entity, Frobber, pFrobber);
  WB_SET_AUTO(OnBecameFrobTarget, Vector, Highlight, m_Highlight);
  WB_DISPATCH_EVENT(GetEventManager(), OnBecameFrobTarget, GetEntity());

  if (IsFrobTarget) {
    PublishToHUD();
  } else {
    SetHUDHidden(true);
  }
}
示例#21
0
void WBCompEldHands::AddAnimationsToHand( WBEntity* const pItem, const EHand Hand ) const
{
	if( !pItem )
	{
		return;
	}

	if( pItem == GetRightHand() || pItem == GetLeftHand() )
	{
		return;
	}

	WB_MAKE_EVENT( CopyAnimations, GetEntity() );
	WB_SET_AUTO( CopyAnimations, Entity, SourceEntity, pItem );
	WB_SET_AUTO( CopyAnimations, Bool, SuppressAnimEvents, true );
	WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), CopyAnimations, GetHand( Hand ) );
}
示例#22
0
void WBCompEldMesh::Load(const IDataStream& Stream) {
  XTRACE_FUNCTION;

  ASSERT(m_Mesh);

  const uint Version = Stream.ReadUInt32();

  if (Version >= VERSION_MESHNAME) {
    const SimpleString MeshName = Stream.ReadString();
    if (MeshName != m_MeshName) {
      SetMesh(MeshName);
    }
  }

  if (Version >= VERSION_TEXTURENAME) {
    const SimpleString TextureName = Stream.ReadString();
    if (TextureName != m_TextureName) {
      SetTexture(TextureName);
    }
  }

  if (Version >= VERSION_MESHSCALE) {
    Stream.Read(sizeof(Vector), &m_Mesh->m_Scale);
  }

  if (Version >= VERSION_HIDDEN) {
    m_Hidden = Stream.ReadBool();
  }

  if (Version >= VERSION_ANIMATION) {
    const int AnimationIndex = Stream.ReadInt32();
    const float AnimationTime = Stream.ReadFloat();
    const int AnimationEndBehavior = Stream.ReadInt32();
    const float AnimationPlayRate =
        (Version >= VERSION_ANIMRATE) ? Stream.ReadFloat() : 1.0f;

    if (m_Mesh->IsAnimated()) {
      WB_MAKE_EVENT(SetAnim, GetEntity());
      WB_SET_AUTO(SetAnim, Int, AnimationIndex, AnimationIndex);
      WB_SET_AUTO(SetAnim, Float, AnimationTime, AnimationTime);
      WB_SET_AUTO(SetAnim, Int, AnimationEndBehavior, AnimationEndBehavior);
      WB_SET_AUTO(SetAnim, Float, AnimationPlayRate, AnimationPlayRate);
      WB_QUEUE_EVENT(GetEventManager(), SetAnim, GetEntity());
    }
  }
}
/*virtual*/ void WBActionEldBankTransaction::Execute()
{
	WBAction::Execute();

	EldritchGame* const			pGame			= EldritchFramework::GetInstance()->GetGame();
	ASSERT( pGame );

	EldritchBank* const			pBank			= pGame->GetBank();
	ASSERT( pBank );

	WBEventManager* const		pEventManager	= WBWorld::GetInstance()->GetEventManager();
	ASSERT( pEventManager );

	WB_MAKE_EVENT( BankTransaction, NULL );
	WB_LOG_EVENT( BankTransaction );
	WB_SET_AUTO( BankTransaction, Int, Amount, m_Amount );
	WB_DISPATCH_EVENT( pEventManager, BankTransaction, pBank );
}
/*virtual*/ void WBActionEldPlayAnim::Execute()
{
	WBAction::Execute();

	STATIC_HASHED_STRING( EventOwner );
	WBEntity* const pEntity = WBActionStack::Top().GetEntity( sEventOwner );

	WBParamEvaluator::SPEContext PEContext;
	PEContext.m_Entity = pEntity;
	m_PlayRatePE.Evaluate( PEContext );

	if( pEntity )
	{
		WB_MAKE_EVENT( PlayAnim, pEntity );
		WB_SET_AUTO( PlayAnim, Hash, AnimationName, m_AnimationName );
		WB_SET_AUTO( PlayAnim, Bool, Loop, m_Loop );
		WB_SET_AUTO( PlayAnim, Float, PlayRate, m_PlayRatePE.GetFloat() );
		WB_DISPATCH_EVENT( WBWorld::GetInstance()->GetEventManager(), PlayAnim, pEntity );
	}
}
示例#25
0
RodinBTNode::ETickStatus RodinBTNodeEldPlayBark::Tick(float DeltaTime) {
  Unused(DeltaTime);

  WBEntity* const pEntity = GetEntity();

  WBParamEvaluator::SPEContext PEContext;
  PEContext.m_Entity = pEntity;
  m_SoundDefPE.Evaluate(PEContext);
  const SimpleString SoundDef =
      (m_SoundDefPE.GetType() == WBParamEvaluator::EPT_String)
          ? m_SoundDefPE.GetString()
          : m_SoundDef;

  WB_MAKE_EVENT(PlayBark, pEntity);
  WB_SET_AUTO(PlayBark, Hash, Sound, SoundDef);
  WB_SET_AUTO(PlayBark, Hash, Category, m_Category);
  WB_DISPATCH_EVENT(GetEventManager(), PlayBark, pEntity);

  return ETS_Success;
}
示例#26
0
/*virtual*/ void WBCompEldSensorTheft::HandleEvent(const WBEvent& Event) {
  XTRACE_FUNCTION;

  Super::HandleEvent(Event);

  STATIC_HASHED_STRING(OnTheft);

  const HashedString EventName = Event.GetEventName();
  if (EventName == sOnTheft) {
    STATIC_HASHED_STRING(Thief);
    WBEntity* const pThief = Event.GetEntity(sThief);

    HandleTheft(pThief);

    // Also, forward event to this entity for scripting to handle.
    {
      WB_MAKE_EVENT(OnTheftSensed, GetEntity());
      WB_SET_AUTO(OnTheftSensed, Entity, Thief, pThief);
      WB_DISPATCH_EVENT(GetEventManager(), OnTheftSensed, GetEntity());
    }
  }
}
示例#27
0
void EldritchGame::RequestGoToLevel( const SimpleString& NextLevel, const HashedString& NextWorldDef, const bool RestoreSpawnPoint )
{
    XTRACE_FUNCTION;

    if( NextLevel == "" || NextWorldDef == HashedString::NullString )
    {
        WARN;
        return;
    }

    // Make a checkpoint save, for crash protection
    Checkpoint();

    ASSERT( !m_GoToLevelOnNextTick );
    m_GoToLevelOnNextTick	= true;
    m_RestoreSpawnPoint		= RestoreSpawnPoint;
    m_NextLevelName			= NextLevel;
    m_NextWorldDef			= NextWorldDef;

    WBEventManager* const pEventManager = WBWorld::GetInstance()->GetEventManager();

    WB_MAKE_EVENT( PreLevelTransition, NULL );
    WB_DISPATCH_EVENT( pEventManager, PreLevelTransition, NULL );
}
示例#28
0
LRESULT CALLBACK Framework3D::WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	switch( uMsg )
	{
	case WM_CLOSE:
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			return 0;
		}

	case WM_SYSCOMMAND:
		{
			// Ignored so that releasing Alt doesn't cause game to hang
			if( wParam == SC_KEYMENU )
			{
				return 0;
			}
			break;
		}

	case WM_ACTIVATE:
		{
			if( wParam != WA_INACTIVE )
			{
				// Restore the resolution if it was changed from under us
				ASSERT( gSingletonFramework );
				WB_MAKE_EVENT( ConditionalRefreshDisplay, NULL );
				WB_DISPATCH_EVENT( gSingletonFramework->GetEventManager(), ConditionalRefreshDisplay, gSingletonFramework );
			}
			break;
		}

	case WM_NOTIFY_SIZE:
		{
			POINT* const	pSize = reinterpret_cast<POINT*>( lParam );

			ASSERT( gSingletonFramework );
			gSingletonFramework->SetLastWindowSize( *pSize );

			return 0;
		}

	case WM_GETMINMAXINFO:
		{
			MINMAXINFO* const pInfo = reinterpret_cast<MINMAXINFO*>( lParam );
			ASSERT( pInfo );

			ASSERT( gSingletonFramework );
			POINT LastWindowSize = gSingletonFramework->GetLastWindowSize();

			pInfo->ptMaxTrackSize.x = Max( pInfo->ptMaxTrackSize.x, LastWindowSize.x );
			pInfo->ptMaxTrackSize.y = Max( pInfo->ptMaxTrackSize.y, LastWindowSize.y );

			return 0;
		}

	case WM_MOUSEWHEEL:
		{
			const short WheelDelta = GET_WHEEL_DELTA_WPARAM( wParam );
			if( WheelDelta > 0 )
			{
				ASSERT( gSingletonFramework );
				gSingletonFramework->m_Mouse->Buffer( Mouse::EB_WheelUp );
			}
			else if( WheelDelta < 0 )
			{
				ASSERT( gSingletonFramework );
				gSingletonFramework->m_Mouse->Buffer( Mouse::EB_WheelDown );
			}
		}

	case WM_MOUSEMOVE:
		{
			ASSERT( gSingletonFramework );
			gSingletonFramework->m_Mouse->NotifyMouseMoved();
		}
	}

	return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
/*virtual*/ void WBActionEldCheckLine::Execute()
{
	WBAction::Execute();

	STATIC_HASHED_STRING( EventOwner );
	WBEntity* const				pEntity			= GetEntity();
	WBEntity* const				pOwnerEntity	= GetOwner();
	EldritchWorld* const		pWorld			= EldritchFramework::GetInstance()->GetWorld();
	WBEventManager* const		pEventManager	= WBWorld::GetInstance()->GetEventManager();

	Vector						LineStart;
	Angles						LineOrientation;
	GetLineTransform( LineStart, LineOrientation );
	const Vector				LineDirection	= LineOrientation.ToVector();

	CollisionInfo Info;
	Info.m_CollideWorld		= true;
	Info.m_CollideEntities	= true;
	Info.m_CollidingEntity	= pOwnerEntity;
	Info.m_UserFlags		= EECF_Trace;

	if( m_LineLength > 0.0f )
	{
		const Vector			LineEnd			= LineStart + LineDirection * m_LineLength;
		const Segment			TraceSegment	= Segment( LineStart, LineEnd );
		if( !pWorld->Trace( TraceSegment, Info ) )
		{
			return;
		}
	}
	else
	{
		const Ray				TraceRay		= Ray( LineStart, LineDirection );
		if( !pWorld->Trace( TraceRay, Info ) )
		{
			return;
		}
	}

	const Vector	HitLocation		= Info.m_Intersection;
	const Vector	HitNormal		= Info.m_Plane.m_Normal;

	// Notify this entity that the line check hit that entity.
	if( Info.m_HitEntity )
	{
		WB_MAKE_EVENT( OnLineCheck, pEntity );
		WB_SET_AUTO( OnLineCheck, Hash, CheckTag, m_CheckTag );
		WB_SET_AUTO( OnLineCheck, Entity, Checked, static_cast<WBEntity*>( Info.m_HitEntity ) );
		WB_SET_AUTO( OnLineCheck, Vector, LineDirection, LineDirection );
		WB_SET_AUTO( OnLineCheck, Vector, HitLocation, HitLocation );
		WB_SET_AUTO( OnLineCheck, Vector, HitNormal, HitNormal );
		WB_DISPATCH_EVENT( pEventManager, OnLineCheck, pEntity );
	}
	else
	{
		const Vector	HalfHitNormal	= 0.5f * Info.m_Plane.m_Normal;
		const Vector	HitVoxel		= pWorld->GetVoxelCenter( HitLocation - HalfHitNormal );

		WB_MAKE_EVENT( OnLineCheckMissed, pEntity );
		WB_SET_AUTO( OnLineCheckMissed, Hash, CheckTag, m_CheckTag );
		WB_SET_AUTO( OnLineCheckMissed, Vector, LineDirection, LineDirection );
		WB_SET_AUTO( OnLineCheckMissed, Vector, HitLocation, HitLocation );
		WB_SET_AUTO( OnLineCheckMissed, Vector, HitNormal, HitNormal );
		WB_SET_AUTO( OnLineCheckMissed, Vector, HitVoxel, HitVoxel );
		WB_DISPATCH_EVENT( pEventManager, OnLineCheckMissed, pEntity );
	}
}
/*virtual*/ void WBCompEldIcicles::Tick( float DeltaTime )
{
	XTRACE_FUNCTION;
	PROFILE_FUNCTION;

	Unused( DeltaTime );

	WBEntity* const				pEntity		= GetEntity();
	ASSERT( pEntity );

	WBCompEldAnchor* const		pAnchor		= GET_WBCOMP( pEntity, EldAnchor );
	ASSERT( pAnchor );

	if( !pAnchor->IsAnchored() )
	{
		return;
	}

	WBEntity* const				pPlayer		= EldritchGame::GetPlayer();

	if( !pPlayer )
	{
		return;
	}

	WBCompStatMod* const		pPlayerStatMod		= GET_WBCOMP( pPlayer, StatMod );
	ASSERT( pPlayerStatMod );

	WB_MODIFY_FLOAT( IgnoreIcicles, 0.0f, pPlayerStatMod );
	const bool IgnoreIcicles = ( WB_MODDED( IgnoreIcicles ) != 0.0f );

	if( IgnoreIcicles )
	{
		return;
	}

	EldritchWorld* const		pWorld				= GetWorld();
	ASSERT( pWorld );

	WBCompEldTransform* const	pTransform			= pEntity->GetTransformComponent<WBCompEldTransform>();
	ASSERT( pTransform );

	WBCompEldCollision* const	pCollision			= GET_WBCOMP( pEntity, EldCollision );
	ASSERT( pCollision );

	WBCompEldTransform* const	pPlayerTransform	= pPlayer->GetTransformComponent<WBCompEldTransform>();
	ASSERT( pPlayerTransform );

	WBCompEldCollision* const	pPlayerCollision	= GET_WBCOMP( pPlayer, EldCollision );
	ASSERT( pPlayerCollision );

	const Vector	CheckOffset	= Vector( 0.0f, 0.0f, -m_CheckDistance );
	const Vector	TraceStart	= pTransform->GetLocation();
	Vector			TraceEnd	= TraceStart + CheckOffset;

	// Early out if player doesn't intersect the trace bounds.
	Vector			EntityExtents	= pCollision->GetExtents();
	EntityExtents.z					= 0.0f;
	const AABB		TraceBox		= AABB( TraceEnd - EntityExtents, TraceStart + EntityExtents );
	const AABB		PlayerBox		= pPlayerCollision->GetBounds();
	if( !TraceBox.Intersects( PlayerBox ) )
	{
		return;
	}

	// Move trace up to the top of player so we don't check occlusion beyond player.
	const float	PlayerTopZ	= PlayerBox.m_Max.z;
	TraceEnd.z				= PlayerTopZ;

	// Do an occlusion test to make sure there's nothing blocking the trace.
	CollisionInfo Info;
	Info.m_CollideWorld			= true;
	Info.m_CollideEntities		= true;
	Info.m_CollidingEntity		= pEntity;
	Info.m_UserFlags			= EECF_Occlusion;
	Info.m_StopAtAnyCollision	= true;

	const bool Occluded			= pWorld->LineCheck( TraceStart, TraceEnd, Info );
	if( Occluded )
	{
		return;
	}

	// All checks passed. Unanchor to initiate falling sequence
	WB_MAKE_EVENT( Unanchor, pEntity );
	WB_DISPATCH_EVENT( GetEventManager(), Unanchor, pEntity );
}