Files
OpenRA/OpenRA.Mods.Common/Traits/World/CameraOvalMover.cs
let5sne.win10 9cf6ebb986
Some checks failed
Continuous Integration / Linux (.NET 8.0) (push) Has been cancelled
Continuous Integration / Windows (.NET 8.0) (push) Has been cancelled
Initial commit: OpenRA game engine
Fork from OpenRA/OpenRA with one-click launch script (start-ra.cmd)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 21:46:54 +08:00

69 lines
2.0 KiB
C#

#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[TraitLocation(SystemActors.World)]
[Desc("Moves the camera in an oval pattern around its starting position.")]
sealed class CameraOvalMoverInfo : TraitInfo
{
[Desc("Starting angle in degrees.")]
public int StartAngle = 45;
[Desc("How fast the camera moves around the oval.")]
public float DegreesPerSecond = 3f;
[Desc("The X and Y radius of the oval path. Z is unused.")]
public WVec OvalRadius = new(19200, 20480, 0);
public override object Create(ActorInitializer init) { return new CameraOvalMover(this); }
}
sealed class CameraOvalMover : IWorldLoaded
{
readonly CameraOvalMoverInfo info;
public CameraOvalMover(CameraOvalMoverInfo info)
{
this.info = info;
}
public void WorldLoaded(World world, WorldRenderer wr)
{
var vo = wr.Viewport.CenterPosition;
var viewportOrigin = new float2(vo.X, vo.Y);
float angle = info.StartAngle;
long lastTime = 0;
wr.Viewport.ViewportCenterProvider = () =>
{
if (!Game.Settings.Game.PauseShellmap)
{
var currentTime = Game.RunTime;
var dt = currentTime - lastTime;
lastTime = currentTime;
// Prevent large jumps when the game is paused or the framerate is very low.
const float MaxStep = 0.25f;
angle += Math.Min(dt / 1000.0f * info.DegreesPerSecond, MaxStep);
}
var rad = angle * (Math.PI / 180);
var offset = new float2((float)(info.OvalRadius.X * Math.Sin(rad)), (float)(info.OvalRadius.Y * Math.Cos(rad)));
return viewportOrigin + offset;
};
}
}
}