Merge pull request #3458 from pchote/harvester-animations

Fix the harvest animations for TS and D2k.
This commit is contained in:
Matthias Mailänder
2013-06-22 01:21:34 -07:00
12 changed files with 116 additions and 28 deletions

View File

@@ -74,6 +74,8 @@ namespace OpenRA.Traits
public interface INotifyOwnerChanged { void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner); }
public interface INotifyCapture { void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner); }
public interface INotifyOtherCaptured { void OnActorCaptured(Actor self, Actor captured, Actor captor, Player oldOwner, Player newOwner); }
public interface INotifyHarvest { void Harvested(Actor self, ResourceType resource); }
public interface IAcceptInfiltrator { void OnInfiltrate(Actor self, Actor infiltrator); }
public interface IStoreOre { int Capacity { get; } }
public interface IToolTip

View File

@@ -135,45 +135,51 @@ namespace OpenRA.Mods.RA.Activities
public class HarvestResource : Activity
{
bool isHarvesting = false;
public override Activity Tick(Actor self)
{
if (isHarvesting) return this;
var territory = self.World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
if (IsCanceled)
{
if (territory != null) territory.UnclaimByActor(self);
if (territory != null)
territory.UnclaimByActor(self);
return NextActivity;
}
var harv = self.Trait<Harvester>();
var harvInfo = self.Info.Traits.Get<HarvesterInfo>();
harv.LastHarvestedCell = self.Location;
if (harv.IsFull)
{
if (territory != null) territory.UnclaimByActor(self);
if (territory != null)
territory.UnclaimByActor(self);
return NextActivity;
}
// Turn to one of the harvestable facings
if (harvInfo.HarvestFacings != 0)
{
var facing = self.Trait<IFacing>().Facing;
var desired = Util.QuantizeFacing(facing, harvInfo.HarvestFacings) * (256 / harvInfo.HarvestFacings);
if (desired != facing)
return Util.SequenceActivities(new Turn(desired), this);
}
var resLayer = self.World.WorldActor.Trait<ResourceLayer>();
var resource = resLayer.Harvest(self.Location);
if (resource == null)
{
if (territory != null) territory.UnclaimByActor(self);
if (territory != null)
territory.UnclaimByActor(self);
return NextActivity;
}
var renderUnit = self.Trait<RenderUnit>(); /* better have one of these! */
if (renderUnit.anim.CurrentSequence.Name != "harvest")
{
isHarvesting = true;
renderUnit.PlayCustomAnimation(self, "harvest", () => isHarvesting = false);
}
harv.AcceptResource(resource);
return this;
foreach (var t in self.TraitsImplementing<INotifyHarvest>())
t.Harvested(self, resource);
return Util.SequenceActivities(new Wait(harvInfo.LoadTicksPerBale), this);
}
}
}

View File

@@ -21,8 +21,10 @@ namespace OpenRA.Mods.RA
public class HarvesterInfo : ITraitInfo
{
public readonly int Capacity = 28;
public readonly int LoadTicksPerBale = 4;
public readonly int UnloadTicksPerBale = 4;
public readonly int PipCount = 7;
public readonly int HarvestFacings = 0;
public readonly string[] Resources = { };
public readonly decimal FullyLoadedSpeed = .85m;
/// <summary>

View File

@@ -454,6 +454,7 @@
<Compile Include="Render\WithVoxelWalkerBody.cs" />
<Compile Include="Widgets\Logic\CreditsLogic.cs" />
<Compile Include="Render\WithResources.cs" />
<Compile Include="Render\WithHarvestAnimation.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -18,22 +18,24 @@ namespace OpenRA.Mods.RA.Render
{
class RenderHarvesterInfo : RenderUnitInfo, Requires<HarvesterInfo>
{
public readonly string[] ImagesByFullness = { "harvempty", "harvhalf", "harv" };
public readonly string[] ImagesByFullness = {"harv"};
public override object Create(ActorInitializer init) { return new RenderHarvester(init.self, this); }
}
class RenderHarvester : RenderUnit
class RenderHarvester : RenderUnit, INotifyHarvest
{
Harvester harv;
RenderHarvesterInfo info;
public RenderHarvester(Actor self, RenderHarvesterInfo info) : base(self)
public RenderHarvester(Actor self, RenderHarvesterInfo info)
: base(self)
{
this.info = info;
harv = self.Trait<Harvester>();
foreach( var image in info.ImagesByFullness )
new Animation( image ); /* just force these to get loaded upfront */
// HACK: Force images to be loaded up-front
foreach (var image in info.ImagesByFullness)
new Animation(image);
}
public override void Tick(Actor self)
@@ -42,9 +44,15 @@ namespace OpenRA.Mods.RA.Render
var desiredImage = info.ImagesByFullness[desiredState];
if (anim.Name != desiredImage)
anim.ChangeImage( desiredImage, "idle" );
anim.ChangeImage(desiredImage, "idle");
base.Tick(self);
}
public void Harvested(Actor self, ResourceType resource)
{
if (anim.CurrentSequence.Name != "harvest")
PlayCustomAnim(self, "harvest");
}
}
}

