//------------------------------------------------------------------------
void CDebugGun::Update( SEntityUpdateContext& ctx, int update)
{ 
  if (!IsSelected())
    return;
  
  static float drawColor[4] = {1,1,1,1};
  static const int dx = 5; 
  static const int dy = 15;
  static const float font = 1.2f;
  static const float fontLarge = 1.4f;

  IRenderer* pRenderer = gEnv->pRenderer;
  IRenderAuxGeom* pAuxGeom = pRenderer->GetIRenderAuxGeom();
  pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags);

  pRenderer->Draw2dLabel(pRenderer->GetWidth()/5.f, pRenderer->GetHeight()-35, fontLarge, drawColor, false, "Firemode: %s (%.1f)", m_fireModes[m_fireMode].first.c_str(), m_fireModes[m_fireMode].second);      

  ray_hit rayhit;
  
  unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
  if (m_fireModes[m_fireMode].first == "pierceability")
  { 
    flags = (unsigned int)m_fireModes[m_fireMode].second & rwi_pierceability_mask;
  }
  
  // use cam, no need for firing pos/dir
  CCamera& cam = GetISystem()->GetViewCamera();

  if (gEnv->pPhysicalWorld->RayWorldIntersection(cam.GetPosition()+cam.GetViewdir(), cam.GetViewdir()*HIT_RANGE, ent_all, flags, &rayhit, 1))
  {
    IMaterialManager* pMatMan = gEnv->p3DEngine->GetMaterialManager();
    IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem();
    IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem();
    
    int x = (int)(pRenderer->GetWidth() *0.5f) + dx;
    int y = (int)(pRenderer->GetHeight()*0.5f) + dx - dy;

    // draw normal
    ColorB colNormal(200,0,0,128);
    Vec3 end = rayhit.pt + 0.75f*rayhit.n;
    pAuxGeom->DrawLine(rayhit.pt, colNormal, end, colNormal);
    pAuxGeom->DrawCone(end, rayhit.n, 0.1f, 0.2f, colNormal);

    IEntity * pEntity = (IEntity*)rayhit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY);
    if(pEntity)
    {  
      pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)fontLarge, drawColor, false, pEntity->GetName());      
    }
    
    // material
    const char* matName = pMatMan->GetSurfaceType(rayhit.surface_idx)->GetName();

    if (matName[0])      
      pRenderer->Draw2dLabel((float)x, (y+=dy), (float)font, drawColor, false, "%s (%i)", matName, rayhit.surface_idx);

    pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.1f m", rayhit.dist);

    if (pEntity)
    {
      IScriptTable* pScriptTable = pEntity->GetScriptTable();

      // physics 
      if (IPhysicalEntity* pPhysEnt = pEntity->GetPhysics())
      {
        pe_status_dynamics status;
        if (pPhysEnt->GetStatus(&status))
        {        
          if (status.mass > 0.f)
            pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.1f kg", status.mass);

          pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "pe_type: %i", pPhysEnt->GetType());                

					// PartId - Part name
				ICharacterInstance* pCharacter = pEntity->GetCharacter(0);
					if (pCharacter)
					{
						CryFixedStringT<64> hit_part("unknown part");

						const int FIRST_ATTACHMENT_PARTID = 1000;
						if (rayhit.partid >= FIRST_ATTACHMENT_PARTID)
						{
							IAttachmentManager* pAttachmentManager = pCharacter->GetIAttachmentManager();
							IAttachment* pAttachment = pAttachmentManager->GetInterfaceByIndex(rayhit.partid - FIRST_ATTACHMENT_PARTID);
							if (pAttachment)
							{
								hit_part = pAttachment->GetName();
							}
						}
						else
						{
							ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton();
							ISkeletonPose* pSkeletonPose = pCharacter->GetISkeletonPose();
							const char* szJointName = pICharacterModelSkeleton->GetJointNameByID(pSkeletonPose->getBonePhysParentOrSelfIndex(rayhit.partid));
							if (szJointName && *szJointName)
								hit_part = szJointName;
						}

						pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "partId: %i (%s)", rayhit.partid, hit_part.c_str());
					}

          if (status.submergedFraction > 0.f)
            pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.2f submerged", status.submergedFraction);

          if (status.v.len2() > 0.0001f)
            pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.2f m/s", status.v.len());
        }   
      }  

    
      // class-specific stuff
      if (IActor* pActor = pActorSystem->GetActor(pEntity->GetId()))
      {
	        pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%8.2f health", pActor->GetHealth());
      }
      else if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(pEntity->GetId()))
      {
        const SVehicleStatus& status = pVehicle->GetStatus();
        
        pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%.0f%% health", 100.f*status.health);
        pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%i passengers", status.passengerCount);
        
        if (pVehicle->GetMovement() && pVehicle->GetMovement()->IsPowered())
        {
          pRenderer->Draw2dLabel((float)x, (float)(y+=dy),(float) font, drawColor, false, "Running");
        }
      }
      else
      {
        if (pScriptTable)
        {
          HSCRIPTFUNCTION func = 0;
          if (pScriptTable->GetValue("GetHealth", func) && func)
          {
            float health = 0.f;
            if (Script::CallReturn(gEnv->pScriptSystem, func, pScriptTable, health))
            {
              pRenderer->Draw2dLabel((float)x, (float)(y+=dy),(float) font, drawColor, false, "%.0f health", health);
            }
          }
					gEnv->pScriptSystem->ReleaseFunc(func);
        }
      }
    }    
  }  
}
bool CStickyProjectile::StickToEntity( const SStickParams& stickParams, IEntity* pTargetEntity )
{
	IEntity* pProjectileEntity = stickParams.m_pProjectile->GetEntity();
	ICharacterInstance* pCharInstance = pTargetEntity->GetCharacter(0);
	if( pCharInstance)	
	{
		IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId());
		if (!pActor || (stickParams.m_bStickToFriendlies || !pActor->IsFriendlyEntity(stickParams.m_ownerId)) && (gEnv->bMultiplayer || !pActor->IsDead()))
		{
			m_stuckJoint = GetJointIdFromPartId(*pTargetEntity, stickParams.m_targetPartId);
			m_stuckNormal = stickParams.m_stickNormal;
			m_stuckPartId = stickParams.m_targetPartId;

			ICharacterModelSkeleton* pICharacterModelSkeleton = pCharInstance->GetICharacterModel()->GetICharacterModelSkeleton();
			ISkeletonPose* pSkeleton = pCharInstance->GetISkeletonPose();
			const char* boneName = pICharacterModelSkeleton->GetJointNameByID(m_stuckJoint);
			const QuatT jointWorld = QuatT(pTargetEntity->GetWorldTM()) * pSkeleton->GetAbsJointByID(m_stuckJoint);
			QuatT loc;
			CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc );
			pProjectileEntity->SetWorldTM(Matrix34(loc));

			// Get the local pos and rot.
			loc = jointWorld.GetInverted() * loc;
			m_stuckPos = loc.t;
			m_stuckRot = loc.q;

			// Attach.
			if(AttachToCharacter( stickParams.m_pProjectile, *pTargetEntity, *pCharInstance, boneName))
			{
				m_flags |= eSF_IsStuck;
				m_flags |= pActor ? pActor->IsPlayer() ? eSF_StuckToPlayer : eSF_StuckToAI : 0;
				SetParentId(pTargetEntity->GetId());
				m_childId = pProjectileEntity->GetId();
				return true;
			}
		}
	}
	else
	{
		m_stuckNormal = stickParams.m_stickNormal;
		m_stuckPartId = stickParams.m_targetPartId;

		QuatT loc;
		CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc );

		AttachTo(stickParams.m_pProjectile, pTargetEntity);

		pProjectileEntity->SetWorldTM(Matrix34(loc));

		// Set as Stuck.
		SetParentId(pTargetEntity->GetId());
		m_childId = pProjectileEntity->GetId();
		m_flags |= eSF_IsStuck;

		//Store position and rotation relative to parent entity
		m_stuckPos = pProjectileEntity->GetPos();
		m_stuckRot = pProjectileEntity->GetRotation();
		return true;
	}

	return false;
}