protected virtual void OnFixedUpdate(float timeMult) { if (currentCarryOver.HasValue) { bool playersReady = true; foreach (Player player in players) { // Exit type is already provided playersReady &= player.OnLevelChanging(ExitType.None); } if (playersReady) { if (levelChangeTimer > 0) { levelChangeTimer -= timeMult; } else { root.ChangeLevel(currentCarryOver.Value); currentCarryOver = null; initState = InitState.Disposed; return; } } } if (difficulty != GameDifficulty.Multiplayer) { if (players.Count > 0) { Vector3 pos = players[0].Transform.Pos; int tx1 = (int)pos.X >> 5; int ty1 = (int)pos.Y >> 5; int tx2 = tx1; int ty2 = ty1; #if ENABLE_SPLITSCREEN for (int i = 1; i < players.Count; i++) { Vector3 pos2 = players[i].Transform.Pos; int tx = (int)pos2.X >> 5; int ty = (int)pos2.Y >> 5; if (tx1 > tx) { tx1 = tx; } else if (tx2 < tx) { tx2 = tx; } if (ty1 > ty) { ty1 = ty; } else if (ty2 < ty) { ty2 = ty; } } #endif // ToDo: Remove this branching #if __ANDROID__ const int ActivateTileRange = 20; #else const int ActivateTileRange = 26; #endif tx1 -= ActivateTileRange; ty1 -= ActivateTileRange; tx2 += ActivateTileRange; ty2 += ActivateTileRange; for (int i = 0; i < actors.Count; i++) { if (actors[i].OnTileDeactivate(tx1 - 2, ty1 - 2, tx2 + 2, ty2 + 2)) { i--; } } eventMap.ActivateEvents(tx1, ty1, tx2, ty2, initState != InitState.Initializing); } eventMap.ProcessGenerators(timeMult); } ResolveCollisions(); // Ambient Light Transition if (ambientLightCurrent != ambientLightTarget) { float step = timeMult * 0.012f; if (MathF.Abs(ambientLightCurrent - ambientLightTarget) < step) { ambientLightCurrent = ambientLightTarget; } else { ambientLightCurrent += step * ((ambientLightTarget < ambientLightCurrent) ? -1 : 1); } } // Weather if (weatherType != WeatherType.None && commonResources.Graphics != null) { // ToDo: Apply weather effect to all other cameras too Vector3 viewPos = cameras[0].Transform.Pos; for (int i = 0; i < weatherIntensity; i++) { TileMap.DebrisCollisionAction collisionAction; if (weatherOutdoors) { collisionAction = TileMap.DebrisCollisionAction.Disappear; } else { collisionAction = (MathF.Rnd.NextFloat() > 0.7f ? TileMap.DebrisCollisionAction.None : TileMap.DebrisCollisionAction.Disappear); } Vector3 debrisPos = viewPos + MathF.Rnd.NextVector3((LevelRenderSetup.TargetSize.X / -2) - 40, (LevelRenderSetup.TargetSize.Y * -2 / 3), MainPlaneZ, LevelRenderSetup.TargetSize.X + 120, LevelRenderSetup.TargetSize.Y, 0); if (weatherType == WeatherType.Rain) { GraphicResource res = commonResources.Graphics["Rain"]; Material material = res.Material.Res; Texture texture = material.MainTexture.Res; float scale = MathF.Rnd.NextFloat(0.4f, 1.1f); float speedX = MathF.Rnd.NextFloat(2.2f, 2.7f) * scale; float speedY = MathF.Rnd.NextFloat(7.6f, 8.6f) * scale; debrisPos.Z = MainPlaneZ * scale; tileMap.CreateDebris(new TileMap.DestructibleDebris { Pos = debrisPos, Size = res.Base.FrameDimensions, Speed = new Vector2(speedX, speedY), Scale = scale, Angle = MathF.Atan2(speedY, speedX), Alpha = 1f, Time = 180f, Material = material, MaterialOffset = texture.LookupAtlas(res.FrameOffset + MathF.Rnd.Next(res.FrameCount)), CollisionAction = collisionAction }); } else { GraphicResource res = commonResources.Graphics["Snow"]; Material material = res.Material.Res; Texture texture = material.MainTexture.Res; float scale = MathF.Rnd.NextFloat(0.4f, 1.1f); float speedX = MathF.Rnd.NextFloat(-1.6f, -1.2f) * scale; float speedY = MathF.Rnd.NextFloat(3f, 4f) * scale; float accel = MathF.Rnd.NextFloat(-0.008f, 0.008f) * scale; debrisPos.Z = MainPlaneZ * scale; tileMap.CreateDebris(new TileMap.DestructibleDebris { Pos = debrisPos, Size = res.Base.FrameDimensions, Speed = new Vector2(speedX, speedY), Acceleration = new Vector2(accel, -MathF.Abs(accel)), Scale = scale, Angle = MathF.Rnd.NextFloat(MathF.TwoPi), AngleSpeed = speedX * 0.02f, Alpha = 1f, Time = 180f, Material = material, MaterialOffset = texture.LookupAtlas(res.FrameOffset + MathF.Rnd.Next(res.FrameCount)), CollisionAction = collisionAction }); } } } // Active Boss if (activeBoss != null && activeBoss.Scene == null) { activeBoss = null; Hud hud = rootObject.GetComponent <Hud>(); if (hud != null) { hud.ActiveBoss = null; } InitLevelChange(ExitType.Normal, null); levelChangeTimer = 300; } if (initState == InitState.Initializing) { initState = InitState.Initialized; } collisionsCountA = 0; collisionsCountB = 0; collisionsCountC = 0; }