void PropertyTree::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar*) 
{
    SCROLLINFO si;
    CRect rc;
    LONG nHeight;

    SetFocus();

    GetClientRect(rc);
    nHeight = rc.Height() + 1;

    ZeroMemory(&si, sizeof(SCROLLINFO));
    si.cbSize = sizeof(SCROLLINFO);
    si.fMask = SIF_RANGE;

    GetScrollInfo(SB_VERT, &si);

    LONG ny = GetOrigin();

    switch (nSBCode)
    {
        case SB_LINEDOWN:
            ny += PROPTREEITEM_DEFHEIGHT;
            break;

        case SB_LINEUP:
            ny -= PROPTREEITEM_DEFHEIGHT;
            break;

        case SB_PAGEDOWN:
            ny += nHeight;
            break;

        case SB_PAGEUP:
            ny -= nHeight;
            break;

        case SB_THUMBTRACK:
            ny = nPos;
            break;
    }

    ny = __min(__max(ny, si.nMin), si.nMax - nHeight);

    SetOriginOffset(ny);
    si.fMask = SIF_POS;
    si.nPos = ny;

    SetScrollInfo(SB_VERT, &si, TRUE);
    CheckScrollVisible();	// sets a flag thats used when drawing
    Invalidate();
}
void PropertyTree::UpdateScrollbar()
{
    SCROLLINFO si;
    LONG nHeight;
    CRect rc;

    GetClientRect(rc);
    nHeight = rc.Height() + 1;

    ZeroMemory(&si, sizeof(SCROLLINFO));
    si.cbSize = sizeof(SCROLLINFO);
    si.fMask = SIF_RANGE|SIF_PAGE;
    si.nMin = 0;
    si.nMax = GetRootItem()->GetTotalHeight();
    si.nPage = nHeight + PROPTREEITEM_DEFHEIGHT;

    if ((int)si.nPage>si.nMax)
        SetOriginOffset(0);

    SetScrollInfo(SB_VERT, &si, TRUE);
    CheckScrollVisible();	// sets a flag thats used when drawing
}
/* ------------------------------------------------------------------------------------ */
geBoolean CDSpotLight::Tick(geFloat dwTicks)
{
	geEntity_EntitySet *pSet;
	geEntity *pEntity;

	if(CCD->World() == NULL)
		return GE_TRUE;

	pSet = geWorld_GetEntitySet(CCD->World(), "DSpotLight");

	if(!pSet)
		return GE_TRUE;

	for(pEntity=geEntity_EntitySetGetNextEntity(pSet, NULL); pEntity;
		pEntity=geEntity_EntitySetGetNextEntity(pSet, pEntity))
	{
		DSpotLight *Light;
		geFloat		Radius;
		geFloat		Percentage;
		int			Index;
		geVec3d		Pos;
		int32		Leaf;

		Light = (DSpotLight*)geEntity_GetUserData(pEntity);

		if(!EffectC_IsStringNull(Light->TriggerName))
		{
			if(GetTriggerState(Light->TriggerName))
			{
				if(Light->active == GE_FALSE)
				{
					Light->DynLight = geWorld_AddLight(CCD->World());
					Light->active = GE_TRUE;
				}
			}
			else
			{
				if(Light->active == GE_TRUE)
					geWorld_RemoveLight(CCD->World(), Light->DynLight);

				Light->active = GE_FALSE;
			}
		}
		else
		{
			if(Light->active == GE_FALSE)
			{
				Light->DynLight = geWorld_AddLight(CCD->World());
				Light->active = GE_TRUE;
			//	CCD->ReportError("DSpotLight light added", false);
			}
		}

		if(Light->active == GE_TRUE)
		{
			// pass the OriginOffset to SetOrigin
            // so that the light will stay in the same position relative to the model.
            Light->origin = Light->OriginOffset;
			SetOriginOffset(Light->EntityName, Light->BoneName, Light->Model, &(Light->origin));
			geWorld_GetLeaf(CCD->World(), &(Light->origin), &Leaf);
			Pos = Light->origin;

			if(Light->Rotate)
			{
				if(Light->Model)
				{
					geXForm3d Xf;
					geVec3d  Tmp;
					geWorld_GetModelXForm(CCD->World(), Light->Model, &Xf);
					geXForm3d_GetEulerAngles(&Xf, &Tmp);
					geVec3d_Add(&(Light->RealAngle), &Tmp, &(Light->angles));

					geVec3d_Scale(&(Light->angles), GE_180OVERPI, &(Light->angles));
				}
				else if(!EffectC_IsStringNull(Light->EntityName))
				{
					// changed QD 07/15/06
					/*
					geXForm3d BoneXForm;
					geActor	*theActor;

					theActor = GetEntityActor(Light->EntityName);

					if(!EffectC_IsStringNull(Light->BoneName))
					{
						if(geActor_GetBoneTransform(theActor, Light->BoneName, &BoneXForm) != GE_TRUE)
							continue;					// No such bone
					}
					else
					{
						if(geActor_GetBoneTransform(theActor, RootBoneName(theActor), &BoneXForm) != GE_TRUE)
							continue;					// No such bone
					}

					geXForm3d_RotateY(&BoneXForm, Light->RealAngle.Y);
					geXForm3d_GetEulerAngles(&BoneXForm, &(Light->angles));
					Light->angles.Z += Light->RealAngle.Z;

					*/
					SetAngle(Light->EntityName, Light->BoneName, &(Light->angles));

					if(Light->RealAngle.X || Light->RealAngle.Y || Light->RealAngle.Z)
					{
						geXForm3d XForm, BoneXForm;

						geXForm3d_SetZRotation(&XForm, Light->RealAngle.Z);
						geXForm3d_RotateX(&XForm, Light->RealAngle.X);
						geXForm3d_RotateY(&XForm, Light->RealAngle.Y);

						geXForm3d_SetZRotation(&BoneXForm, Light->angles.Z);
						geXForm3d_RotateX(&BoneXForm, Light->angles.X);
						geXForm3d_RotateY(&BoneXForm, Light->angles.Y);

						geXForm3d_Multiply(&BoneXForm, &XForm, &XForm);
						geXForm3d_GetEulerAngles(&XForm, &(Light->angles));
					}
					// end change QD 07/15/06

					// convert to degrees
					geVec3d_Scale(&(Light->angles), GE_180OVERPI, &(Light->angles));

				}
			}


			Percentage = Light->LastTime / Light->RadiusSpeed;

			Index = (int)(Percentage * Light->NumFunctionValues);

			if(Light->InterpolateValues && Index < Light->NumFunctionValues - 1)
			{
				geFloat	Remainder;
				geFloat	InterpolationPercentage;
				int		DeltaValue;
				geFloat	Value;

				Remainder = (geFloat)fmod(Light->LastTime, Light->IntervalWidth);
				InterpolationPercentage = Remainder / Light->IntervalWidth;
				DeltaValue = Light->RadiusFunction[Index + 1] - Light->RadiusFunction[Index];
				Value = Light->RadiusFunction[Index] + DeltaValue * InterpolationPercentage;
				Percentage = ((geFloat)(Value - 'a')) / ((geFloat)('z' - 'a'));
			}
			else
				Percentage = ((geFloat)(Light->RadiusFunction[Index] - 'a')) / ((geFloat)('z' - 'a'));

			Radius = Percentage * (Light->MaxRadius - Light->MinRadius) + Light->MinRadius;

			// angles in degrees
			geWorld_SetSpotLightAttributes(CCD->World(),
										   Light->DynLight,
										   &Pos,
										   &(Light->Color),
										   Radius,
										   Light->arc,
										   &(Light->angles),
										   Light->style,
										   Light->CastShadows);

			Light->LastTime = (geFloat)fmod(Light->LastTime + dwTicks, Light->RadiusSpeed);

			if(EffectC_IsPointVisible(CCD->World(),
					CCD->CameraManager()->Camera(),
					&Pos,
					Leaf,
					EFFECTC_CLIP_LEAF ) == GE_FALSE)
			{
				geWorld_RemoveLight(CCD->World(), Light->DynLight);
				Light->active = GE_FALSE;
			}
		}
	}

	return GE_TRUE;
}
/* ------------------------------------------------------------------------------------ */
void CRain::Tick(geFloat dwTicks)
{
	geEntity_EntitySet *pSet;
	geEntity *pEntity;
	int i;
	Spray Sp;

	pSet = geWorld_GetEntitySet(CCD->World(), "Rain");

	if(!pSet)
		return;

	for(pEntity=geEntity_EntitySetGetNextEntity(pSet, NULL); pEntity;
		pEntity=geEntity_EntitySetGetNextEntity(pSet, pEntity))
	{
		Rain *R = (Rain*)geEntity_GetUserData(pEntity);

		if(!EffectC_IsStringNull(R->TriggerName))
		{
			if(GetTriggerState(R->TriggerName))
			{
				if(R->active == GE_FALSE)
				{
					for(i=0; i<R->EffectCount; i++)
						R->EffectList[i] = Create(R);

					R->active = GE_TRUE;
				}
			}
			else
			{
				if(R->active == GE_TRUE)
				{
					for(i=0; i<R->EffectCount; i++)
						CCD->EffectManager()->Item_Delete(EFF_SPRAY, R->EffectList[i]);

					R->active = GE_FALSE;
				}
			}
		}
		else
		{
			if(R->active == GE_FALSE)
			{
				for(i=0; i<R->EffectCount; i++)
					R->EffectList[i] = Create(R);

				R->active = GE_TRUE;
			}
		}

		if(R->active == GE_TRUE)
		{
			R->origin = R->OriginOffset;

			if(SetOriginOffset(R->EntityName, R->BoneName, R->Model, &(R->origin)))
			{
	  			geVec3d_Copy(&(R->origin), &(Sp.Source));
				geVec3d_AddScaled(&(Sp.Source), &(Sp.Gravity), Sp.MinUnitLife, &(Sp.Dest));

				// adjust position
				for(i=0; i<R->EffectCount; i++)
					CCD->EffectManager()->Item_Modify(EFF_SPRAY, R->EffectList[i], (void *)&Sp, SPRAY_SOURCE | SPRAY_ACTUALDEST);
			}
	    }
	}
}
/* ------------------------------------------------------------------------------------ */
geBoolean CDynalite::Tick(geFloat dwTicks)
{
	geEntity_EntitySet *pSet;
	geEntity *pEntity;

	if(CCD->World() == NULL)
		return GE_TRUE;

	pSet = geWorld_GetEntitySet(CCD->World(), "DynamicLight");

	if(!pSet)
		return GE_TRUE;

	for(pEntity=geEntity_EntitySetGetNextEntity(pSet, NULL); pEntity;
		pEntity=geEntity_EntitySetGetNextEntity(pSet, pEntity))
	{
		DynamicLight	*Light;
		geFloat			Radius;
		geFloat			Percentage;
		int				Index;
		geVec3d			Pos;
		int32			Leaf;

		Light = (DynamicLight*)geEntity_GetUserData(pEntity);

		if(!EffectC_IsStringNull(Light->TriggerName))
		{
			if(GetTriggerState(Light->TriggerName))
			{
				if(Light->active == GE_FALSE)
				{
					Light->DynLight = geWorld_AddLight(CCD->World());
					Light->active = GE_TRUE;
				}
			}
			else
			{
				if(Light->active == GE_TRUE)
					geWorld_RemoveLight(CCD->World(), Light->DynLight );

				Light->active = GE_FALSE;
			}
		}
		else
		{
			if(Light->active == GE_FALSE)
			{
				Light->DynLight = geWorld_AddLight(CCD->World());
				Light->active = GE_TRUE;
			}
		}

		if(Light->active==GE_TRUE)
		{
			//MOD010124 - Added next line of code to pass the OriginOffset to SetOrigin
            //            so that the light will stay in the same position relative to the model.
            //            Also we now call SetOriginOffset instead of SetOffset in the line after.
            Light->origin = Light->OriginOffset;
			SetOriginOffset(Light->EntityName, Light->BoneName, Light->Model, &(Light->origin));
			geWorld_GetLeaf(CCD->World(), &(Light->origin), &Leaf);
			Pos = Light->origin;

			Percentage = Light->LastTime / Light->RadiusSpeed;

			Index = (int)(Percentage * Light->NumFunctionValues);

			if(Light->InterpolateValues && Index < Light->NumFunctionValues - 1)
			{
				geFloat	Remainder;
				geFloat	InterpolationPercentage;
				int		DeltaValue;
				geFloat	Value;

				Remainder = (geFloat)fmod(Light->LastTime, Light->IntervalWidth);
				InterpolationPercentage = Remainder / Light->IntervalWidth;
				DeltaValue = Light->RadiusFunction[Index + 1] - Light->RadiusFunction[Index];
				Value = Light->RadiusFunction[Index] + DeltaValue * InterpolationPercentage;
				Percentage = ((geFloat)(Value - 'a')) / ((geFloat)('z' - 'a'));
			}
			else
				Percentage = ((geFloat)(Light->RadiusFunction[Index] - 'a')) / ((geFloat)('z' - 'a'));

			Radius = Percentage * (Light->MaxRadius - Light->MinRadius) + Light->MinRadius;

			geWorld_SetLightAttributes(CCD->World(),
									   Light->DynLight,
									   &Pos,
									   &(Light->Color),
									   Radius,
									   GE_TRUE);

			Light->LastTime = (geFloat)fmod(Light->LastTime + dwTicks, Light->RadiusSpeed);

			if(EffectC_IsPointVisible(CCD->World(),
					CCD->CameraManager()->Camera(),
					&Pos,
					Leaf,
					EFFECTC_CLIP_LEAF ) == GE_FALSE )
			{
				geWorld_RemoveLight(CCD->World(), Light->DynLight);
				Light->active = GE_FALSE;
			}
		}
	}

	return GE_TRUE;
}