Files
OpenRA/OpenRA.Mods.Common/Projectiles/GravityBomb.cs
reaperrr 8513a83331 Add ImpactOrientation to WarheadArgs
Allows to pass the horizontal facing/yaw
and vertical angle/pitch of the carrier
projectile to warheads for further use.

Add ImpactPosition to WarheadArgs

InflictDamage doesn't pass the impact pos
directly, and the very point of WarheadArgs
is to avoid adding more and more arguments
to the warhead methods.
2020-07-12 19:52:55 +02:00

131 lines
3.8 KiB
C#

#region Copyright & License Information
/*
* Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
* 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.Collections.Generic;
using OpenRA.GameRules;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Projectiles
{
public class GravityBombInfo : IProjectileInfo
{
public readonly string Image = null;
[SequenceReference("Image")]
[Desc("Loop a randomly chosen sequence of Image from this list while falling.")]
public readonly string[] Sequences = { "idle" };
[SequenceReference("Image")]
[Desc("Sequence to play when launched. Skipped if null or empty.")]
public readonly string OpenSequence = null;
[PaletteReference]
[Desc("The palette used to draw this projectile.")]
public readonly string Palette = "effect";
[Desc("Palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false;
public readonly bool Shadow = false;
[PaletteReference]
public readonly string ShadowPalette = "shadow";
[Desc("Projectile movement vector per tick (forward, right, up), use negative values for opposite directions.")]
public readonly WVec Velocity = WVec.Zero;
[Desc("Value added to Velocity every tick.")]
public readonly WVec Acceleration = new WVec(0, 0, -15);
public IProjectile Create(ProjectileArgs args) { return new GravityBomb(this, args); }
}
public class GravityBomb : IProjectile, ISync
{
readonly GravityBombInfo info;
readonly Animation anim;
readonly ProjectileArgs args;
readonly WVec acceleration;
WVec velocity;
[Sync]
WPos pos, lastPos;
public GravityBomb(GravityBombInfo info, ProjectileArgs args)
{
this.info = info;
this.args = args;
pos = args.Source;
var convertedVelocity = new WVec(info.Velocity.Y, -info.Velocity.X, info.Velocity.Z);
velocity = convertedVelocity.Rotate(WRot.FromYaw(args.Facing));
acceleration = new WVec(info.Acceleration.Y, -info.Acceleration.X, info.Acceleration.Z);
if (!string.IsNullOrEmpty(info.Image))
{
anim = new Animation(args.SourceActor.World, info.Image, () => args.Facing);
if (!string.IsNullOrEmpty(info.OpenSequence))
anim.PlayThen(info.OpenSequence, () => anim.PlayRepeating(info.Sequences.Random(args.SourceActor.World.SharedRandom)));
else
anim.PlayRepeating(info.Sequences.Random(args.SourceActor.World.SharedRandom));
}
}
public void Tick(World world)
{
lastPos = pos;
pos += velocity;
velocity += acceleration;
if (pos.Z <= args.PassiveTarget.Z)
{
pos += new WVec(0, 0, args.PassiveTarget.Z - pos.Z);
world.AddFrameEndTask(w => w.Remove(this));
var warheadArgs = new WarheadArgs(args)
{
ImpactOrientation = new WRot(WAngle.Zero, Util.GetVerticalAngle(lastPos, pos), args.Facing),
ImpactPosition = pos,
};
args.Weapon.Impact(Target.FromPos(pos), warheadArgs);
}
if (anim != null)
anim.Tick();
}
public IEnumerable<IRenderable> Render(WorldRenderer wr)
{
if (anim == null)
yield break;
var world = args.SourceActor.World;
if (!world.FogObscures(pos))
{
if (info.Shadow)
{
var dat = world.Map.DistanceAboveTerrain(pos);
var shadowPos = pos - new WVec(0, 0, dat.Length);
foreach (var r in anim.Render(shadowPos, wr.Palette(info.ShadowPalette)))
yield return r;
}
var palette = wr.Palette(info.Palette + (info.IsPlayerPalette ? args.SourceActor.Owner.InternalName : ""));
foreach (var r in anim.Render(pos, palette))
yield return r;
}
}
}
}