View File

@@ -0,0 +1,62 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 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. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Render
{
class WithHarvestAnimationInfo : ITraitInfo, Requires<RenderSpritesInfo>, Requires<IBodyOrientationInfo>
{
[Desc("Sequence name to use")]
public readonly string Sequence = "harvest";
[Desc("Position relative to body")]
public readonly WVec Offset = WVec.Zero;
[Desc("Additional draw-order offset")]
public readonly int ZOffset = 0;
public object Create(ActorInitializer init) { return new WithHarvestAnimation(init.self, this); }
}
class WithHarvestAnimation : INotifyHarvest
{
WithHarvestAnimationInfo info;
Animation anim;
bool visible;
public WithHarvestAnimation(Actor self, WithHarvestAnimationInfo info)
{
this.info = info;
var rs = self.Trait<RenderSprites>();
var body = self.Trait<IBodyOrientation>();
anim = new Animation(rs.GetImage(self), RenderSimple.MakeFacingFunc(self));
anim.Play(info.Sequence);
rs.anims.Add("harvest_{0}".F(info.Sequence), new AnimationWithOffset(anim,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
() => !visible,
p => WithTurret.ZOffsetFromCenter(self, p, info.ZOffset)));
}
public void Harvested(Actor self, ResourceType resource)
{
if (visible)
return;
visible = true;
anim.PlayThen(info.Sequence, () => visible = false);
}
}
}

View File

@@ -58,6 +58,7 @@ HARV:
Resources: Tiberium, BlueTiberium
PipCount: 7
Capacity: 20
LoadTicksPerBale: 6
UnloadTicksPerBale: 12
SearchFromProcRadius: 24
SearchFromOrderRadius: 12
@@ -75,6 +76,8 @@ HARV:
LeavesHusk:
HuskActor: HARV.Husk
-GainsExperience:
-RenderUnit:
RenderHarvester:
APC:
Inherits: ^Tank

BIN
mods/d2k/bits/harvest2.shp Normal file

Binary file not shown.

BIN
mods/d2k/bits/unload2.shp Normal file

Binary file not shown.

View File

@@ -64,6 +64,7 @@ HARVESTER:
Harvester:
PipCount: 10
Capacity: 40
HarvestFacings: 8
Resources: Spice
UnloadTicksPerBale: 5
# How far away from our linked refinery to find resources (in cells):
@@ -87,6 +88,8 @@ HARVESTER:
-AttackMove:
LeavesHusk:
HuskActor: Harvester.Husk
WithHarvestAnimation:
ZOffset: 1
HARVESTER.Husk:
Inherits: ^Husk

View File

@@ -67,15 +67,15 @@ harvester:
idle:
Start: 0
Facings: 32
harvest: #TODO use the real overlay instead of this hacky paintjob
Start: 32
Length: 8
harvest: harvest2
Start: 0
Length: 6
Facings: 8
Tick: 40
dock: unload
Tick: 80
dock: unload2
Start: 0
Length: 10
dock-loop: unload
dock-loop: unload2
Start: 10
Length: 1

View File

@@ -261,6 +261,7 @@ HARV:
RevealsShroud:
Range: 4
RenderHarvester:
ImagesByFullness: harvempty, harvhalf, harv
-AttackMove:
GpsDot:
String:Harvester