class BleedingIndicatorDropData { protected ImageWidget m_Widget; protected int m_Severity; protected float m_TimeTotal; protected float m_ProgressBreakpointTime; protected float m_ProgressFadingDuration; //remaining duration AFTER breakpoint protected float m_ProgressBreakpoint; protected float m_Duration; protected float m_SpeedCoef; protected int m_ScatterPx; protected float m_SlideDistance; protected float m_ColorAlphaStart; protected float m_ColorAlphaEnd; protected float m_ColorAlphaCurrent; protected float m_ImageBaseSizeX; protected float m_ImageBaseSizeY; protected float m_ImageStartingSizeX; //adjusted by percentage protected float m_ImageStartingSizeY; //adjusted by percentage protected float m_ImageEndSizeX; //adjusted by percentage protected float m_ImageEndSizeY; //adjusted by percentage protected float m_ImageMaxSizeX; protected float m_ImageMaxSizeY; protected float m_ImageBaseRotation; protected bool m_IsRunning; protected vector m_BasePosition; protected int m_ScreenSizeX; protected int m_ScreenSizeY; protected float m_PosX, m_PosY; protected float m_StartSizeCoef; protected float m_EndSizeCoef; protected float m_RandomSizeMin; protected float m_RandomSizeMax; //Written with relative positioning in mind void BleedingIndicatorDropData(ImageWidget image, int severity) { m_Widget = image; m_Severity = severity; m_TimeTotal = 0; m_IsRunning = false; #ifdef DIAG_DEVELOPER if (DbgBleedingIndicationStaticInfo.m_DbgUseOverrideValues) { m_Duration = DbgBleedingIndicationStaticInfo.m_DbgDropDurationBase; m_ProgressBreakpointTime = m_Duration * DbgBleedingIndicationStaticInfo.m_DbgDropProgressTreshold; m_ProgressBreakpoint = DbgBleedingIndicationStaticInfo.m_DbgDropProgressTreshold; m_StartSizeCoef = DbgBleedingIndicationStaticInfo.m_DbgDropStartSize; m_EndSizeCoef = DbgBleedingIndicationStaticInfo.m_DbgDropEndSize; m_RandomSizeMin = DbgBleedingIndicationStaticInfo.m_DbgDropSizeVariationMin; m_RandomSizeMax = DbgBleedingIndicationStaticInfo.m_DbgDropSizeVariationMax; m_ScatterPx = DbgBleedingIndicationStaticInfo.m_DbgDropScatter; m_SlideDistance = DbgBleedingIndicationStaticInfo.m_DbgDropSlideDistance; } else #endif { switch (m_Severity) { case BleedingIndicationConstants.INDICATOR_SEVERITY_LOW: { m_Duration = BleedingIndicationConstants.DROP_DURATION_LOW; m_StartSizeCoef = BleedingIndicationConstants.DROP_SIZE_START_LOW; m_EndSizeCoef = BleedingIndicationConstants.DROP_SIZE_END_LOW; m_RandomSizeMin = BleedingIndicationConstants.DROP_SIZE_VARIATION_MIN_LOW; m_RandomSizeMax = BleedingIndicationConstants.DROP_SIZE_VARIATION_MAX_LOW; m_ScatterPx = BleedingIndicationConstants.DROP_SCATTER_LOW; m_SlideDistance = BleedingIndicationConstants.DROP_SLIDE_DISTANCE_LOW; break; } case BleedingIndicationConstants.INDICATOR_SEVERITY_MEDIUM: { m_Duration = BleedingIndicationConstants.DROP_DURATION_MEDIUM; m_StartSizeCoef = BleedingIndicationConstants.DROP_SIZE_START_MEDIUM; m_EndSizeCoef = BleedingIndicationConstants.DROP_SIZE_END_MEDIUM; m_RandomSizeMin = BleedingIndicationConstants.DROP_SIZE_VARIATION_MIN_MEDIUM; m_RandomSizeMax = BleedingIndicationConstants.DROP_SIZE_VARIATION_MAX_MEDIUM; m_ScatterPx = BleedingIndicationConstants.DROP_SCATTER_MEDIUM; m_SlideDistance = BleedingIndicationConstants.DROP_SLIDE_DISTANCE_MEDIUM; break; } case BleedingIndicationConstants.INDICATOR_SEVERITY_HIGH: { m_Duration = BleedingIndicationConstants.DROP_DURATION_HIGH; m_StartSizeCoef = BleedingIndicationConstants.DROP_SIZE_START_HIGH; m_EndSizeCoef = BleedingIndicationConstants.DROP_SIZE_END_HIGH; m_RandomSizeMin = BleedingIndicationConstants.DROP_SIZE_VARIATION_MIN_HIGH; m_RandomSizeMax = BleedingIndicationConstants.DROP_SIZE_VARIATION_MAX_HIGH; m_ScatterPx = BleedingIndicationConstants.DROP_SCATTER_HIGH; m_SlideDistance = BleedingIndicationConstants.DROP_SLIDE_DISTANCE_HIGH; break; } } m_ProgressBreakpointTime = m_Duration * BleedingIndicationConstants.DROP_PROGRESS_THRESHOLD; m_ProgressBreakpoint = BleedingIndicationConstants.DROP_PROGRESS_THRESHOLD; } m_ProgressFadingDuration = Math.Max(0.0001, m_Duration - m_ProgressBreakpointTime); m_SpeedCoef = 1.0; //TODO ?? #ifdef DIAG_DEVELOPER if (DbgBleedingIndicationStaticInfo.m_DbgUseOverrideValues) { m_ColorAlphaStart = DbgBleedingIndicationStaticInfo.m_DbgDropColorAlphaStart / 255; m_ColorAlphaEnd = DbgBleedingIndicationStaticInfo.m_DbgDropColorAlphaEnd / 255; } else #endif { m_ColorAlphaStart = BleedingIndicationConstants.DROP_COLOR_ALPHA_START / 255; m_ColorAlphaEnd = BleedingIndicationConstants.DROP_COLOR_ALPHA_END / 255; } InitImageScale(); GetScreenSize(m_ScreenSizeX,m_ScreenSizeY); AdjustColorSaturation(); } void ~BleedingIndicatorDropData() { } protected void InitImageScale() { m_Widget.GetSize(m_ImageBaseSizeX,m_ImageBaseSizeY); float randomScaleCoef = Math.RandomFloatInclusive(m_RandomSizeMin,m_RandomSizeMax); m_ImageStartingSizeX = m_ImageBaseSizeX * m_StartSizeCoef * randomScaleCoef; m_ImageEndSizeX = m_ImageBaseSizeX * m_EndSizeCoef * randomScaleCoef; m_ImageStartingSizeY = m_ImageBaseSizeY * m_StartSizeCoef * randomScaleCoef; m_ImageEndSizeY = m_ImageBaseSizeY * m_EndSizeCoef * randomScaleCoef; } void ScatterPosition(vector pos) { #ifdef DIAG_DEVELOPER if (DbgBleedingIndicationStaticInfo.m_DbgUseOverrideValues) { m_ScatterPx = DbgBleedingIndicationStaticInfo.m_DbgDropScatter; } #endif float rndRadius = Math.RandomFloatInclusive(0.0,m_ScatterPx); float rndPos = Math.RandomFloatInclusive(0.0,Math.PI2); m_PosX = pos[0]; m_PosX = m_PosX + rndRadius * Math.Sin(rndPos); m_PosY = pos[1]; m_PosY = m_PosY + rndRadius * Math.Cos(rndPos); } void StartDrop() { m_TimeTotal = 0; ScatterPosition(m_BasePosition); m_Widget.SetPos(m_PosX,m_PosY); #ifdef DIAG_DEVELOPER if (DbgBleedingIndicationStaticInfo.m_DbgUseOverrideValues && !DbgBleedingIndicationStaticInfo.m_DbgDropRotationRandom) { m_Widget.SetRotation(0,0,0); } else #endif { m_Widget.SetRotation(0,0,Math.RandomFloatInclusive(0.0,360.0)); } m_Widget.Show(true); m_IsRunning = true; } void StopDrop() { m_IsRunning = false; m_Widget.SetSize(m_ImageBaseSizeX,m_ImageBaseSizeY); //resets image size m_Widget.Show(false); } void SetBasePosition(vector pos) { m_BasePosition = pos; m_BasePosition[0] = m_BasePosition[0] - m_ScreenSizeX/2; m_BasePosition[1] = m_BasePosition[1] - m_ScreenSizeY/2; } bool IsRunning() { return m_IsRunning; } ImageWidget GetImage() { return m_Widget; } void AdjustColorSaturation() { //color adjustment float r = BleedingIndicationConstants.DROP_COLOR_RED; float g = BleedingIndicationConstants.DROP_COLOR_GREEN; float b = BleedingIndicationConstants.DROP_COLOR_BLUE; float desaturationEnd = BleedingIndicationConstants.DROP_COLOR_DESATURATIONEND; #ifdef DIAG_DEVELOPER if (DbgBleedingIndicationStaticInfo.m_DbgUseOverrideValues) { r = DbgBleedingIndicationStaticInfo.m_DbgDropColorRed; g = DbgBleedingIndicationStaticInfo.m_DbgDropColorGreen; b = DbgBleedingIndicationStaticInfo.m_DbgDropColorBlue; desaturationEnd = DbgBleedingIndicationStaticInfo.m_DbgDesaturationEnd; } #endif //saturation adjustment #ifdef DIAG_DEVELOPER if (!DbgBleedingIndicationStaticInfo.m_DbgUseOverrideValues || (DbgBleedingIndicationStaticInfo.m_DbgUseOverrideValues && DbgBleedingIndicationStaticInfo.m_DbgDropDesaturate) ) { #endif Param par = PPEManagerStatic.GetPPEManager().GetPostProcessCurrentValues(PostProcessEffectType.Glow,PPEGlow.PARAM_SATURATION); float saturationProgress = Param1.Cast(par).param1; saturationProgress = Easing.EaseOutSine(saturationProgress); saturationProgress = Math.Lerp(desaturationEnd,1.0,saturationProgress); float lowest_channel = Math.Min(Math.Min(r,g),b); r = Math.Lerp(lowest_channel,r,saturationProgress); g = Math.Lerp(lowest_channel,g,saturationProgress); b = Math.Lerp(lowest_channel,b,saturationProgress); #ifdef DIAG_DEVELOPER } #endif int color = ARGB(0x00,r,g,b); m_Widget.SetColor(color); } void UpdateAlpha(float progress,float progressFade) { if (progress <= m_ProgressBreakpoint) { m_ColorAlphaCurrent = m_ColorAlphaStart; } else { m_ColorAlphaCurrent = Math.Lerp(m_ColorAlphaStart,m_ColorAlphaEnd,progressFade); } m_Widget.SetAlpha(m_ColorAlphaCurrent); } //! scaling and transformation void UpdateTransform(float progress, float progressFade) { float breakProgress = Math.Clamp(Math.InverseLerp(0.0,m_ProgressBreakpoint,progress),0,1); float sizeX = Math.Lerp(m_ImageStartingSizeX,m_ImageEndSizeX,breakProgress); float sizeY = Math.Lerp(m_ImageStartingSizeY,m_ImageEndSizeY,breakProgress); m_Widget.SetSize(sizeX,sizeY); if (progress <= m_ProgressBreakpoint) { //do stuff before breakpoint } else { //do stuff after breakpoint float posYTemp = Math.Lerp(m_PosY,m_PosY + m_SlideDistance, progressFade); m_Widget.SetPos(m_PosX,posYTemp); } } void Update(float timeSlice) { if (m_IsRunning) { float progress, progressFade; progress = m_TimeTotal / m_Duration; progressFade = (m_TimeTotal - m_ProgressBreakpointTime) / m_ProgressFadingDuration; //alpha UpdateAlpha(progress,progressFade); //transform + scaling UpdateTransform(progress,progressFade); m_TimeTotal += (timeSlice * m_SpeedCoef); if (m_TimeTotal >= m_Duration) { //deletes this; StopDrop(); } } } }